如何将两个ggplot图形并排展示且保留默认布局并扩展画布?
解决ggplot2双图并排时布局拥挤、注释溢出的问题
问题描述
我已经调整好若干ggplot图形,确保注释能完美适配绘图边界。现在想将其中两个图形并排展示,尝试用grid.arrange和patchwork实现后,出现布局变形:元素拥挤、点重叠难以辨认,注释框超出绘图区域。我需要扩展画布,让每个图形与单独绘制时(默认画布尺寸)完全一致,画布宽度需略大于两倍单图宽度以预留间距,该如何实现?
示例代码
library(ggplot2) library(ggtext) library(tidyverse) library(patchwork) N <- 10000 rho = 0.5 mu <- c(0, 0) sigma <- matrix(c(1, rho, rho, 1 ), nrow = 2, ncol = 2, byrow = TRUE) vs = MASS::mvrnorm(N, mu, sigma) df = tibble(rMZall = vs[,1], rDZall = vs[,2], n_twin_pairs = runif(N, 5000, 50000)) plot <- function(min_twin_pairs) { ggplot(data=df |> filter(n_twin_pairs > min_twin_pairs), aes(rMZall, rDZall)) + ggtitle(sprintf("Studies with > %d twin pairs", min_twin_pairs)) + theme(legend.position="none") + # Bounds scale_x_continuous(name = "rMZ", limits = c(-0.05, 1.1), breaks = seq(0,1,0.25)) + scale_y_continuous(name = "rDZ", limits = c(-0.05, 1), breaks = seq(0,1,0.25)) + coord_fixed() + # Scatterplot stat_density2d(aes(fill=..level.., alpha=..level..), geom='polygon', colour='black', linewidth = 0.1) + scale_fill_continuous(low="green", high="red") + geom_point(aes(size = sqrt(n_twin_pairs))) + scale_size_continuous(range = c(0, 1)) + # AE and AD lines geom_abline(intercept = 0, slope = .5) + annotate(geom = "richtext", x = 1, y = .5, label = "AE model", angle = 26.6) + geom_abline(intercept = 0, slope = .25) + annotate(geom = "richtext", x = 1, y = .25, label = "AD model", angle = 14.0) } plot1000 = plot(min_twin_pairs = 1000) plot4000 = plot(min_twin_pairs = 4000) # 单独绘图正常 plot1000 plot4000 # 并排绘图出现问题 plot1000 + plot4000
解决方案
核心思路是让整体画布宽度足够容纳两个单图的原始宽度+间距,高度保持单图高度,同时保留图形的固定宽高比(你的代码中已经用coord_fixed()实现,这一点很关键)。
方法1:使用patchwork包
patchwork默认会缩放图形适配画布,解决方法是在导出图形时直接指定足够大的画布尺寸:
# 拼接图形 combined_plot <- plot1000 + plot4000 # 导出时设置宽度为单图的2倍多(预留间距),高度与单图一致 # 假设单图默认宽度为8,这里设为17(略大于2*8=16) ggsave("combined_patchwork.png", combined_plot, width = 17, height = 8, dpi = 300)
如果需要在RStudio预览窗口中看到正确效果,可以调整预览窗口的宽度到足够大,或者在拼接时明确设置布局的宽高比:
combined_plot <- plot1000 + plot4000 + plot_layout(guides = "collect", widths = c(1,1))
方法2:使用gridExtra包的grid.arrange
同样通过调整导出时的画布尺寸来保证子图原始大小:
library(gridExtra) # 拼接图形 grid_combined <- grid.arrange(plot1000, plot4000, ncol = 2, widths = c(1,1)) # 导出时设置合适的宽高 ggsave("combined_grid.png", grid_combined, width = 17, height = 8, dpi = 300)
关键说明
- 你的图形使用了
coord_fixed()固定了坐标比例,只要画布尺寸足够,图形元素就不会被压缩变形。 - 注释框溢出的问题本质也是画布空间不足,只要给每个子图预留足够的原始宽度,注释就会回到绘图边界内。
内容的提问来源于stack exchange,提问作者Mohan
相关产品推荐
相关产品推荐

