如何在R的ggplot2中为折线匹配对应颜色并添加末端标签
R语言ggplot2绘图需求解决
数据背景
我有一个名为df_的data frame,数据结构如下:
df_ # A tibble: 40 × 4 # Groups: Year [5] Year Country mu Color <int> <fct> <dbl> <fct> 1 2019 ALPHA 68.9 red 2 2019 BETA 64.8 black 3 2019 GAMMA 70.0 yellow 4 2019 RHO 65.2 gray 5 2019 DELTA 70.1 green 6 2019 EPSILON 69.6 pink 7 2019 THETA 69.8 purple 8 2019 OMEGA 67.9 orange 9 2020 ALPHA 69.3 red 10 2020 BETA 65.2 black # ℹ 30 more rows
数据结构的完整structure:
structure(list(Year = c(2019L, 2019L, 2019L, 2019L, 2019L, 2019L, 2019L, 2019L, 2020L, 2020L, 2020L, 2020L, 2020L, 2020L, 2020L, 2020L, 2022L, 2022L, 2022L, 2022L, 2022L, 2022L, 2022L, 2022L, 2023L, 2023L, 2023L, 2023L, 2023L, 2023L, 2023L, 2023L, 2024L, 2024L, 2024L, 2024L, 2024L, 2024L, 2024L, 2024L), Country = structure(c(1L, 2L, 5L, 7L, 3L, 4L, 8L, 6L, 1L, 2L, 5L, 7L, 3L, 4L, 8L, 6L, 1L, 2L, 5L, 7L, 3L, 4L, 8L, 6L, 1L, 2L, 5L, 7L, 3L, 4L, 8L, 6L, 1L, 2L, 5L, 7L, 3L, 4L, 8L, 6L), levels = c("ALPHA", "BETA", "DELTA", "EPSILON", "GAMMA", "OMEGA", "RHO", "THETA"), class = "factor"), mu = c(68.855, 64.77, 69.9875, 65.22, 70.1266666666667, 69.6166666666667, 69.8085714285714, 67.9093333333333, 69.2675, 65.2, 72.4075, 69.49, 72.28, 69.262, 70.07125, 65.3864285714286, 74.6584615384615, 67.77, 75.3533333333333, 73, 64.09, 73.1715384615385, 66.058, 72.12, 75.5645833333333, 70.46, 78.2933333333333, 79.07, 59.82, 79.6361538461538, 74.225, 69.5871428571429, 76.4007407407407, 67.91, 76.805, 77.31, 74.0966666666667, 81.2811764705882, 74.6671428571428, 78.0316666666667), Color = structure(c(7L, 1L, 8L, 2L, 3L, 5L, 6L, 4L, 7L, 1L, 8L, 2L, 3L, 5L, 6L, 4L, 7L, 1L, 8L, 2L, 3L, 5L, 6L, 4L, 7L, 1L, 8L, 2L, 3L, 5L, 6L, 4L, 7L, 1L, 8L, 2L, 3L, 5L, 6L, 4L), levels = c("black", "gray", "green", "orange", "pink", "purple", "red", "yellow" ), class = "factor")), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, -40L), groups = structure(list( Year = c(2019L, 2020L, 2022L, 2023L, 2024L), .rows = structure(list( 1:8, 9:16, 17:24, 25:32, 33:40), ptype = integer(0), class = c("vctrs_list_of", "vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame" ), row.names = c(NA, -5L), .drop = TRUE))
需求
- a) 为每个国家对应的折线应用其
Color列指定的颜色; - b) 在每条折线的末端(2024年的数据点处)显示
Country名称和对应mu值,格式如“ALPHA ,76.4”。
现有代码
基础绘图代码:
ggplot(df_, aes(x = Year, y = mu, color = Color, group = Country)) + geom_line(size = 1.5) + geom_point() + labs(x = "Years", y = "") + theme_minimal() + theme(legend.position = "none")
尝试添加标签的代码:
先给数据框新增列:
mutate(label = if_else(Year == max(Year), as.character(Country), NA_character_))
再在绘图代码中添加:
theme(legend.position = "none") + geom_label_repel(aes(label = label), nudge_x = 1, na.rm = TRUE)
但这样只能显示国家名称,无法同时显示对应mu值。
解决方案
1. 修正标签列的生成逻辑
原数据是按Year分组的,直接用max(Year)会取每组的最大值,所以必须先取消分组,再将Country和格式化后的mu值拼接成目标格式:
df_ <- df_ %>% ungroup() %>% mutate(label = if_else(Year == max(Year), paste0(as.character(Country), ", ", round(mu, 1)), NA_character_))
如果需要保留更多小数位数,调整round()的第二个参数即可。
2. 完整绘图代码
将修正后的标签应用到绘图中,确保折线颜色和标签显示符合需求:
library(ggplot2) library(dplyr) library(ggrepel) # 预处理数据生成标签 df_ <- df_ %>% ungroup() %>% mutate(label = if_else(Year == max(Year), paste0(Country, ", ", round(mu, 1)), NA_character_)) # 绘图 ggplot(df_, aes(x = Year, y = mu, color = Color, group = Country)) + geom_line(size = 1.5) + geom_point() + # 添加带排斥效果的标签,避免重叠 geom_label_repel(aes(label = label), nudge_x = 1, na.rm = TRUE, fill = "white", size = 3) + labs(x = "Years", y = "") + theme_minimal() + theme(legend.position = "none")
关键说明
- 取消分组:
ungroup()确保max(Year)获取的是全局最大年份2024,而非每组的最大值; - 标签格式化:
round(mu,1)将数值保留1位小数,匹配示例中的显示格式;paste0()完成字符串拼接; - 标签样式:
fill="white"让标签背景为白色,增强可读性;nudge_x=1将标签向右偏移,避免和折线末端点重叠。
内容的提问来源于stack exchange,提问作者Homer Jay Simpson
相关产品推荐
相关产品推荐

