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
相关产品推荐
相关产品推荐

