Geoff
Geoff

Reputation: 1007

r plot one histogram above another

I want to be able to recreate the following diagram using r. The main problem being the stacking of one plot above the other. I am hoping for something simple without the need to go into the depths of such packages as ggplot since the emphasis is on the result of the digram (central limit theorem) rather than programming.

enter image description here

x1<-rnorm(1000,50,10)
x2<-rnorm(1000,50,20)
x3<-rnorm(1000,50,30)
x4<-rnorm(1000,50,40)

xMin=min(x1,x2,x3,x4)
xMax=max(x1,x2,x3,x4)

hist(x1, xlim = c(xMin,xMax))
hist(x2, xlim = c(xMin,xMax))
hist(x3, xlim = c(xMin,xMax))
hist(x4, xlim = c(xMin,xMax))

Upvotes: 2

Views: 957

Answers (3)

Chris
Chris

Reputation: 3986

I would argue that one of the great things about ggplot2 is that it's intuitive and users can spend more time making quick and easy visualisations like this and less time worrying about the code.

Base R solution

x1<-rnorm(1000,50,10)
x2<-rnorm(1000,50,20)
x3<-rnorm(1000,50,30)
x4<-rnorm(1000,50,40)

xMin=min(x1,x2,x3,x4)
xMax=max(x1,x2,x3,x4)


par(mfrow=c(4,1), oma = c(5,2,2,2), mar = c(3, 1, 1, 1))      
hist(x1, xlim = c(xMin,xMax), col='#4281C3', main = NULL)
hist(x2, xlim = c(xMin,xMax), col = '#008437', main = NULL)
hist(x3, xlim = c(xMin,xMax), col= '#F49824', main = NULL)
hist(x4, xlim = c(xMin,xMax), col = '#E42313', main = NULL)
legend('bottom',legend=c("x1", "x2", "x3", 'x4'),
       fill=c("#4281C3", '#008437', "#F49824", '#E42313'),
       horiz = T, inset=c(0,-1), xpd=NA)

enter image description here

ggplot2 solution

library(tidyr)
library(ggplot2)
df1 <- gather(data.frame(x1, x2,x3,x4) , 'variable', 'value') 

ggplot(df1) +
  geom_histogram(aes(x = value, fill = variable), colour = '#000000') +
  facet_wrap(.~ variable, nrow = 4) +
  scale_fill_manual(values = c("#4281C3", '#008437', "#F49824", '#E42313')) 

enter image description here

The key to ggplot2 is to have one column per variable, hence the use of tidyr::gather but we could equally have done:

df1 <- data.frame(value = c(x1,x2,x3,x4),
                  variable = rep(c('x1','x2','x3','x4'), each =1000))

Upvotes: 2

Ronny Efronny
Ronny Efronny

Reputation: 1508

If you're going for absolute ground level basics then par() should help you plot several plots in the same window.

par(mfrow = c(4,1)) # breaking your graphic windows into 4 rows, 1 column
hist(x1, xlim = c(xMin,xMax))
hist(x2, xlim = c(xMin,xMax))
hist(x3, xlim = c(xMin,xMax))
hist(x4, xlim = c(xMin,xMax))

This will plot every histogram above the next but they will have their own legends etc. To reset the window parameters use dev.off(). For more complex methods that look much nicer, ggplot is definitely the go-to, there are countless simple guides online.

Upvotes: 0

heck1
heck1

Reputation: 726

You can use par(mfcol=c(4,1)) to stack the different histograms.

x1<-rnorm(1000,50,10)
x2<-rnorm(1000,50,20)
x3<-rnorm(1000,50,30)
x4<-rnorm(1000,50,40)
xMin=min(x1,x2,x3,x4)
xMax=max(x1,x2,x3,x4)
par(mfcol=c(4,1))
hist(x1, xlim = c(xMin,xMax))
hist(x2, xlim = c(xMin,xMax))
hist(x3, xlim = c(xMin,xMax))
hist(x4, xlim = c(xMin,xMax))
dev.off()

Result:

enter image description here

Upvotes: 1

Related Questions