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

如何为ggplot绘制的stacked density plot添加曲线标签?

为堆叠密度图添加曲线标签的可行方案

你当前的问题是直接使用geom_text()时,会给原始数据的每个点都打上标签,导致文字严重重叠,根本无法分辨。要实现给靠前3-4条曲线添加names标签,需要先提取每条曲线的关键位置(比如峰值或端点),再针对性添加标签,具体步骤如下:

你的原始代码与结果

初始绘图代码

ggplot(data=tydy_rawdata, aes(x=timepoint, y=tpm, group=fct_inorder(names), 
    fill=fct_inorder(names))) +
         geom_density(position="fill",
                      stat="identity") +
         scale_fill_manual(values = rev(mycolors))

对应的图像:
初始堆叠密度图

错误尝试的代码

ggplot(data=tydy_rawdata, aes(x=timepoint, y=tpm, group=fct_inorder(names), 
    fill=fct_inorder(names))) +
         geom_density(position="fill",
                      stat="identity") +
         geom_text(aes(label=names)) +
         scale_fill_manual(values = rev(mycolors))

得到的重叠图像:
标签重叠的错误结果

解决方案

方法1:在曲线右侧添加标签(推荐)

先预处理数据,提取排名靠前的类别在x轴最右侧的堆叠位置,然后在曲线外侧添加标签:

library(ggplot2)
library(dplyr)
library(forcats)

# 预处理标签数据:筛选前4个高表达类别,计算它们在x轴最右侧的堆叠y位置
label_data <- tydy_rawdata %>%
  # 按timepoint排序,确保取到最大的x值
  arrange(timepoint) %>%
  group_by(names) %>%
  filter(timepoint == max(timepoint)) %>%
  ungroup() %>%
  # 计算堆叠后的相对y位置(对应position="fill"的比例)
  mutate(cum_y = cumsum(tpm)/sum(tpm)) %>%
  # 选取总tpm最高的4个类别
  slice_max(order_by = tpm, n = 4)

# 绘图
ggplot(data=tydy_rawdata, aes(x=timepoint, y=tpm, group=fct_inorder(names), 
    fill=fct_inorder(names))) +
  geom_density(position="fill", stat="identity") +
  # 添加右侧标签,x轴扩展出空间放置标签
  geom_text(data = label_data, 
            aes(x = max(tydy_rawdata$timepoint) + 0.5, y = cum_y, label = names),
            hjust = 0, size = 3.5) +
  scale_fill_manual(values = rev(mycolors)) +
  # 扩展x轴范围,避免标签被截断
  xlim(min(tydy_rawdata$timepoint), max(tydy_rawdata$timepoint) + 2)

方法2:在曲线峰值处添加标签(用ggrepel避免重叠)

如果想在曲线的峰值位置添加标签,可以用ggrepel包自动避免标签重叠:

library(ggplot2)
library(dplyr)
library(forcats)
library(ggrepel)

# 预处理标签数据:提取每个类别曲线的峰值点,筛选前4个
peak_data <- tydy_rawdata %>%
  group_by(names) %>%
  filter(tpm == max(tpm)) %>%
  ungroup() %>%
  slice_max(order_by = tpm, n = 4)

# 绘图
ggplot(data=tydy_rawdata, aes(x=timepoint, y=tpm, group=fct_inorder(names), 
    fill=fct_inorder(names))) +
  geom_density(position="fill", stat="identity") +
  # 使用geom_text_repel自动调整标签位置,避免重叠
  geom_text_repel(data = peak_data, aes(label = names),
                  box.padding = 0.5, point.padding = 0.3, size = 3.5) +
  scale_fill_manual(values = rev(mycolors))

核心逻辑说明

直接使用geom_text()会遍历原始数据的每一行添加标签,导致同一条曲线出现成百上千个重叠的文字。通过预处理数据,我们只保留每个目标类别一个关键位置的标签,既清晰又不会干扰图表可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 01:13:59