添加一个共同的图例组合ggplots

我有两个ggplots,我水平alignmentgrid.arrange 。 我已经浏览了很多论坛post,但是我尝试的所有东西似乎都是现在已更新并命名为其他内容的命令。

我的数据看起来像这样;

 # Data plot 1 axis1 axis2 group1 -0.212201 0.358867 group2 -0.279756 -0.126194 group3 0.186860 -0.203273 group4 0.417117 -0.002592 group1 -0.212201 0.358867 group2 -0.279756 -0.126194 group3 0.186860 -0.203273 group4 0.186860 -0.203273 # Data plot 2 axis1 axis2 group1 0.211826 -0.306214 group2 -0.072626 0.104988 group3 -0.072626 0.104988 group4 -0.072626 0.104988 group1 0.211826 -0.306214 group2 -0.072626 0.104988 group3 -0.072626 0.104988 group4 -0.072626 0.104988 #And I run this: library(ggplot2) library(gridExtra) groups=c('group1','group2','group3','group4','group1','group2','group3','group4') x1=data1[,1] y1=data1[,2] x2=data2[,1] y2=data2[,2] p1=ggplot(data1, aes(x=x1, y=y1,colour=groups)) + geom_point(position=position_jitter(w=0.04,h=0.02),size=1.8) p2=ggplot(data2, aes(x=x2, y=y2,colour=groups)) + geom_point(position=position_jitter(w=0.04,h=0.02),size=1.8) #Combine plots p3=grid.arrange( p1 + theme(legend.position="none"), p2+ theme(legend.position="none"), nrow=1, widths = unit(c(10.,10), "cm"), heights = unit(rep(8, 1), "cm"))) 

我将如何从这些图中提取图例并将其添加到组合图的底部/中心?

2015年2月更新

请参阅下面的Steven的答案


 df1 <- read.table(text="group xy group1 -0.212201 0.358867 group2 -0.279756 -0.126194 group3 0.186860 -0.203273 group4 0.417117 -0.002592 group1 -0.212201 0.358867 group2 -0.279756 -0.126194 group3 0.186860 -0.203273 group4 0.186860 -0.203273",header=TRUE) df2 <- read.table(text="group xy group1 0.211826 -0.306214 group2 -0.072626 0.104988 group3 -0.072626 0.104988 group4 -0.072626 0.104988 group1 0.211826 -0.306214 group2 -0.072626 0.104988 group3 -0.072626 0.104988 group4 -0.072626 0.104988",header=TRUE) library(ggplot2) library(gridExtra) p1 <- ggplot(df1, aes(x=x, y=y,colour=group)) + geom_point(position=position_jitter(w=0.04,h=0.02),size=1.8) + theme(legend.position="bottom") p2 <- ggplot(df2, aes(x=x, y=y,colour=group)) + geom_point(position=position_jitter(w=0.04,h=0.02),size=1.8) #extract legend #https://github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs 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)} mylegend<-g_legend(p1) p3 <- grid.arrange(arrangeGrob(p1 + theme(legend.position="none"), p2 + theme(legend.position="none"), nrow=1), mylegend, nrow=2,heights=c(10, 1)) 

这是由此产生的情节: 2与常见的传说情节

罗兰的答案需要更新。 见: https : //github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs

这个方法已经更新为ggplot2 v1.0.0。

 library(ggplot2) library(gridExtra) library(grid) grid_arrange_shared_legend <- function(...) { 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, lapply(plots, function(x) x + theme(legend.position="none"))), legend, ncol = 1, heights = unit.c(unit(1, "npc") - lheight, lheight)) } dsamp <- diamonds[sample(nrow(diamonds), 1000), ] p1 <- qplot(carat, price, data=dsamp, colour=clarity) p2 <- qplot(cut, price, data=dsamp, colour=clarity) p3 <- qplot(color, price, data=dsamp, colour=clarity) p4 <- qplot(depth, price, data=dsamp, colour=clarity) grid_arrange_shared_legend(p1, p2, p3, p4) 

注意缺lessggplot_gtableggplot_buildggplotGrob代替。 这个例子比上面的解决scheme稍微复杂一点,但它仍然为我解决了这个问题。

