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

如何在ggplot2 facet_wrap各分面中添加多层X轴绘制条形图

ggplot2分面嵌套多层X轴实现方案

原代码使用interaction()合并年份和季度字段,会直接把两个值拼接成单行文本标签,无法实现分层嵌套效果,同时原代码存在两个小问题:一是映射的y轴变量Series不存在,实际数据字段为Series1;二是Series1为字符格式,直接绘图会导致数值映射错误,需要先转成数值型。

基础实现(无需额外依赖包)

先预处理数据:

library(ggplot2)
# 构造并清洗数据
df <- data.frame(
  Years =  c("2016","2016","2016","2016",
             "2017","2017","2017","2017", "2016","2016","2016","2016",
             "2017","2017","2017","2017"),
  Quarters =  c("1","2","3","4",
                "1","2","3","4", "1","2","3","4",
                "1","2","3","4"),
  panel=  c("A","A","A","A",
            "A","A","A","A", "B","B","B","B",
            "B","B","B","B"),
  Series1 = as.numeric(c("100","200","300","400","500","600","700","800", 
                         "400","200","300","600","500","300","700","800"))
)

绘图核心逻辑是把季度作为第一级X轴刻度,手动在刻度下方添加年份作为第二级标签:

ggplot(df, aes(x = Quarters, y = Series1)) +
  geom_col(width = 0.7) +
  # 分面仅释放X轴自由度即可
  facet_wrap(~panel, scales = "free_x") +
  # 配置第一级X轴(季度)
  scale_x_discrete(
    name = NULL,
    labels = c("Q1","Q2","Q3","Q4"),
    expand = c(0,0)
  ) +
  # 添加第二级X轴标签(年份),定位到每个年份对应季度组的中心下方
  annotate(
    geom = "text",
    x = c(2.5, 6.5, 2.5, 6.5), # 每个分面里2016年中心在Q1-Q4中点2.5,2017年在Q5-Q8中点6.5
    y = -60, # 标签位置在X轴下方,可根据自身y轴范围调整
    label = rep(c("2016", "2017"), 2),
    fontface = "bold",
    size = 3.8
  ) +
  # 可选:添加年份组分隔线,分层效果更清晰
  geom_vline(xintercept = 4.5, color = "gray60", linetype = "dashed") +
  # 关闭裁剪防止轴外标签被截断,y轴下限设为0避免负值区域显示
  coord_cartesian(clip = "off", ylim = c(0, NA)) +
  theme(
    # 给底部二级标签预留足够空间
    plot.margin = margin(b = 22),
    axis.text.x = element_text(margin = margin(t = 6))
  )

简化实现(借助ggh4x包)

如果不想手动计算二级标签位置,可以用ggh4x扩展包提供的嵌套轴向导,自动识别层级关系:

library(ggh4x)
ggplot(df, aes(x = interaction(Years, Quarters, lex.order = TRUE), y = Series1)) +
  geom_col(width = 0.7) +
  facet_wrap(~panel, scales = "free_x") +
  scale_x_discrete(
    name = NULL,
    labels = rep(c("Q1","Q2","Q3","Q4"), 2),
    # 调用嵌套轴向导自动生成二级标签
    guide = guide_axis_nested()
  ) +
  theme(
    # 配置二级轴的分隔线和标签样式
    ggh4x.axis.nestline.x = element_line(linewidth = 1),
    ggh4x.axis.nesttext.x = element_text(face = "bold")
  )

两种方案都可以在每个分面内实现「年份在上层分组、季度在下层刻度」的嵌套X轴效果,和facet_wrap的分面逻辑完全兼容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 14:03:20