As camille pointed out, cowplot
has a really easy way to do this. You can also do it by manually arranging your grobs
. This works especially well if you have plots with different widths, scales, and breaks. One example here.
The benefit of doing this manually, unless cowplot
can, is that you can specify which plots get x-axis labels, and y-axis titles/labels, so in the end you can only have x-axis titles/labels on your bottom grids, and y-axis titles/labels on your left grids. The downside, being it's tedious to define multiple plotting functions if you have several plots.
df_plots <- lapply(lst_df, function(x) {
ggplot() +
geom_point(data=lst_df[[i]], aes(x=lon, y=lat, size=sign, colour = cor), alpha = 0.5) +
scale_color_manual(values=c("blue", "orange"),
name='col',
labels = c('neg', 'pos'),
guide = guide_legend(override.aes = list(alpha = 1, size = 3))) +
scale_size(range = c(1,3),
breaks = c(90, 95, 99),
labels = c(1, 5, 10),
name = 'test',
guide = guide_legend(override.aes = list(colour = 'black',
alpha = 1)))
})
df_leg <- get_legend(df_plots[[1]]) # get legend
df_plots_noleg <- lapply(lst_df, function(x) { # make plots with no legends, however you want to do this
ggplot() +
geom_point(data=lst_df[[i]], aes(x=lon, y=lat, size=sign, colour = cor), alpha = 0.5) +
scale_color_manual(values=c("blue", "orange"),
name='col',
labels = c('neg', 'pos'),
guide = guide_legend(override.aes = list(alpha = 1, size = 3))) +
theme(legend.position = "none")
})
If you have plots that start to vary in widths, this is important to align your axes. Since in this example they're all the same, this doesn't matter.
#maxWidth_df_plots <- grid::unit.pmax(df_plots_noleg1$widths[2:5], df_plots_noleg2$widths[2:5], df_plots_noleg3$widths[2:5], df_plots_noleg4$widths[2:5]) #get your grob widths
#df_plots_noleg1$widths[2:5] <- as.list(maxWidth1Page1)
#df_plots_noleg2$widths[2:5] <- as.list(maxWidth1Page1)
#df_plots_noleg3$widths[2:5] <- as.list(maxWidth1Page1)
#df_plots_noleg4$widths[2:5] <- as.list(maxWidth1Page1)
df_plots1 <- ggplotGrob(df_plots_noleg[[1]])
df_plots2 <- ggplotGrob(df_plots_noleg[[2]])
df_plots3 <- ggplotGrob(df_plots_noleg[[3]])
df_plots4 <- ggplotGrob(df_plots_noleg[[4]])
df_plot_arranged <- grid.arrange(arrangeGrob(df_plots1, df_plots2, df_plots3, df_plots4, nrow = 2),
arrangeGrob(nullGrob(), df_leg, nullGrob(), nrow = 1), ncol = 1, heights = c(4,0.5),
top = textGrob("Title Text Holder Here", gp = gpar(fotsize = 12, font = 2)))

The benefit that I mentioned is you can control what graphs get what labeling. This is where controlling your widths would help, as you can see in the image the right plots are wider than the left, and the ones on top are taller than the ones on the bottom.
df_plots1 <- df_plots_noleg[[1]] + theme(axis.title.x = element_blank(), axis.text.x = element_blank())
df_plots2 <- df_plots_noleg[[2]] + theme(axis.title.x = element_blank(), axis.title.y = element_blank(),
axis.text.x = element_blank(), axis.text.y = element_blank())
df_plots4 <- df_plots_noleg[[4]] + theme(axis.title.y = element_blank(), axis.text.y = element_blank())
df_plots1 <- ggplotGrob(df_plots1)
df_plots2 <- ggplotGrob(df_plots2)
df_plots3 <- ggplotGrob(df_plots_noleg[[3]])
df_plots4 <- ggplotGrob(df_plots4)
df_plot_arranged <- grid.arrange(arrangeGrob(df_plots1, df_plots2, df_plots3, df_plots4, nrow = 2),
arrangeGrob(nullGrob(), df_leg, nullGrob(), nrow = 1), ncol = 1, heights = c(4,0.5),
top = textGrob("Title Text Holder Here", gp = gpar(fotsize = 12, font = 2)))
