R 如何在ggplot(带图例)中绘制一致的宽度图?

R 如何在ggplot(带图例)中绘制一致的宽度图?,r,ggplot2,R,Ggplot2,我有几个不同的类别,我想画出来。这些是不同的类别,每个类别都有自己的标签集,但在文档中分组是有意义的。下面给出了一些简单的堆叠条形图示例: df <- data.frame(x=c("a", "b", "c"), y=c("happy", "sad", "ambivalent about life")) ggplot(df, aes(x=factor(0), fill=x)) + geom_bar() ggplot(df, aes(x=factor(0),

我有几个不同的类别,我想画出来。这些是不同的类别,每个类别都有自己的标签集,但在文档中分组是有意义的。下面给出了一些简单的堆叠条形图示例:

df <- data.frame(x=c("a", "b", "c"),
                 y=c("happy", "sad", "ambivalent about life"))
ggplot(df, aes(x=factor(0), fill=x)) + geom_bar()
ggplot(df, aes(x=factor(0), fill=y)) + geom_bar()

df编辑:使用
egg
软件包非常简单

# install.packages("egg")

library(egg)

p1 <- ggplot(data.frame(x=c("a","b","c"),
                        y=c("happy","sad","ambivalent about life")),
             aes(x=factor(0),fill=x)) + 
      geom_bar()
p2 <- ggplot(data.frame(x=c("a","b","c"),
                        y=c("happy","sad","ambivalent about life")),
             aes(x=factor(0),fill=y)) + 
      geom_bar()

ggarrange(p1,p2, ncol = 1)
# Get the grobs
gA <- ggplotGrob(p1)
gB <- ggplotGrob(p2)

# Combine the plots
g = gridExtra::rbind.gtable(gA, gB, size = "max")

# Draw it
grid.newpage()
grid.draw(g)
此外,图例框需要左对齐,并借用@Julius编写的代码

p1 <- ggplot(data.frame(x=c("a","b","c"),y=c("happy","sad","ambivalent about life")),aes(x=factor(0),fill=x)) + geom_bar()
p2 <- ggplot(data.frame(x=c("a","b","c"),y=c("happy","sad","ambivalent about life")),aes(x=factor(0),fill=y)) + geom_bar()

# Get the widths
gA <- ggplotGrob(p1)
gB <- ggplotGrob(p2)

# The parts that differs in width
leg1 <- convertX(sum(with(gA$grobs[[15]], grobs[[1]]$widths)), "mm")
leg2 <- convertX(sum(with(gB$grobs[[15]], grobs[[1]]$widths)), "mm")

# Set the widths
gA$widths <- gB$widths

# Add an empty column of "abs(diff(widths)) mm" width on the right of 
# legend box for gA (the smaller legend box)
gA$grobs[[15]] <- gtable_add_cols(gA$grobs[[15]], unit(abs(diff(c(leg1, leg2))), "mm"))

# Arrange the two charts
grid.newpage()
grid.arrange(gA, gB, nrow = 2)
左对齐图例:

# Get the grobs
gA <- ggplotGrob(p1)
gB <- ggplotGrob(p2)

# The parts that differs in width
leg1 <- convertX(sum(with(gA$grobs[[15]], grobs[[1]]$widths)), "mm")
leg2 <- convertX(sum(with(gB$grobs[[15]], grobs[[1]]$widths)), "mm")

# Add an empty column of "abs(diff(widths)) mm" width on the right of 
# legend box for gA (the smaller legend box)
gA$grobs[[15]] <- gtable_add_cols(gA$grobs[[15]], unit(abs(diff(c(leg1, leg2))), "mm"))

# Combine the plots
g = rbind(gA, gB, size = "last")

# Draw it
grid.newpage()
grid.draw(g)
# Get the grobs
gA <- ggplotGrob(p1)
gB <- ggplotGrob(p2)

# The parts that differs in width
leg1 <- convertX(sum(with(gA$grobs[[15]], grobs[[1]]$widths)), "mm")
leg2 <- convertX(sum(with(gB$grobs[[15]], grobs[[1]]$widths)), "mm")

# Add an empty column of "abs(diff(widths)) mm" width on the right of 
# legend box for gA (the smaller legend box)
gA$grobs[[15]] <- gtable_add_cols(gA$grobs[[15]], unit(abs(diff(c(leg1, leg2))), "mm"))

# Combine the plots
g = gridExtra::rbind.gtable(gA, gB, size = "max")

# Draw it
grid.newpage()
grid.draw(g)
左对齐图例:

# Get the grobs
gA <- ggplotGrob(p1)
gB <- ggplotGrob(p2)

# The parts that differs in width
leg1 <- convertX(sum(with(gA$grobs[[15]], grobs[[1]]$widths)), "mm")
leg2 <- convertX(sum(with(gB$grobs[[15]], grobs[[1]]$widths)), "mm")

# Add an empty column of "abs(diff(widths)) mm" width on the right of 
# legend box for gA (the smaller legend box)
gA$grobs[[15]] <- gtable_add_cols(gA$grobs[[15]], unit(abs(diff(c(leg1, leg2))), "mm"))

# Combine the plots
g = rbind(gA, gB, size = "last")

# Draw it
grid.newpage()
grid.draw(g)
# Get the grobs
gA <- ggplotGrob(p1)
gB <- ggplotGrob(p2)

# The parts that differs in width
leg1 <- convertX(sum(with(gA$grobs[[15]], grobs[[1]]$widths)), "mm")
leg2 <- convertX(sum(with(gB$grobs[[15]], grobs[[1]]$widths)), "mm")

# Add an empty column of "abs(diff(widths)) mm" width on the right of 
# legend box for gA (the smaller legend box)
gA$grobs[[15]] <- gtable_add_cols(gA$grobs[[15]], unit(abs(diff(c(leg1, leg2))), "mm"))

# Combine the plots
g = gridExtra::rbind.gtable(gA, gB, size = "max")

# Draw it
grid.newpage()
grid.draw(g)
#拿到食物

gA正如@hadley所建议的,
rbind.gtable
应该能够处理这个问题

  grid.draw(rbind(ggplotGrob(p1), ggplotGrob(p2), size="last"))

然而,理想情况下,布局宽度应为
size=“max”
,这与某些类型的网格单元有关。

只是碰巧,我注意到Arun在其评论中提出的解决方案没有得到采纳。我觉得他的简单而有效的方法确实值得加以说明

Arun建议将图例移至顶部或底部:

ggplot(df, aes(x=factor(0), fill=x)) + geom_bar() + theme(legend.position = "bottom")
ggplot(df, aes(x=factor(0), fill=y)) + geom_bar() + theme(legend.position = "bottom")

现在,绘图的宽度与要求的宽度相同。此外,两种情况下绘图区域的大小相同


如果有更多的因素或更长的标签,可能需要使用图例,例如,在两行或更多行中显示图例
theme()和
guide\u legend()
具有多个参数,用于控制
ggplot2
中图例的位置和外观
cowplot
软件包还具有用于此目的的
align\u plots
功能(未显示输出)


我根据@Sandy的答案创建了一个小函数


same.size.ggplot另一种选择:您可能可以将图例放在绘图的顶部/底部/内部?
+主题(legend.position=“top”)
(或“底部”)(或
+主题(legend.position=c(1,0),legend.justionment=c(1,0))
太棒了!这些函数和变量是否记录在任何地方,或者您是否只是查看了
ggplot
source?@jamie.f.olson在CRAN上有,但除此之外,还需要注意其他人的例子,所以有时也需要记录。您是否尝试了
rbind()
将这些图组合在一起?这应该行得通,但我不记得我们是否完成了代码。我似乎遇到了@baptiste在使用
rbind
时提到的关于单位的问题。这种方法仍然是对齐图例框的最佳方法,还是有任何新的功能来帮助这一点?经常这样做似乎需要大量的手工工作。是:
mmm中的错误
您的意思是什么?我在问题页面上没有看到错误消息的示例。
both2 <- align_plots(p1, p2, align="hv", axis="tblr")
p1x <- ggdraw(both2[[1]])
p2x <- ggdraw(both2[[2]])
save_plot("cow1.png", p1x)
save_plot("cow2.png", p2x)
library(cowplot)
both <- plot_grid(p1, p2, ncol=1, labels = c("A", "B"), align = "v")
save_plot("cow.png", both)