如何在R的ggplot中按条件为折线着色并添加id标签
在ggplot中标记折线下降段并添加ID标签
完全可以实现这个需求,核心思路是先预处理数据找出所有Ratio下降的区间,再单独绘制这些红色线段,最后在对应位置添加ID标签。以下是完整实现代码和说明:
1. 数据预处理
首先需要从原始数据中筛选出Ratio下降的线段区间,并生成标签的位置数据:
library(tidyverse) # 原始数据 m=" id Year Ratio A yr2019 .5 A yr2020 .3 A yr2021 .4 B yr2019 .2 B yr2020 .2 B yr2021 .1 C yr2019 .6 C yr2020 .7 C yr2021 .9" data <- read.table(text= m, h= TRUE) # 生成下降线段的绘图数据 drop_segments <- data %>% group_by(id) %>% arrange(Year) %>% # 获取下一年的Ratio和Year,判断是否下降 mutate( next_Ratio = lead(Ratio), next_Year = lead(Year), is_drop = Ratio > next_Ratio ) %>% filter(is_drop) %>% # 重构数据格式,让每段下降线包含两个端点 pivot_longer(cols = c(Year, next_Year), names_to = "tmp", values_to = "Year") %>% pivot_longer(cols = c(Ratio, next_Ratio), names_to = "tmp2", values_to = "Ratio") %>% arrange(id, Year) %>% select(id, Year, Ratio) # 生成标签位置数据(取下降段中点并上移一点) label_data <- data %>% group_by(id) %>% arrange(Year) %>% mutate( next_Ratio = lead(Ratio), is_drop = Ratio > next_Ratio ) %>% filter(is_drop) %>% mutate( # 定义年份中点的刻度值 Year_mid = factor( case_when( Year == "yr2019" ~ "yr2019-2020", Year == "yr2020" ~ "yr2020-2021" ), levels = c("yr2019", "yr2019-2020", "yr2020", "yr2020-2021", "yr2021") ), Ratio_mid = (Ratio + next_Ratio)/2 + 0.05 # 标签位置高于线段,避免重叠 )
2. 绘制图形
先绘制基础灰色折线,再叠加红色下降线段和对应ID标签:
ggplot() + # 绘制所有id的基础折线(灰色) geom_line(data = data, aes(Year, Ratio, group = id), color = "gray50", linewidth = 1) + # 绘制下降的红色线段(加粗突出) geom_line(data = drop_segments, aes(Year, Ratio, group = id), color = "red", linewidth = 1.5) + # 添加ID标签 geom_text(data = label_data, aes(Year_mid, Ratio_mid, label = id), color = "red", fontface = "bold") + # 调整x轴刻度顺序,确保中点标签显示正确 scale_x_discrete(limits = c("yr2019", "yr2019-2020", "yr2020", "yr2020-2021", "yr2021")) + labs(x = "年份", y = "Ratio") + theme_minimal()
关键说明
- 使用
lead()函数获取每个id下一年的Ratio值,以此判断是否出现下降 - 通过
pivot_longer()重构数据,让每段下降线的两个端点能被ggplot识别为同一组线段 - 标签位置设置在下降段的中点并轻微上移,避免与线段重叠
- 自定义x轴离散刻度,确保年份中点的标签能正确显示在两个年份之间
内容的提问来源于stack exchange,提问作者Reza
相关产品推荐
相关产品推荐

