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

R语言中facet_grid分组后行高不一致,如何强制统一行高?

解决ggplot热力图分面后行高度不一致的问题

在使用ggplot2的facet_grid按行分组绘制热力图时,若不同分组的Y轴类别数量不同,会出现每个分组内的瓷砖高度不一致的情况(比如示例中gr=a只有1个类别,瓷砖高度是gr=b中4个类别瓷砖高度的4倍)。下面提供两种可行的解决方法:

方法1:用ggh4x包的facet_grid2(推荐)

ggh4x是ggplot2的扩展包,提供了更灵活的分面控制功能,通过设置space = "free_y"参数,可以让每个分面的高度根据自身Y轴类别数量自动调整,从而保证所有瓷砖高度一致。

代码示例

library(data.table)
library(ggplot2)
library(ggh4x)

dt <- data.table(x = c(1, 2, 3, 4, 5),
                 y = c("a_x", "b_w", "b_x", "b_y", "b_z"),
                 gr = c("a", "b", "b", "b", "b"))

ggplot(dt, aes(x = x, y = y, fill = x)) + 
  geom_tile() +
  # 替换facet_grid为facet_grid2,设置scales和space参数
  facet_grid2(rows = vars(gr), scales = "free_y", space = "free_y")

方法2:用patchwork手动拼接分面

如果不想额外安装包,可以将每个分组的热力图单独绘制,再用patchwork按行拼接,手动指定每个子图的高度比例(比例等于对应分组的Y类别数量)。

代码示例

library(data.table)
library(ggplot2)
library(patchwork)

dt <- data.table(x = c(1, 2, 3, 4, 5),
                 y = c("a_x", "b_w", "b_x", "b_y", "b_z"),
                 gr = c("a", "b", "b", "b", "b"))

# 拆分数据为单个分组的子集
dt_a <- dt[gr == "a"]
dt_b <- dt[gr == "b"]

# 绘制每个分组的热力图
p_a <- ggplot(dt_a, aes(x = x, y = y, fill = x)) + 
  geom_tile() +
  facet_grid(rows = vars(gr), scales = "free_y") +
  # 隐藏第一个图的分面标题,避免重复
  theme(strip.background = element_blank(), strip.text = element_blank())

p_b <- ggplot(dt_b, aes(x = x, y = y, fill = x)) + 
  geom_tile() +
  facet_grid(rows = vars(gr), scales = "free_y")

# 按高度比例拼接,比例对应每个分组的Y类别数量
p_a / p_b + plot_layout(heights = c(nrow(dt_a), nrow(dt_b)))

原理说明

  • 方法1中,space = "free_y"会让分面高度与该分面内Y轴类别数成正比,每个瓷砖的高度自然统一。
  • 方法2通过手动控制子图高度比例,让高度匹配各自的Y类别数量,实现瓷砖高度一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 14:35:25