I\'m trying to use ggplot or base R to produce something like the following:
densityplot()
from bioconductor flowViz
package is one option for stacked densities.
from: http://www.bioconductor.org/packages/release/bioc/manuals/flowViz/man/flowViz.pdf :
For flowSets the idea is to horizontally stack plots of density estimates for all frames in the flowSet for one or several flow parameters. In the latter case, each parameter will be plotted in a separate panel, i.e., we implicitely condition on parameters.
you can see example visuals here: http://www.bioconductor.org/packages/release/bioc/vignettes/flowViz/inst/doc/filters.html
source("http://bioconductor.org/biocLite.R")
biocLite("flowViz")
require(ggplot2)
require(plyr)
my.data <- as.data.frame(rbind( cbind( rnorm(1e3), 1) , cbind( rnorm(1e3)+2, 2), cbind( rnorm(1e3)+3, 3), cbind( rnorm(1e3)+4, 4)))
my.data$V2=as.factor(my.data$V2)
calculate the density depending on V2
res <- dlply(my.data, .(V2), function(x) density(x$V1))
dd <- ldply(res, function(z){
data.frame(Values = z[["x"]],
V1_density = z[["y"]],
V1_count = z[["y"]]*z[["n"]])
})
add an offset depending on V2
dd$offest=-as.numeric(dd$V2)*0.2 # adapt the 0.2 value as you need
dd$V1_density_offest=dd$V1_density+dd$offest
and plot
ggplot(dd, aes(Values, V1_density_offest, color=V2)) +
geom_line()+
geom_ribbon(aes(Values, ymin=offest,ymax=V1_density_offest, fill=V2),alpha=0.3)+
scale_y_continuous(breaks=NULL)
I think it's going to be difficult to get ggplot
to offset the histograms like that. At least with faceting it makes new panels, and really, this transformation makes the y-axis meaningless. (The value is in the comparison from row to row). Here's one attempt at using base graphics to try to accomplish a similar thing.
#plotting function
plotoffsethists <- function(vals, groups, freq=F, overlap=.25, alpha=.75, colors=apply(floor(rbind(col2rgb(scales:::hue_pal(h = c(0, 360) + 15, c = 100, l = 65)(nlevels(groups))),alpha=alpha*255)),2,function(x) {paste0("#",paste(sprintf("%02X",x),collapse=""))}), ...) {
print(colors)
if (!is.factor(groups)) {
groups<-factor(groups)
}
offsethist <- function (x, col = NULL, offset=0, freq=F, ...) {
y <- if (freq) y <- x$counts
else
x$density
nB <- length(x$breaks)
rect(x$breaks[-nB], 0+offset, x$breaks[-1L], y+offset, col = col, ...)
}
hh<-tapply(vals, groups, hist, plot=F)
ymax<-if(freq)
sapply(hh, function(x) max(x$counts))
else
sapply(hh, function(x) max(x$density))
offset<-(mean(ymax)*overlap) * (length(ymax)-1):0
ylim<-range(c(0,ymax+offset))
xlim<-range(sapply(hh, function(x) range(x$breaks)))
plot.new()
plot.window(xlim, ylim, "")
box()
axis(1)
Map(offsethist, hh, colors, offset, freq=freq, ...)
invisible(hh)
}
#sample call
par(mar=c(3,1,1,1)+.1)
plotoffsethists(my.data$V1, factor(my.data$V2), overlap=.25)
Complementing Axeman's answer, you can add the option stat="binline"
to the geom_density_ridges
geom. This results in a histogram like plot, instead of a density line.
library(ggplot2)
library(ggridges)
my.data <- as.data.frame(rbind( cbind( rnorm(1e3), 1) ,
cbind( rnorm(1e3)+2, 2),
cbind( rnorm(1e3)+3, 3),
cbind( rnorm(1e3)+4, 4)))
my.data$V2 <- as.factor(my.data$V2)
ggplot(my.data, aes(x=V1, y=factor(V2), fill=factor(V2))) +
geom_density_ridges(alpha=0.6, stat="binline", bins=30)
Resulting image:
Using the ggridges
package:
ggplot(my.data, aes(x = V1, y = factor(V2), fill = factor(V2), color = factor(V2))) +
geom_density_ridges(alpha = 0.5)