Here's an example using the built-in diamonds
data frame:
library(ggplot2)
library(gridExtra)
library(dplyr)
g_legend<-function(a.gplot){
tmp <- ggplot_gtable(ggplot_build(a.gplot))
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]
return(legend)}
First we'll create two plots to lay out together:
df <- count(diamonds, cut)
p1 = ggplot(df, aes(x=cut, y=n, label=format(n, big.mark=","), fill=cut)) +
geom_bar(stat="identity") +
geom_text(aes(y=0.5*n), colour="white") +
coord_flip() +
theme(legend.position="bottom")
p2 = ggplot(diamonds %>% sample_n(1000), aes(x=carat, y=price, colour=cut)) +
geom_point()
Now save the legend from p1
as a separate grob:
leg = g_legend(p1)
Lay out the two plots side-by-side using arrangeGrob
and then use marrangeGrob
to lay out the two-plot layout and the legend beneath it. Note that we also remove the legends from the original plots.
marrangeGrob(grobs=list(
arrangeGrob(grobs=lapply(list(p1,p2), function(p) {
p + guides(colour=FALSE, fill=FALSE)
}), ncol=2),
leg), ncol=1, nrow=2, heights=c(20,1))
