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

R语言ggplot2中geom_text()无法正确标注geom_col柱状图

R ggplot2 geom_col添加数值标签位置异常、文字糊成一团解决方案

问题复现

使用geom_col()绘制骑手类型对应总骑行距离柱状图时,尝试通过geom_text()添加柱顶数值标签,调整vjust参数希望将标签放在柱顶内侧,但标签始终堆积在柱底、模糊无法辨识,原始代码如下:

total_distance_ridden_by_rider_type <- 
                                ggplot(consolidated_data_202106_202205, aes(member_casual, distance))+
                                geom_col(aes(fill = member_casual))+
                                labs(y = "Distance ridden in km", 
                                     x = "Rider type",
                                     title = "Distance ridden by Rider type in km",
                                     subtitle = "Over the period of 2021-06-01 - 2022-05-31",
                                     fill = "Rider type")+
                                scale_y_continuous(labels = unit_format(unit = "M", scale = 1e-6))+
                                 geom_text(aes(x = member_casual, y = distance, label = comma(distance)), 
                                      stat = "identity", 
                                      vjust = 1.5, 
                                      colour = "black", 
                                      size = 5)+
                                theme(legend.position = "top", 
                                      plot.title = element_text(size = 20), 
                                      plot.subtitle = element_text(size = 15))

运行效果截图:
geom_text标签异常运行效果

问题根源

两个核心逻辑错误导致异常:

  • 传入绘图函数的是未聚合的单条骑行明细数据:geom_col()默认使用stat = "identity",即逐行读取数据映射坐标,同组数据会从y=0开始堆叠出总柱高,但不会自动按骑手类型分组计算总骑行距离;对应geom_text()会为每一条明细记录都生成一个数值标签,当数据集包含几十万甚至上百万条骑行记录时,所有标签会挤在柱体范围内糊成一团,根本无法辨识。
  • 此时vjust参数作用在每一个单独的明细标签上,而不是分组总柱高对应的标签位置,所以不管怎么调整参数,标签都不会出现在预期的总柱顶位置。

修复方案

方案1:提前聚合数据(推荐新手使用,逻辑最清晰)

先按骑手类型分组计算总骑行距离,用汇总后的数据集绘图,从根源上避免逐行生成标签的问题:

library(tidyverse)
library(scales) # 加载comma、unit_format依赖的函数

# 第一步:分组汇总总骑行距离
rider_type_distance_summary <- consolidated_data_202106_202205 %>%
  group_by(member_casual) %>%
  summarise(distance = sum(distance, na.rm = TRUE)) # 加na.rm避免空值导致计算失败

# 第二步:用汇总后的数据绘图
total_distance_ridden_by_rider_type <- 
  ggplot(rider_type_distance_summary, aes(member_casual, distance))+
  geom_col(aes(fill = member_casual))+
  labs(y = "Distance ridden in km", 
       x = "Rider type",
       title = "Distance ridden by Rider type in km",
       subtitle = "Over the period of 2021-06-01 - 2022-05-31",
       fill = "Rider type")+
  scale_y_continuous(labels = unit_format(unit = "M", scale = 1e-6))+
  geom_text(aes(label = comma(distance)), 
            vjust = 1.5, # 该参数此时可正常生效,1.5对应柱顶内侧位置
            colour = "white", # 柱内标签用白色比黑色辨识度更高
            size = 5)+
  theme(legend.position = "top", 
        plot.title = element_text(size = 20), 
        plot.subtitle = element_text(size = 15))

方案2:在图层内直接指定统计逻辑(无需提前处理数据)

不想提前做数据汇总的话,给柱体和文本图层都指定按分组求和的统计规则,直接在绘图环节完成聚合:

total_distance_ridden_by_rider_type <- 
  ggplot(consolidated_data_202106_202205, aes(member_casual, distance))+
  geom_col(aes(fill = member_casual),
           stat = "summary", fun = "sum")+ # 指定按组求和计算柱高
  labs(y = "Distance ridden in km", 
       x = "Rider type",
       title = "Distance ridden by Rider type in km",
       subtitle = "Over the period of 2021-06-01 - 2022-05-31",
       fill = "Rider type")+
  scale_y_continuous(labels = unit_format(unit = "M", scale = 1e-6))+
  geom_text(aes(label = comma(after_stat(y))),
            stat = "summary", fun = "sum", # 和柱体保持一致的汇总逻辑
            vjust = 1.5,
            colour = "white",
            size = 5)+
  theme(legend.position = "top", 
        plot.title = element_text(size = 20), 
        plot.subtitle = element_text(size = 15))

调整提示:如果需要把标签放在柱体外侧顶部,把vjust值改为-0.5,文字颜色换回黑色即可,避免和柱体填充色重叠看不清。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:15:33