如何在R中复现带分组X轴的Excel图表?
用ggplot2实现带主/子类别分组的X轴图表
这种带层级分组的X轴在ggplot2里可以通过分面(facet)或者手动调整轴标签+分组间距实现,下面是两种实用方案:
方案1:分面实现(适合类别区分明显的场景)
先模拟符合你描述的数据集(替换成你的真实数据列名即可):
# 模拟数据 df <- data.frame( 主类别 = rep(c("类别A", "类别B"), each = 3), 子类别 = c("子A1", "子A2", "子A3", "子B1", "子B2", "子B3"), 数值 = c(12, 18, 15, 22, 19, 25) )
通过分面+样式调整实现分组效果:
library(ggplot2) ggplot(df, aes(x = 子类别, y = 数值)) + geom_col(fill = "#2E86AB") + # 按主类别横向分面,隐藏默认分面标题 facet_wrap(~主类别, scales = "free_x", nrow = 1, strip.position = "bottom") + # 优化分面样式,增加分组间距 theme( strip.background = element_blank(), strip.placement = "outside", panel.spacing.x = unit(0.5, "cm"), axis.title.x = element_blank() )
这个方案自动完成分组,适配子类别数量不统一的场景。
方案2:手动调整轴标签(贴近Excel紧凑样式)
如果要在同一X轴上同时显示主/子类别,可手动处理标签和分组间距:
ggplot(df, aes(x = interaction(子类别, 主类别), y = 数值)) + geom_col(fill = "#2E86AB") + # X轴只显示子类别标签 scale_x_discrete(labels = df$子类别) + # 在轴下方添加主类别标签(位置根据子类别数量调整) annotate("text", x = c(2, 5), y = -1, label = c("类别A", "类别B"), size = 5, fontface = "bold") + # 调整绘图边距,避免标签被截断 theme( axis.title.x = element_blank(), plot.margin = margin(10, 10, 30, 10) )
若你的数据中子类别数量固定,这个方法能做出和Excel几乎一致的效果。
额外提示
- 若主/子类别是分散的列,直接替换代码里的列名即可;
- 要添加分组分隔竖线,可使用
geom_vline(); - 提供具体数据文件的话,可以帮你生成更精准的适配代码。
内容的提问来源于stack exchange,提问作者Ahmet-Salman
相关产品推荐
相关产品推荐

