使用 ggplot2/gridExtra 保持两个图垂直对齐

问题描述 投票:0回答:1
我试图将多个 ggplot2 图合并到一张图片中,同时保留对每个元素各自高度的控制。 下面的代码运行良好,它生成一个条形图和一个曲线图,它们彼此完美对齐(参见

here):

library(ggplot2) library(grid) library(gridExtra) # Save plot as PDF (set to NULL initially) pdf(file = NULL) # Data frame for the first plot df_1 <- data.frame( data = c(0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.2, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.4, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.5, 0.1, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.2, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.4, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.5, 0.1, 0.5, 0.1, 0.15, 0.5, 0.5, 0.4), base = 1:54, value = c(0.9557, 0.4407, 0.141, 3.4229, 3.5197, 4.7386, 6.9897, 0.3958, 4.7268, 1.8085, 10.5312, 5.9011, 7.9393, 5.7363, 13.8539, 11.2096, 14.8407, 11.4008, 0.5412, 10.3042, 11.3208, 15.6669, 8.2177, 12.6917, 20.7124, 10.9896, 24.7246, 7.0544, 21.0489, 16.4536, 7.4753, 28.2106, 32.7284, 29.7557, 23.3567, 29.9186, 30.3813, 15.1307, 20.2323, 34.4262, 20.8036, 18.7994, 41.7036, 26.828, 10.7628, 28.2335, 4.4982, 3.6528, 33.8571, 11.6208, 43.54, 26.7859, 22.2176, 11.0588) ) # First plot with ggplot plot_1 <- ggplot(df_1, aes(x = base, y = data, fill = value)) + geom_bar(stat = 'identity', position = position_dodge(width = 0.9)) + scale_fill_distiller(palette = 'YlGnBu') + theme( axis.text.x = element_text(size = 9, angle = 0, vjust = 0.5), axis.text.y = element_text(size = 9), legend.position = 'right', legend.spacing.x = unit(5, 'pt'), legend.text = element_text(margin = margin(0, 0, 0, 0, 'pt'), size = 10), legend.key = element_rect(fill = NA), axis.title.x = element_blank(), axis.title.y = element_blank(),plot.margin = margin(0,0,0,0) ) + guides( colour = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5), shape = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5), fill = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5) )+ xlim(0, 55) # Data frame for the second plot df_2 <- data.frame( x1 = c(4, 12, 1, 2), x2 = c(9, 15, 24, 54), y1 = c(0, 0, 0, 0), y2 = c(0, 0, 0, 0), priority = c('high', 'low', 'mid', 'high') ) # Second plot with ggplot plot_2 <- ggplot(df_2) + geom_curve(aes(x = x1, xend = x2, y = y1, yend = y2, color = priority), curvature = 1, linewidth = 0.5, ncp = 1000) + expand_limits(y = -1) + coord_fixed(ratio = 22, ylim = c(-1, 0)) + scale_colour_brewer(palette = 'YlGnBu') + theme( legend.position = 'right', legend.spacing.x = unit(5, 'pt'), legend.text = element_text(margin = margin(0, 0, 0, 0, 'pt'), size = 10), legend.key = element_rect(fill = NA), axis.title.x = element_blank(), axis.title.y = element_blank(),plot.margin = margin(0,0,0,0) ) + guides( colour = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5), shape = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5), fill = guide_legend(label.position = 'right', title.position = 'top', title.hjust = 0.5) ) + xlim(0, 55) # List of ggplot objects plots <- list(plot_1, plot_2) # Add as many plots as you need # Apply a small margin to each plot to reduce extra white space plots_adjusted <- lapply(plots, "+", theme(plot.margin = margin(0, 0, 0, 0))) # Convert adjusted plots to gtables grob_plots <- lapply(plots_adjusted, ggplotGrob) # Calculate the maximum widths across all plots max_widths <- do.call(unit.pmax, lapply(grob_plots, function(g) g$widths)) # Set each plot's widths to the calculated maximum widths grob_plots <- lapply(grob_plots, function(g) { g$widths <- max_widths; g }) # Arrange the grobs with specific heights combined_plot <- arrangeGrob(grobs = grob_plots, heights = unit(c(1,1), "null"), padding = unit(0, "pt")) dev.off() # Save the combined plot to a file ggsave("~/Downloads/mytest.pdf", combined_plot,dpi = 300)
但是,当我尝试在 

