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

ggplot2堆叠柱状图:如何按日期排序、自定义颜色并修改图例

堆叠柱状图解决方案

核心需求

  • 按week分组,每星期一列;堆叠顺序为每周最早日期(周四)在底部,最晚日期(周三)在顶部;
  • 为每个tp_code使用数据中定义的tp_color自定义颜色;
  • 图例以tp_code作为标签。

数据集

session_df <- structure(list(date = structure(c(19570, 19571, 19572, 19573, 
  19574, 19575, 19576, 19577, 19578, 19579, 19580, 19581, 19582, 
  19583), class = "Date"), metric = c(2, 8, 12, 18, 6, 12, 20, 
  2, 6, 9, 7, 19, 4, 17), tp_code = c("Off", "ReEntry", "Strength", 
  "Match 1", "Recovery", "Activation", "Match 2", "Off", "Strength", 
  "Speed", "Activation", "Match 1", "ReEntry-Activation", "Match 2"
  ), week = structure(c(19566, 19566, 19566, 19573, 19573, 19573, 
  19573, 19573, 19573, 19573, 19580, 19580, 19580, 19580), class = "Date"), 
      tp_color = c("grey", "lightgreen", "blue", "darkgreen", "chartreuse", 
      "lightyellow", "darkgreen", "grey", "blue", "yellow", "lightyellow", 
      "darkgreen", "lightgreen", "darkgreen")), row.names = c(NA, 
  -14L), class = c("tbl_df", "tbl", "data.frame"))

问题根源

之前的尝试要么将fill映射到date导致图例错误,要么映射到tp_code但使用全局因子水平控制堆叠,无法适配不同周内tp_code对应的日期顺序差异。ggplot的堆叠顺序默认由fill的因子水平决定,但我们需要按每个周内的日期顺序独立控制堆叠,同时保留tp_code作为填充映射以保证图例和颜色正确。

解决方案

步骤1:预处理数据,生成周内堆叠顺序标记

按周分组,对每个周内的行按日期升序排序,生成每个行在周内的堆叠顺序编号:

library(tidyverse)

session_df_processed <- session_df %>%
  group_by(week) %>%
  arrange(date) %>% # 每周内按日期从早到晚(周四→周三)排序
  mutate(stack_order = row_number()) %>% # 生成周内堆叠顺序编号,1为最早日期
  ungroup() %>%
  # 保留tp_code的因子水平,确保颜色映射正确
  mutate(tp_code = factor(tp_code, levels = distinct(session_df, tp_code, tp_color)$tp_code))

步骤2:绘制堆叠柱状图

通过group = stack_order指定堆叠顺序,同时保留fill = tp_code以保证图例和颜色正确:

# 提取tp_code与自定义颜色的映射关系
cols <- distinct(session_df, tp_code, tp_color) %>% deframe()

session_df_processed %>%
  ggplot(aes(x = week, y = metric, fill = tp_code)) +
  geom_bar(
    stat = "identity",
    position = position_stack(reverse = FALSE), # reverse=FALSE让编号小的(最早日期)在底部
    aes(group = stack_order) # 关键:按周内的stack_order控制堆叠顺序
  ) +
  scale_fill_manual(values = cols) + # 应用自定义颜色
  theme_minimal() +
  labs(x = "周", y = "指标值", fill = "训练类型")

效果验证

  • 堆叠顺序:每个周内最早日期(周四)在底部,最晚日期(周三)在顶部;
  • 颜色:每个tp_code的颜色与数据中tp_color完全匹配;
  • 图例:显示tp_code作为标签,清晰对应训练类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 12:55:02