为了账号安全,请及时绑定邮箱和手机立即绑定

如何在ggplot中创建宽度一致的图(带有图例)?

/ 猿问

如何在ggplot中创建宽度一致的图(带有图例)?

慕莱坞7535251 2019-11-12 10:31:18

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


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()

问题在于,使用不同的标签,图例具有不同的宽度,这意味着绘图具有不同的宽度,如果我制作表格或\subfigure元素,结果看起来会有些愚蠢。我怎样才能解决这个问题?


有没有一种方法可以显式设置绘图或图例的宽度(绝对或相对)?


查看完整描述

3 回答

?
幕布斯6054654

 非常容易与egggithub上可用的包


# install.package(devtools)

# devtools::install_github("baptiste/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)

原始更新到ggplot2 2.2.1


这是一个使用gtable包中功能的解决方案,重点关注图例框的宽度。(可以在此处找到更通用的解决方案。)


library(ggplot2)   

library(gtable)    

library(grid)

library(gridExtra) 


# Your plots

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 gtables

gA <- ggplotGrob(p1)

gB <- ggplotGrob(p2)


# Set the widths

gA$widths <- gB$widths


# Arrange the two charts.

# The legend boxes are centered

grid.newpage()

grid.arrange(gA, gB, nrow = 2)

此外,图例框需要对齐,并从此处借用@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)

在此处输入图片说明


替代方案 有rbind和cbind功能在gtable包grobs组合成一个GROB。对于此处的图表,应使用设置宽度size = "max",但是CRAN版本的gtable抛出错误。


一种选择:显然,第二个图中的图例更宽。因此,使用该size = "last"选项。


# Get the grobs

gA <- ggplotGrob(p1)

gB <- ggplotGrob(p2)


# 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 = rbind(gA, gB, size = "last")


# Draw it

grid.newpage()

grid.draw(g)

第二种选择是使用rbindBaptiste的gridExtra软件包


# 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)

左对齐图例:


# 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)


查看完整回答
反对 回复 2019-11-12
?
蝴蝶不菲

该cowplot软件包还具有align_plots用于此目的的功能(输出未显示),


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)

并将plot_grid图保存到同一文件中。


library(cowplot)

both <- plot_grid(p1, p2, ncol=1, labels = c("A", "B"), align = "v")

save_plot("cow.png", both)


查看完整回答
反对 回复 2019-11-12
?
侃侃无极

偶然地,我注意到他在评论中建议的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_legend()有几个参数可控制图例在ggplot2。


查看完整回答
反对 回复 2019-11-12
  • 3 回答
  • 0 关注
  • 76 浏览
我要回答

相关问题推荐

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信