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

在ggplot2柱状图顶部添加总占比标签,Y轴保留计数显示

解决ggplot2柱状图Y轴显示计数、顶部标注百分比的问题

你的问题出在已经提前汇总了数据,但在geom_text里依然用了stat="count"——这会让ggplot重新基于原始数据集计算计数和比例,和你之前用group_by+summarize算出的结果冲突,自然达不到预期效果。

下面给你两种可行的解决方案,对应不同的使用场景:

方案1:基于提前汇总的数据集(推荐,更清晰)

既然你已经算出了count和percent,直接用这两个列来定义标签和位置就行:

library(tidyverse)
library(scales)

iris %>% 
  group_by(Species) %>% 
  summarize(count = n()) %>% 
  mutate(percent = count / sum(count)) %>% 
  ggplot(aes(x = Species, y = count)) +
  geom_bar(stat = "identity", fill = "#2E86AB") +  # 可选:给柱子加颜色
  geom_text(
    aes(label = percent(percent)),  # 直接用提前计算好的percent列
    vjust = -0.5,  # 把标签向上偏移,避免和柱子顶部重叠
    size = 4,  # 调整标签字号,按需修改
    color = "#2D3047"  # 可选:修改标签颜色
  ) +
  ylim(0, max(.$count) * 1.1)  # 扩展Y轴上限,防止标签超出图表范围

关键解释:

  • 不需要再依赖stat="count"的内部变量(比如..prop..),直接调用你自己计算的percent列即可。
  • vjust=-0.5控制标签垂直位置,负数表示向上偏移;如果标签还是和柱子太近,可以调小这个值(比如-1)。
  • ylim的设置很重要,否则最高的柱子顶部标签可能会被图表边界截断。

方案2:直接基于原始数据集(无需提前汇总)

如果你不想提前处理数据,也可以在ggplot里通过after_stat直接获取统计后的计数,再计算百分比:

library(tidyverse)
library(scales)

iris %>% 
  ggplot(aes(x = Species)) +
  geom_bar(aes(y = after_stat(count)), stat = "count", fill = "#2E86AB") +
  geom_text(
    aes(
      y = after_stat(count),
      label = percent(after_stat(count) / sum(after_stat(count)))
    ),
    stat = "count",
    vjust = -0.5,
    size = 4,
    color = "#2D3047"
  ) +
  ylab("Count") +
  ylim(0, max(table(iris$Species)) * 1.1)

关键解释:

  • after_stat(count)可以获取stat="count"计算出的每个类别的计数。
  • 用after_stat(count)/sum(after_stat(count))实时计算每个类别占总数的百分比,再用percent()格式化输出。

两种方案都能实现你要的效果:Y轴显示计数数值,柱子顶部标注对应类别的占比百分比。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:38:49