左对齐两个图形边(ggplot)

Tyl*_*ker 104 r ggplot2 gridextra gtable

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

问题:
我该怎么做?我没有和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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

bap*_*ste 128

试试这个,

 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)
Run Code Online (Sandbox Code Playgroud)

编辑

这里有一个更通用的解决方案使用修改版的(任意次数的曲线作品)rbind.gtable列入gridExtra

gA <- ggplotGrob(A)
gB <- ggplotGrob(B)
grid::grid.newpage()
grid::grid.draw(rbind(gA, gB))
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的解决方案Baptiste.但是,当其中一个图是一个`tableGrob`时,我不能让它工作.`gtable :: cbind`给了我一个令人失望的错误:`nrow(x)== nrow(y)不是TRUE.有什么建议? (4认同)
  • 美丽,非常直接.谢谢你的解决方案. (3认同)
  • 这个解决方案对我有用,我试图理解它。`[2:5]` 代表什么? (2认同)

sli*_*izb 36

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

plots <- list(A, B, C, D)
grobs <- list()
widths <- list()
Run Code Online (Sandbox Code Playgroud)

收集每个图的每个grob的宽度

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

使用do.call获取最大宽度

maxwidth <- do.call(grid::unit.pmax, widths)
Run Code Online (Sandbox Code Playgroud)

将最大宽度设置为每个grob

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

情节

do.call("grid.arrange", c(grobs, ncol = 1))
Run Code Online (Sandbox Code Playgroud)

  • 即使这些地块有不同宽度的传说也很有效 - 非常好! (2认同)

zx8*_*754 27

使用cowplot包:

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

library(cowplot)
plot_grid(A, B, ncol=1, align="v")
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Wil*_*ert 12

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"))
Run Code Online (Sandbox Code Playgroud)

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

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'))
Run Code Online (Sandbox Code Playgroud)

  • 使用`size ="first"`意味着如果第二个图比第一个图大,那么对齐看起来不会很好 (2认同)

bde*_*est 8

这是使用meltreshape2包的另一种可能的解决方案,并且facet_wrap:

library(ggplot2)
library(reshape2)

dat = CO2[, c(1, 2)]
dat$id = seq(nrow(dat))
mdat = melt(dat, id.vars="id")

head(mdat)
#   id variable value
# 1  1    Plant   Qn1
# 2  2    Plant   Qn1
# 3  3    Plant   Qn1
# 4  4    Plant   Qn1
# 5  5    Plant   Qn1
# 6  6    Plant   Qn1

plot_1 = ggplot(mdat, aes(x=value)) + 
         geom_bar() + 
         coord_flip() +
         facet_wrap(~ variable, nrow=2, scales="free", drop=TRUE)

ggsave(plot=plot_1, filename="plot_1.png", height=4, width=6)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


bap*_*ste 8

egg软件包将ggplot对象包装到标准化的3x3gtable中,从而可以在任意ggplots(包括facetted)之间对齐绘图面板.

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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述