R histogram with multiple populations

30,985

Solution 1

That is actually the annoying default in ggplot2:

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

resulting plot

Solution 2

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)

Solution 3

# 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)
Share:
30,985
Adi
Author by

Adi

Updated on September 18, 2020

Comments

  • Adi
    Adi over 3 years

    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?

  • Jared Smith
    Jared Smith almost 8 years
    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)).
  • BurninLeo
    BurninLeo about 6 years
    That's a stylish solution :)