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

如何在ggplot2的facet_grid中移除指定列并优化空白区域?

问题描述

我有以下R代码生成热力图:

tmp <- data.frame(
  "channel_topic" = rep(LETTERS[seq(1:16)],9),
  "p1_age_cat_complete" = rep(1:9, each = 16),
  "n" = sample(100, size = 144, replace = TRUE)) |>
  group_by(channel_topic) |>
  mutate(n_group = sum(n))|>
  group_by(n_group) |>
  mutate(group_id = abs(cur_group_id()-17)) |>
  ungroup() |>
  mutate(group_id = ifelse(str_detect(channel_topic, "N"),
                           99,
                           ifelse(str_detect(channel_topic, "O"),
                                  100,
                                  ifelse(str_detect(channel_topic, "P"),
                                         101,
                                         group_id)))) |>
  mutate(facets = ifelse(group_id < 99,"1","2"),
         facets_2 = ifelse(p1_age_cat_complete == "9", "2","1"))


ggplot(tmp) +
  facet_grid(
    cols = vars(facets_2),
    rows = vars(facets),
    scales = "free_y",
    space = "free_y",
  ) +
  geom_tile(
    aes(
      x = p1_age_cat_complete,
      y = reorder(channel_topic, -group_id),
      fill = n
    )
  ) + theme(
    axis.text.x = element_text(angle = 90)
  ) +
  labs(
    x = "Alter",
    y = "Channel Topic",
    fill = "Anzahl",
    subtitle = paste("N = ", sum(tmp$n), sep = "")
  ) + theme(
    panel.background = element_rect(fill = "white",
                                    colour = "white"),
    panel.grid.major = element_line(colour = "gray90"),
    panel.grid.minor = element_line(colour = "grey95"),
    plot.subtitle = element_text(hjust = 1),
    axis.text.x = element_text(angle = 90),
    strip.background = element_blank(),
    strip.text = element_blank()
  ) +
  scale_x_discrete(limits = 1:9)

当前图表存在空列区域,我需要实现:

  • 左侧面板移除“9”列
  • 右侧面板仅保留“9”列
  • 消除空列区域,只保留类似y轴的少量间隔

解决方案

核心思路是针对不同面板精准筛选对应数据,同时调整分面与坐标轴设置,具体修改如下:

1. 数据筛选处理

给数据集新增标记列,过滤掉各面板不需要的行:

tmp <- tmp |>
  mutate(keep = case_when(
    facets_2 == "1" & p1_age_cat_complete != "9" ~ TRUE,  # 左侧面板保留非9的列
    facets_2 == "2" & p1_age_cat_complete == "9" ~ TRUE,   # 右侧面板只保留9列
    TRUE ~ FALSE
  )) |>
  filter(keep)  # 移除不需要的行

2. 调整ggplot设置

  • 移除强制x轴显示1-9的scale_x_discrete(limits = 1:9),让坐标轴自适应现有数据
  • 将facet_grid的scales改为"free",让x轴根据面板实际数据自由缩放,避免空列占位

修改后的完整代码

library(tidyverse)

tmp <- data.frame(
  "channel_topic" = rep(LETTERS[seq(1:16)],9),
  "p1_age_cat_complete" = rep(1:9, each = 16),
  "n" = sample(100, size = 144, replace = TRUE)) |>
  group_by(channel_topic) |>
  mutate(n_group = sum(n))|>
  group_by(n_group) |>
  mutate(group_id = abs(cur_group_id()-17)) |>
  ungroup() |>
  mutate(group_id = ifelse(str_detect(channel_topic, "N"),
                           99,
                           ifelse(str_detect(channel_topic, "O"),
                                  100,
                                  ifelse(str_detect(channel_topic, "P"),
                                         101,
                                         group_id)))) |>
  mutate(facets = ifelse(group_id < 99,"1","2"),
         facets_2 = ifelse(p1_age_cat_complete == "9", "2","1")) |>
  # 新增筛选逻辑
  mutate(keep = case_when(
    facets_2 == "1" & p1_age_cat_complete != "9" ~ TRUE,
    facets_2 == "2" & p1_age_cat_complete == "9" ~ TRUE,
    TRUE ~ FALSE
  )) |>
  filter(keep)


ggplot(tmp) +
  facet_grid(
    cols = vars(facets_2),
    rows = vars(facets),
    scales = "free",  # 让x/y轴自由适配面板数据
    space = "free_y",
  ) +
  geom_tile(
    aes(
      x = p1_age_cat_complete,
      y = reorder(channel_topic, -group_id),
      fill = n
    )
  ) +
  labs(
    x = "Alter",
    y = "Channel Topic",
    fill = "Anzahl",
    subtitle = paste("N = ", sum(tmp$n), sep = "")
  ) + 
  theme(
    panel.background = element_rect(fill = "white", colour = "white"),
    panel.grid.major = element_line(colour = "gray90"),
    panel.grid.minor = element_line(colour = "grey95"),
    plot.subtitle = element_text(hjust = 1),
    axis.text.x = element_text(angle = 90),
    strip.background = element_blank(),
    strip.text = element_blank()
  )

关键改动说明

  • 从数据层面直接移除不需要的行,彻底消除空列占位的根源
  • 调整分面缩放规则,让坐标轴仅显示面板内存在的类别
  • 去掉强制的x轴范围限制,实现面板间的自适应布局

内容的提问来源于Stack Exchange,提问作者Aaron Philipp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 03:21:07