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

R语言geom_line:为分组数据折线图添加数值标签

给ggplot折线图(日期维度qty总和)添加数值标签

我用ggplot制作了包含柱状图(geom_col)和折线图(geom_line)的组合图形,已成功在柱状图上方显示qty字段的标签,但希望给折线图(展示每个date变量对应的qty总和)的顶部也添加数值标签。以下是我的代码:

sample <- data.frame(service_type = c("A","B","C","A","B","C","A","B","C","A","B","C","A","B","C","A","B","C","A","B","C"),
                     qty = c(38,185,87,29,12,133,2,14,31,2,9,59,60,43,137,135,31,159,15,32,1),
                     year_week = c("2022 - CW02","2022 - CW02","2022 - CW02","2022 - CW03","2022 - CW03","2022 - CW03","2022 - CW04","2022 - CW04","2022 - CW04","2022 - CW05","2022 - CW05","2022 - CW05","2022 - CW06","2022 - CW06","2022 - CW06","2022 - CW07","2022 - CW07","2022 - CW07","2022 - CW08","2022 - CW08","2022 - CW08"),
                     xlabel2 = c("Jan-22","Jan-22","Jan-22","Jan-22","Jan-22","Jan-22","Jan-22","Jan-22","Jan-22","Feb-22","Feb-22","Feb-22","Feb-22","Feb-22","Feb-22","Feb-22","Feb-22","Feb-22","Feb-22","Feb-22","Feb-22")
)

sample <- sample %>%
  mutate(date = as.Date(paste0(year_week, 1), "%Y - CW%U%u")) 


ggplot(sample ) +
  
  aes(x = date, y = qty, fill = service_type) +
  
  geom_col(position = "dodge") +
  
  geom_line(aes(group = 1), stat = "summary", fun = sum, linetype = "dashed", size = 1, color = '#FF507B') +
  
  geom_text(aes(label=qty), 
            position=position_dodge(7 * 0.9), vjust = 0)+
  
  scale_fill_manual(values = c(A = "#FFC000", B = "#92D050", C = "#AE5AFF"))+
  scale_x_date(
    date_labels = "%Y - CW%U",
    date_breaks = "1 week",
    sec.axis = dup_axis(
      breaks = as.Date(paste0("15-", unique(sample$xlabel2)), "%d-%b-%y"),
      labels = \(x) format(x, "%b-%y")
    )
  ) +
  theme_minimal() +
  theme(legend.position = "left",
        axis.text.x.bottom = element_text(angle=90, hjust=1, vjust = 0.5),
        axis.title = element_blank(), legend.title = element_blank(),
        panel.grid.minor.x = element_blank())

实现方案

方案1:直接用stat="summary"生成标签

因为折线图是通过stat="summary"计算每周qty总和,所以添加标签时可以复用相同的统计逻辑,直接在现有代码中新增一行geom_text:

ggplot(sample ) +
  
  aes(x = date, y = qty, fill = service_type) +
  
  geom_col(position = "dodge") +
  
  geom_line(aes(group = 1), stat = "summary", fun = sum, linetype = "dashed", size = 1, color = '#FF507B') +
  
  # 柱状图标签
  geom_text(aes(label=qty), 
            position=position_dodge(7 * 0.9), vjust = 0)+
  
  # 新增:折线图总和标签
  geom_text(aes(group = 1), stat = "summary", fun = sum, 
            aes(label = after_stat(y)), color = '#FF507B', vjust = -1, size = 4) +
  
  scale_fill_manual(values = c(A = "#FFC000", B = "#92D050", C = "#AE5AFF"))+
  scale_x_date(
    date_labels = "%Y - CW%U",
    date_breaks = "1 week",
    sec.axis = dup_axis(
      breaks = as.Date(paste0("15-", unique(sample$xlabel2)), "%d-%b-%y"),
      labels = \(x) format(x, "%b-%y")
    )
  ) +
  theme_minimal() +
  theme(legend.position = "left",
        axis.text.x.bottom = element_text(angle=90, hjust=1, vjust = 0.5),
        axis.title = element_blank(), legend.title = element_blank(),
        panel.grid.minor.x = element_blank())

关键说明:

  • stat="summary", fun=sum:和折线图逻辑一致,计算每周qty总和
  • aes(label = after_stat(y)):用统计后得到的总和值作为标签文本
  • vjust = -1:让标签显示在折线点上方,避免和柱状图重叠
  • color = '#FF507B':和折线颜色统一,提升视觉一致性

方案2:提前计算汇总数据(逻辑更清晰)

如果不想重复调用统计逻辑,可以先提前计算每周的qty总和,再单独绘制折线和标签:

# 预计算每周qty总和
sample_sum <- sample %>%
  group_by(date) %>%
  summarise(total_qty = sum(qty, na.rm = TRUE)) %>%
  ungroup()

ggplot(sample ) +
  
  aes(x = date, y = qty, fill = service_type) +
  
  geom_col(position = "dodge") +
  
  # 使用预计算数据绘制折线
  geom_line(data = sample_sum, aes(x = date, y = total_qty, group = 1), 
            linetype = "dashed", size = 1, color = '#FF507B') +
  
  # 柱状图标签
  geom_text(aes(label=qty), 
            position=position_dodge(7 * 0.9), vjust = 0)+
  
  # 使用预计算数据添加标签
  geom_text(data = sample_sum, aes(x = date, y = total_qty, label = total_qty),
            color = '#FF507B', vjust = -1, size = 4) +
  
  scale_fill_manual(values = c(A = "#FFC000", B = "#92D050", C = "#AE5AFF"))+
  scale_x_date(
    date_labels = "%Y - CW%U",
    date_breaks = "1 week",
    sec.axis = dup_axis(
      breaks = as.Date(paste0("15-", unique(sample$xlabel2)), "%d-%b-%y"),
      labels = \(x) format(x, "%b-%y")
    )
  ) +
  theme_minimal() +
  theme(legend.position = "left",
        axis.text.x.bottom = element_text(angle=90, hjust=1, vjust = 0.5),
        axis.title = element_blank(), legend.title = element_blank(),
        panel.grid.minor.x = element_blank())

关键说明:

  • 提前计算汇总数据让代码逻辑更直观,也方便后续对总和数据做额外处理
  • 折线和标签都复用sample_sum数据,避免重复统计计算

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 18:54:52