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

R ggplot2堆叠柱状图顶部放置指定列Freq数值的实现问题

问题原因

你将数据集转为长格式后,每个Clonotype分组对应2行记录,geom_text继承全局的x、y映射时,会在每个x位置输出2次完全相同的Freq标签,因此出现重复显示的问题。

修改后的完整代码

你可以直接在geom_text层指定使用按Clonotype汇总的数据集,同时把Freq的计算逻辑移到ggplot调用环节,不需要提前生成Freq列:

library(ggplot2)
library(tidyr)
library(dplyr)

clono_df_long <- data.frame(Clonotype=LETTERS[1:5], Number_Hit_Cells=c(234,56,568,34,46),
                            Number_NonHit_Cells=c(52,12,234,21,31))
clono_df_long <- as.data.frame(pivot_longer(clono_df_long,
                                            -Clonotype,
                                            names_to = "Cells", values_to = "Value"))
clono_df_long$Clonotype <- factor(clono_df_long$Clonotype, levels=unique(clono_df_long$Clonotype))
clono_df_long$Cells <- factor(clono_df_long$Cells, levels=c('Number_NonHit_Cells','Number_Hit_Cells'))

P <- ggplot(clono_df_long, aes(x=Clonotype, y=Value, fill=Cells)) +
  geom_bar(stat="identity") +
  scale_fill_manual(values=c('gray70', 'gray40')) +
  # 汇总计算每个Clonotype的总高度和Freq,仅输出1次标签
  geom_text(data = ~.x %>% 
              group_by(Clonotype) %>% 
              summarise(total = sum(Value),
                        Freq = round(sum(Value[Cells == 'Number_Hit_Cells'])/total,4)*100),
            aes(x = Clonotype, y = total, label = paste0(Freq,'%')), 
            vjust = -0.3, inherit.aes = FALSE) +
  theme_light()

pdf(file='test.pdf', height=6, width=6)
print(P)
dev.off()

如果不想改动原有数据预处理逻辑,也可以仅修改geom_text一行代码快速实现需求:

ggplot2::geom_text(ggplot2::aes(label=paste0(Freq,'%'), y=Clonotype_Size), vjust=-1, check_overlap = TRUE)

指定标签y轴位置为堆叠柱总高度Clonotype_Size,通过check_overlap = TRUE自动过滤重复标签即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 06:45:03