解决ggplot按年份分组设颜色时多条折线合并为单条的问题
问题描述
我想要制作一幅数据按十年区间(如2000-2009、2010-2019、2020+)分组,且同组折线共用统一颜色的图表。单独为各年份设置颜色时一切正常,但尝试按年份组设置颜色时,代表各具体年份的折线会被合并成单条。我希望无需逐个指定年份,让2020年及以后的所有年份折线都像第一张图那样独立显示且全部为红色,如何避免折线合并的情况?
正常运行的代码(各年份单独设置颜色)
suppressWarnings(library(tidyverse)) set.seed(333) start_date <- as.Date('1990-01-01') end_date <- as.Date('2023-12-31') total_days <- as.numeric((end_date-start_date)+1) # 创建数据框 dat <- data.frame( Date = seq(start_date, end_date,'1 day'), Value = rnorm(total_days, 20, 4) ) # 为数据框添加年份和年积日(DoY) dat <- dat %>% mutate(Year = year(Date), DoY = yday(Date)) # 各年份单独设置颜色的正常代码 dat %>% ggplot(aes(x = DoY, y = Value, col = factor(Year))) + geom_line(data = subset(dat, Year == 2020), aes(colour = "2020")) + geom_line(data = subset(dat, Year == 2021), aes(colour = "2021")) + geom_line(data = subset(dat, Year == 2022), aes(colour = "2022")) + geom_line(data = subset(dat, Year == 2023), aes(colour = "2023")) + labs(x = '年积日', y = '数值', colour = '年份区间') + scale_x_continuous(breaks = seq(1, 10, 1), limits = c(1,10)) + scale_color_manual(values = c("2020" = "#225ea8", "2021" = "#41b6c4", "2022" = "#a1dab4", "2023" = "red")) + theme_bw()

存在问题的代码(年份组设置颜色导致折线合并)
# 问题代码:为何>=2020的年份折线被合并为单条? # 期望>=2020的年份折线像上图一样独立显示且为红色 dat %>% ggplot(aes(x = DoY, y = Value, col = factor(Year))) + # geom_line() + # geom_line(data = subset(dat, Year >= 1990 & Year <= 1999), aes(colour = "1990-1999")) + # geom_line(data = subset(dat, Year >= 2000 & Year <= 2009), aes(colour = "2000-2009")) + # geom_line(data = subset(dat, Year >= 2010 & Year <= 2019), aes(colour = "2010-2019")) + geom_line(data = subset(dat, Year >= 2020), aes(colour = "2020+")) + labs(x = '年积日', y = '数值', colour = '年份区间') + scale_x_continuous(breaks = seq(1, 10, 1), limits = c(1,10)) + scale_color_manual(values = c("1990-1999" = "#225ea8", "2000-2009" = "#41b6c4", "2010-2019" = "#a1dab4", "2020+" = "red")) + theme_bw()

创建于2024-02-21,使用reprex v2.0.2
解决方案
问题根源是:当你在geom_line里指定aes(colour = "2020+")时,ggplot会把所有符合条件的数据归为同一个分组,最终合并成单条折线。要保留各年份独立折线且统一颜色,有两种简洁方法:
方法1:预处理数据添加年份分组列
先给数据新增一个标记年份区间的列,用该列映射颜色,同时保留Year作为分组依据:
dat <- dat %>% mutate(Year_Group = case_when( Year >= 1990 & Year <= 1999 ~ "1990-1999", Year >= 2000 & Year <= 2009 ~ "2000-2009", Year >= 2010 & Year <= 2019 ~ "2010-2019", Year >= 2020 ~ "2020+" )) # 绘图代码 dat %>% ggplot(aes(x = DoY, y = Value, group = Year, colour = Year_Group)) + geom_line() + labs(x = '年积日', y = '数值', colour = '年份区间') + scale_x_continuous(breaks = seq(1, 10, 1), limits = c(1,10)) + scale_color_manual(values = c("1990-1999" = "#225ea8", "2000-2009" = "#41b6c4", "2010-2019" = "#a1dab4", "2020+" = "red")) + theme_bw()
方法2:在geom_line中显式指定group映射
如果不想修改原始数据,直接在geom_line里指定group = Year,确保每个年份的折线独立:
dat %>% ggplot(aes(x = DoY, y = Value)) + geom_line(data = subset(dat, Year >= 2020), aes(group = Year, colour = "2020+")) + geom_line(data = subset(dat, Year >= 2010 & Year <= 2019), aes(group = Year, colour = "2010-2019")) + geom_line(data = subset(dat, Year >= 2000 & Year <= 2009), aes(group = Year, colour = "2000-2009")) + geom_line(data = subset(dat, Year >= 1990 & Year <= 1999), aes(group = Year, colour = "1990-1999")) + labs(x = '年积日', y = '数值', colour = '年份区间') + scale_x_continuous(breaks = seq(1, 10, 1), limits = c(1,10)) + scale_color_manual(values = c("1990-1999" = "#225ea8", "2000-2009" = "#41b6c4", "2010-2019" = "#a1dab4", "2020+" = "red")) + theme_bw()
两种方法都能实现同组年份折线独立显示、颜色统一的效果,无需逐个指定年份。
内容的提问来源于stack exchange,提问作者tassones
相关产品推荐
相关产品推荐

