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

使用grid.arrange展示多个facet_wrap图时如何统一面板宽度

方案1:补充空分面适配现有逻辑

该方案适配你当前拆分绘图再合并的开发逻辑,通过给类别数少的父组补充空分类水平实现分面等宽:

library(dplyr)
library(ggplot2)
library(gridExtra)

# 原始示例数据
x <- c(1, 2, 3, 4, 1, 2)
y <- c(3, 3, 3, 3, 3, 3)
category <- c("category a", "category b", "category c", "category d", "category e", "category f")
group <- c("group one", "group one", "group one", "group one", "group two", "group two")
df <- data.frame(x, y, category, group)

# 计算所有父组中最多的类别数,示例中为4
max_cat <- max(table(df$group))

# 封装单组绘图函数,自动补全空分类水平
draw_group_plot <- function(group_name){
  sub_data <- filter(df, group == group_name)
  # 补全分类水平到最大数量,空水平用空字符串占位
  cat_levels <- c(unique(sub_data$category), rep("", max_cat - n_distinct(sub_data$category)))
  sub_data$category <- factor(sub_data$category, levels = cat_levels)
  
  ggplot(sub_data, aes(x = x, y = y)) +
    geom_point() +
    # drop=FALSE保留空水平对应的分面
    facet_wrap(~category, nrow = 1, drop = FALSE) +
    labs(title = group_name) +
    theme(
      # 空分面的标题自动隐藏,可根据需求调整样式
      strip.background = element_rect(fill = NA, color = NA)
    )
}

g1 <- draw_group_plot("group one")
g2 <- draw_group_plot("group two")

grid.arrange(g1, g2, ncol = 1)

运行后第二行的Group Two会自动生成两个空白分面,所有有效分面的宽度完全一致。


方案2:嵌套分面一步生成(无需拆分合并)

如果不需要单独调整每个父组的绘图逻辑,直接使用嵌套分面是更简洁的方案,自动保证分面等宽,还支持父组标题自定义:

library(ggplot2)
# 未安装ggh4x可先运行 install.packages("ggh4x")
library(ggh4x)

max_cat <- max(table(df$group))

ggplot(df, aes(x = x, y = y)) +
  geom_point() +
  # 按父组+类别嵌套分面,每行对应一个父组
  facet_nested_wrap(
    ~ group + category, 
    ncol = max_cat,
    nest_line = TRUE, # 显示父组的嵌套连接线
    strip.position = "top"
  ) +
  theme(
    strip.background = element_rect(fill = "grey95"),
    ggh4x.facet.nestline = element_line(color = "grey60", linewidth = 1)
  )

该方案不需要拆分数据集、单独绘图再合并,所有布局逻辑自动完成。


方案3:patchwork灵活布局

如果需要对每个父组的图做独立样式调整,也可以用patchwork代替grid.arrange,通过插入空白占位符实现等宽布局:

library(dplyr)
library(ggplot2)
library(patchwork)

# 原有绘图逻辑无需修改
g1 <- df %>% 
  filter(group == "group one") %>% 
  ggplot(aes(x = x, y = y)) +
  geom_point() +
  facet_wrap(~category, nrow = 1) +
  labs(title = "Group One")

g2 <- df %>% 
  filter(group == "group two") %>% 
  ggplot(aes(x = x, y = y)) +
  geom_point() +
  facet_wrap(~category, nrow = 1) +
  labs(title = "Group Two")

# 定义布局:第一行g1占4列,第二行g2占2列+2个空白占位符各占1列
layout_design <- "
AAAA
BBCC
"

g1 + g2 + plot_spacer() + plot_spacer() +
  plot_layout(design = layout_design, guides = "collect")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 16:48:02