ggplot2中如何连接单条黑线组与多条彩色线组并避免路径闭合?
解决ggplot路径闭合问题
想要制作类似PPT原型的图表,目前尝试的代码生成了三种不理想的结果(图A、B、C),其中图C最接近目标,但彩色路径出现不必要的闭合,以下是修正方案:
原问题代码
data <- examp = tribble(~scenario, ~years, ~value, ~dummy, 'Normals',' 1961-1990', 0.0000000, 'Normal', 'Normals',' 1961-1990', 0.0000000, 'Normal', 'Normals',' 1991-2020', 0.1965065, 'Normal', 'SSP126 ','2011-2040 ', 0.1366428 , 'Normal', 'SSP126 ','2041-2070 ', 0.1727662 , 'Normal', 'SSP126 ','2071-2100 ', 0.1866775 , 'Normal', 'SSP245 ','2011-2040 ', 0.1334094 , 'Normal', 'SSP245 ','2041-2070 ', 0.1865576 , 'Normal', 'SSP245 ','2071-2100 ', 0.2203371 , 'Normal', 'SSP370 ','2011-2040 ', 0.1315721 , 'Normal', 'SSP370 ','2041-2070 ', 0.2000836 , 'Normal', 'SSP370 ','2071-2100 ', 0.2675299 , 'Normal', 'SSP585 ','2011-2040 ', 0.1351562 , 'Normal', 'SSP585 ','2041-2070 ', 0.2060075 , 'Normal', 'SSP585 ','2071-2100 ', 0.3025003 , 'Normal') data %>% arrange(years) %>% mutate(scenario = fct_reorder(scenario, value)) %>% ggplot(aes(x = years, y = value)) + geom_path(aes(group = scenario, colour = scenario), linewidth = 1) + scale_colour_manual(name = "Climate scenario", values = col, breaks = c("Normals", "Normals", "SSP126", "SSP245", "SSP370", "SSP585"), labels = c("Normals", "", "SSP126", "SSP245", "SSP370", "SSP585")) + scale_x_discrete(name = "Years", breaks = c("1961-1990", "1991-2020", "2011-2040", "2041-2070", "2071-2100"), labels = c("1961-1990", "1991-2020", "2011-2040", "2041-2070", "2071-2100")) + theme(axis.text.x = element_text(angle = 35, hjust = 1))
问题根源
- 数据存在重复行(Normals的1961-1990条目重复),导致路径连接异常
- 年份和scenario字符串前后带有空格,干扰排序逻辑
arrange(years)会跨scenario打乱数据顺序,加上fct_reorder进一步干扰分组后的点顺序,导致geom_path错误连接不同年份的点形成闭合
修正后的代码
library(tidyverse) # 清理并整理数据 data <- tribble( ~scenario, ~years, ~value, ~dummy, 'Normals',' 1961-1990', 0.0000000, 'Normal', 'Normals',' 1961-1990', 0.0000000, 'Normal', 'Normals',' 1991-2020', 0.1965065, 'Normal', 'SSP126 ','2011-2040 ', 0.1366428 , 'Normal', 'SSP126 ','2041-2070 ', 0.1727662 , 'Normal', 'SSP126 ','2071-2100 ', 0.1866775 , 'Normal', 'SSP245 ','2011-2040 ', 0.1334094 , 'Normal', 'SSP245 ','2041-2070 ', 0.1865576 , 'Normal', 'SSP245 ','2071-2100 ', 0.2203371 , 'Normal', 'SSP370 ','2011-2040 ', 0.1315721 , 'Normal', 'SSP370 ','2041-2070 ', 0.2000836 , 'Normal', 'SSP370 ','2071-2100 ', 0.2675299 , 'Normal', 'SSP585 ','2011-2040 ', 0.1351562 , 'Normal', 'SSP585 ','2041-2070 ', 0.2060075 , 'Normal', 'SSP585 ','2071-2100 ', 0.3025003 , 'Normal' ) %>% # 去除字符串前后空格 mutate(across(c(scenario, years), str_trim)) %>% # 移除重复行 distinct() %>% # 按场景+年份排序,确保每个场景内的点按时间顺序排列 arrange(scenario, years) # 定义颜色向量(可根据需求调整) col <- c("Normals" = "black", "SSP126" = "#1f77b4", "SSP245" = "#2ca02c", "SSP370" = "#ff7f0e", "SSP585" = "#d62728") # 绘制图表 data %>% ggplot(aes(x = years, y = value)) + geom_path(aes(group = scenario, colour = scenario), linewidth = 1) + scale_colour_manual( name = "Climate scenario", values = col, breaks = c("Normals", "SSP126", "SSP245", "SSP370", "SSP585"), labels = c("Normals", "SSP126", "SSP245", "SSP370", "SSP585") ) + scale_x_discrete( name = "Years", # 手动指定x轴年份顺序,确保时间逻辑正确 limits = c("1961-1990", "1991-2020", "2011-2040", "2041-2070", "2071-2100") ) + theme(axis.text.x = element_text(angle = 35, hjust = 1))
关键修改点
- 清理字符串空格:避免因空格导致的排序、分组识别错误
- 移除重复数据:消除异常连接的诱因
- 合理排序:按scenario+年份排序,确保每个场景内的点按时间顺序排列,geom_path只会连接同场景内的连续点,不会跨场景形成闭合
- 修正图例配置:移除重复的Normals条目,让图例显示更清晰
内容的提问来源于stack exchange,提问作者Tal
相关产品推荐
相关产品推荐

