如何将单面板与分面ggplot2图横向拼接并保证所有面板宽度一致
解决方法
最简单的实现方式是把双分面的plt2拆分为两个独立的单面板图表,再和plt1共三个单图统一拼接,拼接工具会自动对齐所有绘图区域,保证宽度完全一致,同时也可以灵活控制是否共享坐标轴。
基于patchwork的实现代码
library(tidyverse) library(patchwork) # 第一个面板:setosa plt_setosa <- iris %>% filter(Species == "setosa") %>% ggplot(aes(x = Sepal.Length, y = Petal.Length)) + geom_point() + ggtitle("setosa") # 第二个面板:versicolor plt_versi <- iris %>% filter(Species == "versicolor") %>% ggplot(aes(x = Sepal.Length, y = Petal.Length)) + geom_point() + ggtitle("versicolor") + # 如需共享Y轴保留下面三行,需要独立Y轴则删掉 theme( axis.title.y = element_blank(), axis.text.y = element_blank(), axis.ticks.y = element_blank() ) # 第三个面板:virginica plt_virgi <- iris %>% filter(Species == "virginica") %>% ggplot(aes(x = Sepal.Length, y = Petal.Length)) + geom_point() + ggtitle("virginica") + # 如需共享Y轴保留下面三行,需要独立Y轴则删掉 theme( axis.title.y = element_blank(), axis.text.y = element_blank(), axis.ticks.y = element_blank() ) # 拼接三个图,自动对齐绘图区,默认等宽 plt_setosa + plt_versi + plt_virgi + plot_layout(nrow = 1, axes = "collect") & # 让标题和原生facet的顶部条样式一致,可按需调整 theme( plot.title = element_text( hjust = 0.5, margin = margin(3,0,3,0), size = 11, fill = "grey92" ) )
如果习惯用cowplot,把拼接代码替换为下面的内容即可,效果一致:
cowplot::plot_grid(plt_setosa, plt_versi, plt_virgi, nrow = 1, align = "h", axis = "tb")
原代码问题原因
你之前的方法失效是因为rel_widths统计的是整个图表(包含轴标签、边距、分面间距等所有元素)的相对宽度:双分面的plt2总宽度包含1个Y轴宽度+2个绘图区宽度+1个分面间距,而单面板的plt1总宽度包含1个Y轴宽度+1个绘图区宽度,设置1:2的相对宽度后,分配给plt1绘图区的实际宽度自然会小于plt2的单个分面宽度。
如果不想拆分图表,也可以通过gtable包手动提取两个图表的绘图区再拼接,但操作复杂度远高于拆分分面的方案。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

