You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使R ggplot2中两幅图的绘图面板尺寸完全一致?

解决ggplot2垂直堆叠图面板尺寸不一致的问题

问题说明

使用ggplot2绘制两张垂直堆叠的图形时,底部带x轴标签和标题的图(图2)因x轴元素占用空间,导致其绘图面板尺寸小于顶部无x轴标签的图(图1),y轴被压缩。需要让两张图的绘图面板完全对齐,同时保留底部图的x轴标签作为整体的x轴说明。

现有代码

图1(无x轴标签和标题)

plot1 <- ggplot(data, aes(x=pred_1, y="response", fill=pred_2)) +
    geom_violin(width=0.7) +
    geom_jitter(position=position_jitter(width=0.05)) +
    ggtitle("") +
    ylab("response") +
    xlab("") + # 无x轴标题
    ylim(0,3300) +
    scale_x_discrete(labels=c("level1", "level2")) +
    scale_fill_manual(values=c("red3","green4")) +
    geom_point(data=average_data, aes(x=pred_1, y="response"),
               position=position_dodge(width=0.7), size=4, shape=22, 
               stroke=1, show.legend=FALSE, color="black", fill="grey") +
    geom_line(data=average_data, aes(x=pred_1,y="response",group=1), linewidth=1) +
    theme_minimal() +
    theme(axis.title.x = element_text(margin = margin(t = 5), size=12, face="bold"),
          axis.title.y = element_text(margin = margin(r = 5), size=12, face="bold"),
          axis.text.x = element_blank(), # 隐藏x轴刻度标签
          axis.text.y = element_text(size = 10),
          panel.border = element_rect(color = "black", fill = NA, size = 1),
          legend.position = "none",
          plot.title = element_text(hjust = 0.5))

图2(带x轴标签和标题)

plot2 <- ggplot(data_2, aes(x=pred_1, y="response", fill=pred_2)) +
    geom_violin(width=0.7) +
    geom_jitter(position=position_jitter(width=0.05)) +
    ggtitle("") +
    ylab("response") +
    xlab("this is my x-axis title") +
    ylim(0,3300) +
    scale_x_discrete(labels=c("level1", "level2")) +
    scale_fill_manual(values=c("red3","green4")) +
    geom_point(data=average_data_2, aes(x=pred_1, y="response"),
               position=position_dodge(width=0.7), size=4, shape=22, 
               stroke=1, show.legend=FALSE, color="black", fill="grey") +
    geom_line(data=average_data_2, aes(x=pred_1,y="response",group=1), linewidth=1) +
    theme_minimal() +
    theme(axis.title.x = element_text(margin = margin(t = 5), size=12, face="bold"),
          axis.title.y = element_text(margin = margin(r = 5), size=12, face="bold"),
          axis.text.y = element_text(size = 10),
          panel.border = element_rect(color = "black", fill = NA, size = 1),
          legend.position = "none",
          plot.title = element_text(hjust = 0.5))

解决方案

方案1:使用patchwork包(推荐,对齐最省心)

patchwork专门用于ggplot2图形组合,自动对齐面板,语法简洁:

# 安装并加载包
install.packages("patchwork")
library(patchwork)

# 垂直堆叠图形,plot1在上,plot2在下
combined_plot <- plot1 + plot2 + plot_layout(ncol = 1)

# 可选:调整margin减少图形间空隙,同时确保面板对齐
plot1 <- plot1 + theme(plot.margin = margin(t = 10, r = 10, b = 5, l = 10, "pt"))
plot2 <- plot2 + theme(plot.margin = margin(t = 5, r = 10, b = 10, l = 10, "pt"))
combined_plot <- plot1 / plot2 # 垂直堆叠的简写语法

方案2:用gtable统一面板高度

将ggplot对象转为gtable,手动设置两张图的面板高度一致:

library(gridExtra)
library(gtable)

# 转换为gtable对象
g1 <- ggplotGrob(plot1)
g2 <- ggplotGrob(plot2)

# 获取最大面板高度,统一设置给两张图
panel_height <- max(g1$heights[g1$layout$name == "panel"], 
                    g2$heights[g2$layout$name == "panel"])
g1$heights[g1$layout$name == "panel"] <- unit(panel_height, "null")
g2$heights[g2$layout$name == "panel"] <- unit(panel_height, "null")

# 组合图形
grid.arrange(g1, g2, ncol = 1)

方案3:手动调整图1的底部margin

给图1底部预留与图2x轴标签+标题相同高度的空间,确保面板高度一致:

# 调整图1的底部margin,预留x轴元素空间
plot1 <- plot1 + theme(
  plot.margin = margin(t = 10, r = 10, b = 30, l = 10, "pt"), # 底部留30pt空间
  axis.title.x = element_blank()
)

# 调整图2的顶部margin减少空隙
plot2 <- plot2 + theme(plot.margin = margin(t = 0, r = 10, b = 10, l = 10, "pt"))

# 用ggpubr::ggarrange垂直对齐组合
library(ggpubr)
ggarrange(plot1, plot2, ncol = 1, align = "v")

内容的提问来源于stack exchange,提问作者RobH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 04:59:50