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_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
相关产品推荐
相关产品推荐

