Reputation: 642
I've been attempting to use the grid_arrange_shared_legend code to create a column of ggplot2 plots with a single legend (I can't use straight faceting because I need to use coord_flip and have different x-axis sizes - this has been documented by Hadley as not working - https://github.com/hadley/ggplot2/issues/95)
The code prints out the 4 plots as a 2x2 matrix with the legend underneath (see http://rpubs.com/sjackman/grid_arrange_shared_legend).
I have been trying to get the 4 plots plus legend in a single column, but failed miserably. Oddly enough, I assumed that the ncol=1 argument to grid.arrange would make it all a single column but it doesn't.
At present, given 4 graphs plus a legend, the code gives this layout:
+-----------+ +-----------+
| | | |
| 1 | | 3 |
| | | |
+-----------+ +-----------+
+-----------+ +-----------+
| | | |
| 2 | | 4 |
| | | |
+-----------+ +-----------+
LEGEND HERE
I'm trying to get
+-----------+
| |
| 1 |
| |
+-----------+
+-----------+
| |
| 2 |
| |
+-----------+
+-----------+
| |
| 3 |
| |
+-----------+
+-----------+
| |
| 4 |
| |
+-----------+
LEGEND HERE
Any help appreciated. Regards Pete
Upvotes: 3
Views: 455
Reputation: 77096
this version has a column parameter for the layout of plots (the other ncol is to arrange the group of plots and legend)
grid_arrange_shared_legend <- function(..., ncol=1) {
plots <- list(...)
g <- ggplotGrob(plots[[1]] + theme(legend.position="bottom"))[["grobs"]]
legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]]
lheight <- sum(legend$height)
grid.arrange(
do.call(arrangeGrob, c(ncol=ncol, lapply(plots, function(x)
x + theme(legend.position="none")))),
legend,
ncol = 1,
heights = unit.c(unit(1, "npc") - lheight, lheight))
}
Alternatively, consider this strategy which will align the panels
library(gridExtra)
get_legend <- function(p, position="bottom"){
g <- ggplotGrob(p + theme(legend.position=position))
gtable::gtable_filter(g, "guide-box")
}
strip_legend <- function(pl) lapply(pl, function(x) x + theme(legend.position="none"))
legend <- get_legend(p1)
pl <- strip_legend(list(p1,p2,p3,p4))
gl <- lapply(pl, ggplotGrob)
lheight <- sum(legend$heights)
grid.arrange(do.call(rbind, gl), legend,
heights = unit.c(unit(1,"npc") - lheight, lheight))
Upvotes: 4