如何在ggplot的geom_bar上方添加分组投篮命中率标签
解决方案
要实现按节(period)和投篮类型(type.shoot)分组标注命中率,核心是先聚合数据计算命中率,再用geom_text()将标注定位到堆叠柱的顶部。具体步骤如下:
1. 预处理数据,计算命中率
使用dplyr按period和type.shoot分组,提取命中数、计算总投篮数和命中率:
library(dplyr) # 计算每组的命中率数据框 shooting_stats <- dat_ %>% group_by(period, type.shoot) %>% summarise( made = Freq[result == "made"], # 获取命中次数 total = sum(Freq), # 总投篮数(命中+未命中) hit_rate = made / total, # 命中率 .groups = "drop" ) %>% # 格式化命中率为带百分号的字符串(保留2位小数) mutate(hit_rate_label = sprintf("%.2f%%", hit_rate * 100))
2. 修改ggplot代码,添加命中率标注
在原有堆叠柱状图基础上,使用geom_text()调用预处理好的shooting_stats数据框,将标注定位到柱子顶部(y值为总投篮数total):
library(ggplot2) ggplot(dat_) + geom_bar(aes(x = period, y = Freq, fill = result, group = 1), alpha = .8, color = "transparent", stat = "identity") + # 添加命中率标注 geom_text(data = shooting_stats, aes(x = period, y = total, label = hit_rate_label), vjust = -0.5, # 向上偏移,避免和柱子顶部重叠 size = 4) + scale_fill_manual("", c("Made", "Missed"), values = c("deepskyblue", "indianred1")) + facet_wrap(~type.shoot) + # 调整y轴范围,避免标注被截断 expand_limits(y = max(shooting_stats$total) * 1.1)
关键说明
- 之前使用
annotate()失败的原因:annotate()是全局静态添加文本,无法按分组动态获取不同的命中率数值。 - 直接用原数据调用
geom_text()失败的原因:原数据每个分组有2行(made/missed),会重复生成标注,且无法直接得到总投篮数和命中率,必须先聚合数据。
内容的提问来源于stack exchange,提问作者DR15
相关产品推荐
相关产品推荐

