Combine plots that have a legend with one that doesn't

The reason you are getting the error is because one of your 3 gtable objects has 5 columns while the other has 6 (the p.3 object has 5 because you exclude the legend). You can check out the different layouts of the gtable objects by doing:

library(gtable)
gtable_show_layout(ggplotGrob(p.1))
gtable_show_layout(ggplotGrob(p.2))
gtable_show_layout(ggplotGrob(p.3))

I won't post the pictures here because they'd detract from the answer, but I think thats worthwhile to check out on your own.

Anyway, what we can do to remedy this problem is simply add an extra column onto your p.3 gtable and then use the size="first" option (because we want the legend to be in the right spot for the plots where we have legends).

This should work:

library(grid)
library(gtable)

grid.draw(rbind(ggplotGrob(p.1), 
                ggplotGrob(p.2),
                gtable_add_cols(ggplotGrob(p.3),unit(1,"lines")),
                size = "first"))

enter image description here

One final thing is the y-axis title on the last plot just slightly overlaps with the labels, this is because we took the sizing from the first plot and the labels are smaller on the first plot (so the y-axis labels need less space). To remedy this you could slightly alter your p.3 code to:

p.3<-  ggplot(long_plot_data, 
               aes(variable, 
                   value)) +
  geom_line() +
  theme_minimal() %+replace% theme(axis.title.y=element_text(margin=margin(0,20,0,0),angle=90))

Rerunning gives us:

grid.draw(rbind(ggplotGrob(p.1), 
                ggplotGrob(p.2),
                gtable_add_cols(ggplotGrob(p.3),unit(1,"lines")),
                size = "first"))

enter image description here


Using plot_grid() from package cowplot may help -- at least it does manage to combine plots with and without legends, but it seems tricky to get the plots to align perfectly. I post anyway, as this may be helpful and maybe someone else knows how to sort out the alignment issue

Note, added coord_fixed() also to the line plot, to get make it same size as the maps.

p.3 <-  ggplot(long_plot_data, aes(variable, value)) +
  geom_line() +
  coord_fixed() + 
  theme_minimal() 

library(cowplot)
plot_grid(p.1,p.2,p.3,ncol=1, align='h')

enter image description here


The gtable_add_cols Answer no longer works because the 3 gtable objects now have 11, 11 & 9 columns (when the above was written they had 6, 6 & 5). So you have to add TWO columns to the last plot (p.3), for example:

g1 <- ggplotGrob(p.1)
g2 <- ggplotGrob(p.2)
g3 <- ggplotGrob(p.3)
g3 <- gtable_add_cols(g3, g1$widths[5:6])
grid.newpage()
grid.draw(rbind(g1,g2,g3,
                size = "max"))