如何使用公共色条排列多个ggplot2 grob?

时间:2018-10-09 20:31:54

标签: r ggplot2

这里有一些虚假数据和一个图:

library(foreach)
library(ggplot2)
dat <- foreach(i = 1:6, .combine = rbind) %do% {
  data.frame(x = rnorm(1000), y = rnorm(1000), fac = as.factor(i))
}

ggplot(dat, aes(x=x, y = y))+
  geom_point(aes(col = x+y))+
  facet_wrap( ~ fac, nrow = 2)

enter image description here

如何使它看起来像这样?如果我不在乎普通的颜色条,我会使用grid.arrange

enter image description here

2 个答案:

答案 0 :(得分:2)

我结合了您问题中的评论中的一些想法。您也可以在x和y轴上设置相同的限制-我在这里没有这样做,因为我不确定这对您的问题是否很重要,

library(plyr)
library(foreach)
library(ggplot2)
library(dplyr)
library(gridExtra)

dat <- foreach(i = 1:6, .combine = rbind) %do%  {
  data.frame(x = rnorm(1000), y = rnorm(1000), fac = as.factor(i))
}




 #update: added 7th part to the layer matrix for the legend
lay <- rbind(c(1,1,1,1,2,2,7),c(1,1,1,1,2,2,7),
             c(1,1,1,1,3,3,7),c(1,1,1,1,3,3,7),
             c(4,4,5,5,6,6,7),c(4,4,5,5,6,6,7))


gp1 <- ggplot(filter(dat, fac ==1), aes(x=x, y = y))+
  geom_point(aes(col = x+y))+
  #set limits the same on each graph or color gradient
  scale_color_gradient(limits = c(min(dat$x + dat$y),max(dat$x + dat$y)))


gp2 <- ggplot(filter(dat, fac ==2), aes(x=x, y = y))+
  geom_point(aes(col = x+y))+
  scale_color_gradient(limits = c(min(dat$x + dat$y),max(dat$x + dat$y)))

gp3 <- ggplot(filter(dat, fac ==3), aes(x=x, y = y))+
  geom_point(aes(col = x+y))+
  scale_color_gradient(limits = c(min(dat$x + dat$y),max(dat$x + dat$y)))


gp4 <- ggplot(filter(dat, fac ==4), aes(x=x, y = y))+
  geom_point(aes(col = x+y))+
  scale_color_gradient(limits = c(min(dat$x + dat$y),max(dat$x + dat$y)))

gp5 <- ggplot(filter(dat, fac ==5), aes(x=x, y = y))+
  geom_point(aes(col = x+y))+
  scale_color_gradient(limits = c(min(dat$x + dat$y),max(dat$x + dat$y)))


gp6 <- ggplot(filter(dat, fac ==6), aes(x=x, y = y))+
  geom_point(aes(col = x+y))+
  scale_color_gradient(limits = c(min(dat$x + dat$y),max(dat$x + dat$y)))



 # grab legend from one plot
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)}

aleg <- g_legend(gp1)
gp1 <- gp1+ theme(legend.position = "none")
gp2 <- gp2+ theme(legend.position = "none")
gp3 <- gp3+ theme(legend.position = "none")
gp4 <- gp4+ theme(legend.position = "none")
gp5 <- gp5+ theme(legend.position = "none")
gp6 <- gp6 + theme(legend.position = "none")


gpls <- lapply(list(gp1,gp2,  gp3,gp4,gp5,gp6), ggplotGrob )

gridExtra::grid.arrange(gpls[[1]], gpls[[2]],
                        gpls[[3]], gpls[[4]],
                        gpls[[5]], gpls[[6]],  
                        #use layout matrix to set sizes
                        layout_matrix=lay, aleg)

编辑-添加了答案图。 enter image description here

答案 1 :(得分:0)

几条建议

g_legend<-function(p){
  tmp <- ggplotGrob(p)
  tmp$grobs[grepl('guide-box', tmp$layout$name)][[1]]
}


aleg <- g_legend(gp1)
gpls <- lapply(list(gp1,gp2,gp3,gp4,gp5,gp6), 
               function(p) ggplotGrob(p+theme(legend.position = "none")))

lay <- rbind(c(1,1,2,7),
             c(1,1,3,7),
             c(4,5,6,7))

gridExtra::grid.arrange(grobs=c(gpls,list(aleg)), layout_matrix=lay, widths=c(2,2,2,1))

或者,或者,

lay <- rbind(c(1,1,2),
             c(1,1,3),
             c(4,5,6))

gridExtra::grid.arrange(grobs=gpls, layout_matrix=lay, right=aleg)