/ 猿问

# 如何在ggplot中创建宽度一致的图（带有图例）？

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

## 3 回答

非常容易与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)

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)

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)

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

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

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)

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

• 3 回答
• 0 关注
• 76 浏览

0/150