12

I'm interested in creating a histogram in R that will contain two (or more) population on top of each other, meaning - I don't want a two histograms sharing the same graph but a bar containing two colors or more.

Found the image below - this is what I want to accomplish.

example

Any ideas?

Z.Lin
  • 23,077
  • 5
  • 35
  • 71
Adi
  • 141
  • 1
  • 1
  • 5
  • That's a stacked bar plot/chart. There are many examples here on stackoverflow like http://stackoverflow.com/questions/21236229/ggplot2-stacked-bar-chart and http://stackoverflow.com/questions/6693257/making-a-stacked-bar-plot-for-multiple-variables-ggplot2-in-r. If you show some of your data/reproducible example of your data, it would help others to help you. – Komal Rathi Oct 28 '14 at 15:59
  • Take a look at `?barplot`. E.g. `barplot(VADeaths, legend = rownames(VADeaths))`. – jbaums Oct 28 '14 at 16:05

3 Answers3

17

That is actually the annoying default in ggplot2:

library(ggplot2)
ggplot(iris, aes(x=Sepal.Length, fill=Species)) +
  geom_histogram()

resulting plot

Roland
  • 117,893
  • 9
  • 163
  • 255
9

Here is another option without using ggplot:

#plot the entire data set (everything)
hist(everything, breaks=c(1:10), col="Red")

#then everything except one sub group (1 in this case)
hist(everything[everything!=1], breaks=c(1:10), col="Blue", add=TRUE)

#then everything except two sub groups (1&2 in this case)
hist(everything[everything!=1 && everything!=2], breaks=c(1:10), col="Green", add=TRUE)
Nate
  • 9,151
  • 1
  • 27
  • 33
GuestBruce
  • 91
  • 1
  • 1
2
# 1) Define the breaks to use on your Histogram
xrange = seq(-3,3,0.1)

# 2) Have your vectors ready
v1 = rnorm(n=300,mean=1.1,sd=1.5)
v2 = rnorm(n=350,mean=1.3,sd=1.5)
v3 = rnorm(n=380,mean=1.2,sd=1.9)

# 3) subset your vectors to be inside xrange
v1 = subset(v1,v1<=max(xrange) & v1>=min(xrange))
v2 = subset(v2,v2<=max(xrange) & v2>=min(xrange))
v3 = subset(v3,v3<=max(xrange) & v3>=min(xrange))

# 4) Now, use hist to compute the counts per interval
hv1 = hist(v1,breaks=xrange,plot=F)$counts
hv2 = hist(v2,breaks=xrange,plot=F)$counts
hv3 = hist(v3,breaks=xrange,plot=F)$counts

# 5) Finally, Generate a Frequency BarPlot that is equivalent to a Stacked histogram
maintitle = "Stacked Histogram Example using Barplot"
barplot(rbind(hv1,hv2,hv3),col=2:4,names.arg=xrange[-1],space=0,las=1,main=maintitle)

# 6) You can also generate a Density Barplot
Total = hv1 + hv2 + hv3
barplot(rbind(hv1/Total,hv2/Total,hv3/Total),col=2:4,names.arg=xrange[-1],space=0,las=1)
  • Great answer! I'd like to make 2 suggestions to make your density plot traditional, and more general. Use `Total = sum(hv1, hv2, hv3)` to make a traditional density histogram where the sum of the values for all bars sums to 1, rather than each bar summing to 1. To correct for bins of potentially unequal width, use `rbind(hv1/(Total*diff(xrange), hv2/(Total*diff(xrange), hv3/(Total*diff(xrange))`. – Jared Smith Jun 27 '16 at 20:54