You can use the same code, except for points instead of a graph, to add additional lines to the graph.
Creating some data
set.seed(5) d <- data.frame(x=c(rnorm(1000)+3, rnorm(1000)), g=rep(1:2, each=1000) )
And doing it is quite simple:
x1 <- d$x[d$g==1] x2 <- d$x[d$g==2] y1 <- hist(x1, plot=FALSE) y2 <- hist(x2, plot=FALSE) plot(y1$breaks, c(y1$counts,0), type="s",col="blue", xlim=range(c(y1$breaks, y2$breaks)), ylim=range(c(0,y1$counts, y2$counts))) points(y2$breaks, c(y2$counts,0), type="s", col="red")
Or in a more R-ish way:
col <- c("blue", "red") ds <- split(d$x, d$g) hs <- lapply(ds, hist, plot=FALSE) plot(0,0,type="n", ylim=range(c(0,unlist(lapply(hs, function(x) x$counts)))), xlim=range(unlist(lapply(hs, function(x) x$breaks))) ) for(i in seq_along(hs)) { points(hs[[i]]$breaks, c(hs[[i]]$counts,0), type="s", col=col[i]) }
EDIT: Inspired by Joris's answer, I want to note that the lattice can also easily execute overlapping density plots.
library(lattice) densityplot(~x, group=g, data=d)