左对齐两个图形边(ggplot)

时间:2012-11-08 17:59:37

标签: r ggplot2 gridextra gtable

我正在使用ggplot并且有两个我想要彼此重叠显示的图表。我使用gridExtra中的grid.arrange来堆叠它们。问题是,无论轴标签如何,我都希望图形的左边缘与右边缘对齐。 (问题出现是因为一个图的标签很短而另一个图很长)。

问题:
我怎样才能做到这一点?我没有和grid.arrange结婚,但ggplot2是必须的。

我尝试了什么:
我尝试使用宽度和高度以及ncol和nrow来制作2 x 2网格并将视觉效果放在相对的角落然后使用宽度进行播放但我无法在对角处获得视觉效果。

require(ggplot2);require(gridExtra)
A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip() 
B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip() 
grid.arrange(A, B, ncol=1)

enter image description here

8 个答案:

答案 0 :(得分:124)

试试这个,

 gA <- ggplotGrob(A)
 gB <- ggplotGrob(B)
 maxWidth = grid::unit.pmax(gA$widths[2:5], gB$widths[2:5])
 gA$widths[2:5] <- as.list(maxWidth)
 gB$widths[2:5] <- as.list(maxWidth)
 grid.arrange(gA, gB, ncol=1)

修改

使用rbind.gtable

中包含的gridExtra修改版本,这是一个更通用的解决方案(适用于任意数量的图表)
gA <- ggplotGrob(A)
gB <- ggplotGrob(B)
grid::grid.newpage()
grid::grid.draw(rbind(gA, gB))

答案 1 :(得分:35)

我想对任意数量的情节进行概括。以下是使用Baptiste方法的逐步解决方案:

plots <- list(A, B, C, D)
grobs <- list()
widths <- list()

收集每个地块的每个格栅的宽度

for (i in 1:length(plots)){
    grobs[[i]] <- ggplotGrob(plots[[i]])
    widths[[i]] <- grobs[[i]]$widths[2:5]
}

使用do.call获取最大宽度

maxwidth <- do.call(grid::unit.pmax, widths)

将每个grob的最大宽度设为

for (i in 1:length(grobs)){
     grobs[[i]]$widths[2:5] <- as.list(maxwidth)
}

do.call("grid.arrange", c(grobs, ncol = 1))

答案 2 :(得分:25)

使用cowplot包:

{{1}}

enter image description here

答案 3 :(得分:12)

On http://rpubs.com/MarkusLoew/13295是一个非常简单的解决方案(最后一项) 适用于这个问题:

require(ggplot2);require(gridExtra)
A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip() 
B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip() 
grid.draw(rbind(ggplotGrob(A), ggplotGrob(B), size="first"))

您也可以将它用于宽度和高度:

require(ggplot2);require(gridExtra)
A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip() 
B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip() 
C <- ggplot(CO2, aes(x=conc)) + geom_bar() +coord_flip()
D <- ggplot(CO2, aes(x=uptake)) + geom_bar() +coord_flip() 
grid.draw(cbind(
            rbind(ggplotGrob(A), ggplotGrob(B), size="first"),
            rbind(ggplotGrob(C), ggplotGrob(D), size="first"),
            size='first'))

答案 4 :(得分:7)

egg包将ggplot对象包装到标准化的3x3 gtable中,从而可以在任意ggplots之间对齐绘图面板,包括切面的ggplots。

library(egg) # devtools::install_github('baptiste/egg')
library(ggplot2)

p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) +
  geom_point() 

p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) +
  geom_point() + facet_wrap( ~ cyl, ncol=2, scales = "free") +
  guides(colour="none") +
  theme()

ggarrange(p1, p2)

enter image description here

答案 5 :(得分:1)

patchwork软件包默认处理此问题:

library(ggplot2)
library(patchwork)

A <- ggplot(CO2, aes(x = Plant)) + geom_bar() + coord_flip() 
B <- ggplot(CO2, aes(x = Type)) + geom_bar() + coord_flip() 

A / B

reprex package(v0.3.0)于2019-12-08创建

答案 6 :(得分:0)

充其量这是一个黑客攻击:

library(wq)
layOut(list(A, 1, 2:16),  list(B, 2:3, 1:16))

但感觉真的很错误。

答案 7 :(得分:0)

我知道这是一篇旧文章,并且已经得到答复,但是我建议将@baptiste的方法与purrr结合使用,以使其看起来更好:

library(purrr)
list(A, B) %>% 
  map(ggplotGrob) %>% 
  do.call(gridExtra::gtable_rbind, .) %>% 
  grid::grid.draw()