ggsave()

 中修改输出 PDF 文件的宽度(例如通过设置 
width=20
)时,绘图的相对比例会丢失,并且只有第一个绘图会扩展以填充打印区域(参见
此处)。

你能告诉我如何解决这个问题吗?

r ggplot2 gridextra
1个回答
0
投票
出现您遇到的问题是因为

ggsave()

 独立于 
arrangeGrob()
 中指定的相对布局重新缩放绘图。为了确保在调整输出 PDF 尺寸时保留比例,您需要显式定义组合图的纵横比并统一处理缩放。

library(ggplot2) library(grid) library(gridExtra) # Data frame for the first plot df_1 <- data.frame( data = c(0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.2, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.4, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.5, 0.1, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.2, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.4, 0.2, 0.25, 0.5, 0.1, 0.15, 0.5, 0.5, 0.5, 0.1, 0.5, 0.1, 0.15, 0.5, 0.5, 0.4), base = 1:54, value = c(0.9557, 0.4407, 0.141, 3.4229, 3.5197, 4.7386, 6.9897, 0.3958, 4.7268, 1.8085, 10.5312, 5.9011, 7.9393, 5.7363, 13.8539, 11.2096, 14.8407, 11.4008, 0.5412, 10.3042, 11.3208, 15.6669, 8.2177, 12.6917, 20.7124, 10.9896, 24.7246, 7.0544, 21.0489, 16.4536, 7.4753, 28.2106, 32.7284, 29.7557, 23.3567, 29.9186, 30.3813, 15.1307, 20.2323, 34.4262, 20.8036, 18.7994, 41.7036, 26.828, 10.7628, 28.2335, 4.4982, 3.6528, 33.8571, 11.6208, 43.54, 26.7859, 22.2176, 11.0588) ) plot_1 <- ggplot(df_1, aes(x = base, y = data, fill = value)) + geom_bar(stat = 'identity', position = position_dodge(width = 0.9)) + scale_fill_distiller(palette = 'YlGnBu') + theme( axis.text.x = element_text(size = 9), legend.position = 'right', axis.title.x = element_blank(), axis.title.y = element_blank(), plot.margin = margin(0, 0, 0, 0) ) + xlim(0, 55) df_2 <- data.frame( x1 = c(4, 12, 1, 2), x2 = c(9, 15, 24, 54), y1 = c(0, 0, 0, 0), y2 = c(0, 0, 0, 0), priority = c('high', 'low', 'mid', 'high') ) plot_2 <- ggplot(df_2) + geom_curve(aes(x = x1, xend = x2, y = y1, yend = y2, color = priority), curvature = 1, linewidth = 0.5, ncp = 1000) + expand_limits(y = -1) + coord_fixed(ratio = 22, ylim = c(-1, 0)) + scale_colour_brewer(palette = 'YlGnBu') + theme( legend.position = 'right', axis.title.x = element_blank(), axis.title.y = element_blank(), plot.margin = margin(0, 0, 0, 0) ) + xlim(0, 55) # Combine plots grob_plots <- list(ggplotGrob(plot_1), ggplotGrob(plot_2)) # Equalize widths max_widths <- do.call(unit.pmax, lapply(grob_plots, function(g) g$widths)) grob_plots <- lapply(grob_plots, function(g) { g$widths <- max_widths; g }) # Combine with height proportions (e.g., 2:1) combined_plot <- arrangeGrob( grobs = grob_plots, heights = c(2, 1), # Control relative heights here padding = unit(0, "pt") ) # Save the plot ggsave( "~/Downloads/mytest.pdf", plot = combined_plot, width = 12, height = 8, dpi = 300 )
希望这有帮助。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.