@Giuseppe,你可能想考虑这个灵活的规划的情节安排(从这里修改):

 library(ggplot2) library(gridExtra) library(grid) grid_arrange_shared_legend <- function(..., nrow = 1, ncol = length(list(...)), position = c("bottom", "right")) { plots <- list(...) position <- match.arg(position) g <- ggplotGrob(plots[[1]] + theme(legend.position = position))$grobs legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]] lheight <- sum(legend$height) lwidth <- sum(legend$width) gl <- lapply(plots, function(x) x + theme(legend.position = "none")) gl <- c(gl, nrow = nrow, ncol = ncol) combined <- switch(position, "bottom" = arrangeGrob(do.call(arrangeGrob, gl), legend, ncol = 1, heights = unit.c(unit(1, "npc") - lheight, lheight)), "right" = arrangeGrob(do.call(arrangeGrob, gl), legend, ncol = 2, widths = unit.c(unit(1, "npc") - lwidth, lwidth))) grid.newpage() grid.draw(combined) } 

额外的参数nrownrow控制排列图的布局:

 dsamp <- diamonds[sample(nrow(diamonds), 1000), ] p1 <- qplot(carat, price, data = dsamp, colour = clarity) p2 <- qplot(cut, price, data = dsamp, colour = clarity) p3 <- qplot(color, price, data = dsamp, colour = clarity) p4 <- qplot(depth, price, data = dsamp, colour = clarity) grid_arrange_shared_legend(p1, p2, p3, p4, nrow = 1, ncol = 4) grid_arrange_shared_legend(p1, p2, p3, p4, nrow = 2, ncol = 2) 

在这里输入图像描述 在这里输入图像描述

我build议使用cowplot。 从他们的小插图 :

 # load cowplot library(cowplot) # down-sampled diamonds data set dsamp <- diamonds[sample(nrow(diamonds), 1000), ] # Make three plots. # We set left and right margins to 0 to remove unnecessary spacing in the # final plot arrangement. p1 <- qplot(carat, price, data=dsamp, colour=clarity) + theme(plot.margin = unit(c(6,0,6,0), "pt")) p2 <- qplot(depth, price, data=dsamp, colour=clarity) + theme(plot.margin = unit(c(6,0,6,0), "pt")) + ylab("") p3 <- qplot(color, price, data=dsamp, colour=clarity) + theme(plot.margin = unit(c(6,0,6,0), "pt")) + ylab("") # arrange the three plots in a single row prow <- plot_grid( p1 + theme(legend.position="none"), p2 + theme(legend.position="none"), p3 + theme(legend.position="none"), align = 'vh', labels = c("A", "B", "C"), hjust = -1, nrow = 1 ) # extract the legend from one of the plots # (clearly the whole thing only makes sense if all plots # have the same legend, so we can arbitrarily pick one.) legend_b <- get_legend(p1 + theme(legend.position="bottom")) # add the legend underneath the row we made earlier. Give it 10% of the height # of one plot (via rel_heights). p <- plot_grid( prow, legend_b, ncol = 1, rel_heights = c(1, .2)) p 

与底部的传说结合的情节

你也可以使用ggpubr包中的ggarrange ,并设置“common.legend = TRUE”:

 library(ggpubr) dsamp <- diamonds[sample(nrow(diamonds), 1000), ] p1 <- qplot(carat, price, data = dsamp, colour = clarity) p2 <- qplot(cut, price, data = dsamp, colour = clarity) p3 <- qplot(color, price, data = dsamp, colour = clarity) p4 <- qplot(depth, price, data = dsamp, colour = clarity) ggarrange(p1, p2, p3, p4, ncol=2, nrow=2, common.legend = TRUE, legend="bottom") 

在这里输入图像描述

@Guiseppe:

我不知道Grobs等等,但我一起砍了两块地块的解决scheme,应该可以扩展到任意数量,但它不是一个性感的function:

 plots <- list(p1, p2) g <- ggplotGrob(plots[[1]] + theme(legend.position="bottom"))$grobs legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]] lheight <- sum(legend$height) tmp <- arrangeGrob(p1 + theme(legend.position = "none"), p2 + theme(legend.position = "none"), layout_matrix = matrix(c(1, 2), nrow = 1)) grid.arrange(tmp, legend, ncol = 1, heights = unit.c(unit(1, "npc") - lheight, lheight))