如何用ggplot绘制含多级分组的分组柱状图?
用ggplot实现Excel风格的多级分组柱状图
当然可以用ggplot实现这种多级分组的柱状图,甚至能做出比Excel更灵活的效果。下面是几种常用方案:
方案1:利用ggh4x包快速实现多级X轴
ggh4x是专门扩展ggplot功能的工具包,其中的guide_axis_nested或facet_grid2可以直接处理多级分组轴,步骤简单:
- 先整理数据:确保数据包含多级分组列(比如一级分组
Group1、二级分组Group2) - 示例代码:
library(ggplot2) library(ggh4x) # 构造示例数据 df <- expand.grid( Group1 = c("类别A", "类别B"), Group2 = c("子项1", "子项2", "子项3"), Metric = c("指标X", "指标Y") ) df$Value <- sample(1:20, nrow(df), replace = TRUE) # 绘制嵌套轴柱状图 ggplot(df, aes(x = interaction(Group2, Group1), y = Value, fill = Metric)) + geom_col(position = position_dodge(width = 0.8)) + # 启用嵌套X轴,用分隔符区分层级 scale_x_discrete(guide = guide_axis_nested(delim = ".")) + theme(axis.text.x.bottom = element_text(angle = 45, hjust = 1)) # 或者用分面实现更清晰的分组(推荐) ggplot(df, aes(x = Group2, y = Value, fill = Metric)) + geom_col(position = position_dodge(width = 0.8)) + facet_grid2(. ~ Group1, scales = "free_x", space = "free_x", switch = "x") + theme(strip.placement = "outside")
方案2:手动自定义轴标签(无需额外包)
如果不想安装扩展包,可通过手动添加分隔线和分组标题模拟多级轴:
library(ggplot2) # 示例数据同上 df <- expand.grid( Group1 = c("类别A", "类别B"), Group2 = c("子项1", "子项2", "子项3"), Metric = c("指标X", "指标Y") ) df$Value <- sample(1:20, nrow(df), replace = TRUE) # 处理X轴显示文本(二级分组换行) df$X_Label <- paste(df$Group2, df$Group1, sep = "\n") ggplot(df, aes(x = X_Label, y = Value, fill = Metric)) + geom_col(position = position_dodge(width = 0.8)) + # 添加一级分组分隔线 annotate("segment", x = 3.5, xend = 3.5, y = 0, yend = max(df$Value) + 2, color = "black", size = 1) + # 添加一级分组标题 annotate("text", x = c(2, 5), y = max(df$Value) + 3, label = c("类别A", "类别B"), size = 5) + theme(axis.text.x = element_text(size = 9), plot.margin = margin(10, 10, 20, 10))
其他可选工具
ggtext:支持用富文本格式自定义轴标签,可调整换行、颜色等样式ComplexHeatmap:针对超复杂分组场景,能实现更精细的柱状图布局
核心前提是把数据整理为长格式,每一行对应一个数据点,同时保留所有分组层级的信息,这样ggplot就能快速将分组映射到视觉元素上。
内容的提问来源于stack exchange,提问作者BoTz
相关产品推荐
相关产品推荐

