如何使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
相关产品推荐
相关产品推荐

