2
votes

I'm trying to produce side by side tile plots using ggplot2 and gridExtra. However, the plots produced are not scaled/aligned, see the picture and code below.

How can I produce this figure such that the cells are aligned and of the same dimensions?

enter image description here Code

library(ggplot2)
library(gridExtra)

## make date frames
one <- floor(runif(56, min=0, max=5))
data.one<- cbind(one,expand.grid(h = seq(1,8,1), w = seq(1,7,1)))

two <- floor(runif(35, min=0, max=5))
data.two <- cbind(two,expand.grid(h = seq(1,7,1), w = seq(1,5,1)))

## gridExtra layout
lay <- rbind(c(1,1,1,1,1,1,1,NA,NA,NA,NA,NA),
             c(1,1,1,1,1,1,1,2,2,2,2,2),
             c(1,1,1,1,1,1,1,2,2,2,2,2),
             c(1,1,1,1,1,1,1,2,2,2,2,2),
             c(1,1,1,1,1,1,1,2,2,2,2,2),
             c(1,1,1,1,1,1,1,2,2,2,2,2),
             c(1,1,1,1,1,1,1,2,2,2,2,2),
             c(1,1,1,1,1,1,1,2,2,2,2,2))

##plots
plot.one<-ggplot(data=data.one)+
  geom_tile(aes(x=w,y=h,fill=one),colour = "grey50")+ 
  scale_fill_gradient(low = "white", high = "blue")+
  theme(legend.position= "none")

plot.two<-ggplot(data=data.two)+
  geom_tile(aes(y=h,x=w,fill=two),colour = "grey50")+ 
  scale_fill_gradient(low = "white", high = "red")+
  theme(legend.position= "none")

grid.arrange(plot.one,plot.two, layout_matrix = lay)
1
Take a look at cowplot—it's got some solutions to simplify this type of situation, and is well-documentedcamille

1 Answers

1
votes

ggplot2 doesn't assign fixed sizes to the plot panels, so you need to go to a rather low-level, find out the number of bins in each plot, and use this to set the appropriate panel size in the gtable object. The other complication is that "null" units are a bit special in grid, so to have something that scales with them it needs to be a null unit itself, as in this dummy rectGrob squeezing the second plot panel from the top,

b1 <- ggplot_build(p1)
b2 <- ggplot_build(p2)

n <- function(b) length(unique(b[["data"]][[1]][["y"]]))

library(egg)
library(grid)

gf1 <- gtable_frame(ggplot_gtable(b1))
gf2 <- gtable_frame(ggplot_gtable(b2))

gf2$grobs[[5]][["grobs"]][[1]] <- arrangeGrob(
  rectGrob(gp=gpar(fill="grey95", col=NA)),  gf2$grobs[[5]][["grobs"]][[1]],
  heights = unit.c(unit(1 - n(b2) / n(b1), "null"), unit(n(b2) / n(b1),"null")))

grid.arrange(gf1, gf2, ncol=2)

enter image description here