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

R ggplot2堆叠条形图添加柱端总计值标签的实现方法

问题原因

你之前无法把总标签放到正确位置,核心是两个细节没处理对:

  • 用了coord_flip()把纵向图转成横向条形图后,坐标轴映射逻辑变了:原本控制垂直位置的vjust、nudge_y不再控制柱端方向的偏移,你之前写的nudge_y=10直接把标签甩到了绘图区外;同时总标签层没有取消主图层的fill映射继承,分组逻辑冲突,位置计算直接错位。
  • 原代码y轴上限设为0.6,柱末端的标签会被坐标轴边界截断,没有预留足够的显示空间。
修正方案

不需要改你之前的基础数据和总表计算逻辑,只需要替换原来注释掉的总标签层,同时微调y轴上限即可,核心修改片段:

# 把原代码的scale_y_continuous替换成下面这行,预留标签空间
scale_y_continuous(limits = c(0, 0.65)) +
# 替换原来注释掉的geom_text层,添加柱端总标签
geom_text(
  data = df_t,
  aes(x = company, y = value, label = Label),
  inherit.aes = FALSE, # 关键:取消主图层的fill等映射继承,避免分组错位
  hjust = -0.2, # 横向图下用hjust控制水平偏移,-0.2表示在柱末端右侧留少量间距
  size = 3
)
完整可运行代码
library(tidyverse)
# 构造基础数据
company=c('CompanyA','CompanyA', 'CompanyA', 'CompanyA','CompanyB', 'CompanyB', 'CompanyB', 'CompanyB')
SubSegment = c('SubSeg1', 'SubSeg1', 'SubSeg2', 'SubSeg2', 'SubSeg1', 'SubSeg1', 'SubSeg2', 'SubSeg2')
variable = c('Ratio1', 'Ratio2','Ratio1', 'Ratio2','Ratio1', 'Ratio2','Ratio1', 'Ratio2')
value = c(0.311, 0.256, 0.389, 0.105, 0.256, 0.1002, 0.2569, 0.2856)
df = as.data.frame(cbind(company, SubSegment, variable, value))
df=df%>% mutate(Label=value)
df[,4:ncol(df)]<- sapply(df[,4:ncol(df)] , as.numeric)
df[,ncol(df)]<- sapply(df[,ncol(df)] , function(x) scales::percent(x, accuracy = 0.1))

# 计算每个堆叠柱的总计值
df_t = df[,c(1,2,4)] 
df_t[,ncol(df_t)]<- sapply(df_t[,ncol(df_t)] , as.numeric)
df_t = df_t %>% group_by(company, SubSegment) %>%
  summarise(value = sum(value), .groups = "drop") %>% mutate(Label=value)
df_t[,ncol(df_t)]<- sapply(df_t[,ncol(df_t)] , function(x) scales::percent(x, accuracy = 0.1))

var_levels= c('Ratio1', 'Ratio2')
colors= c("#F3DF6C", "cyan")

plot.1<- ggplot(df, aes(fill=factor(variable, levels = var_levels), y=value, x=company)) + 
  geom_bar(position="stack", stat="identity", alpha=1) +
  scale_y_continuous(limits = c(0, 0.65)) +
  # 柱内分段标签
  geom_text(aes(label=Label), position = position_stack(vjust = 0.5), size=2.5) +
  # 柱端总计标签
  geom_text(
    data = df_t,
    aes(x = company, y = value, label = Label),
    inherit.aes = FALSE,
    hjust = -0.2,
    size = 3
  ) +
  facet_wrap(~factor(SubSegment ), ncol=1)  +
  theme(plot.title = element_text(size = 11), axis.title.x = element_blank(), axis.title.y = element_blank(), axis.text.x = element_blank(), 
        axis.ticks.x = element_blank(),     panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        legend.position = c(0.88, 0.89) , legend.text = element_text(size = 9.5),
        legend.title =  element_text(size = 11),
        legend.background = element_rect(fill="gray92", linetype="solid",colour ="gray75")) +
  scale_fill_manual(values=colors, name="SubSegment") + 
  coord_flip()

plot(plot.1)

运行后即可实现效果:每个堆叠柱内部居中显示分段百分比标签,柱的最右端显示整柱总计百分比,标签不会被截断、也不会和柱体重叠。

内容的提问来源于stack exchange,提问作者lu-202

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 17:30:49