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

如何将单面板与分面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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 06:36:04