使用stat_smooth时按组指定特定线型的方法
问题
我有两组时间序列数据,想用stat_smooth绘制线性拟合回归线,要求一组为实线,另一组为虚线。尝试了几种方法,但要么线型分配给了错误的组,要么出现多余的图例,求正确实现方式。
测试代码如下:
library(tidyverse) # 示例时间序列数据 set.seed(222) df <- data.frame( date = rep(seq(as.Date('2024-04-01'), as.Date('2024-04-05'), '1 day'), times = 2), group = c('a','a','a','a','a', 'z','z','z','z','z'), value = rnorm(10, 1, 2) ) # 图1:两组拟合线线型相同 df %>% ggplot(aes(x = date, y = value, group = group)) + geom_line(aes(col = group)) + geom_point(aes(col = group), shape = 16) + stat_smooth(method = 'lm', se = F, color = 'black') + theme_bw() #> `geom_smooth()` using formula = 'y ~ x'
# 图2:线型改变但分配给了错误的组 df %>% ggplot(aes(x = date, y = value, group = group, linetype = group)) + geom_line(aes(col = group), linetype = 'solid') + geom_point(aes(col = group), shape = 16) + stat_smooth(method = 'lm', se = F, color = 'black') + theme_bw() #> `geom_smooth()` using formula = 'y ~ x'
# 图3:线型分配正确但出现第二个图例 df %>% ggplot(aes(x = date, y = value, group = group, linetype = fct_rev(group))) + # 用rev()也会出现同样问题 geom_line(aes(col = group), linetype = 'solid') + geom_point(aes(col = group), shape = 16) + stat_smooth(method = 'lm', se = F, color = 'black') + theme_bw() #> `geom_smooth()` using formula = 'y ~ x'
解决方案
方法1:精准控制拟合线的线型
只给stat_smooth单独映射linetype,手动指定每组对应的线型,同时让原始折线保持实线,避免生成多余图例:
df %>% ggplot(aes(x = date, y = value, group = group)) + geom_line(aes(col = group), linetype = "solid") + # 原始折线固定为实线 geom_point(aes(col = group), shape = 16) + stat_smooth(aes(linetype = group), method = "lm", se = F, color = "black") + # 给拟合线映射线型 scale_linetype_manual(values = c("a" = "solid", "z" = "dashed")) + # 按需设置每组拟合线的线型 theme_bw()
方法2:合并颜色与线型图例
如果希望把颜色和线型的图例合并成一个(让图例同时显示颜色和对应拟合线的线型),可以在全局aes里同时映射col和linetype到group,然后覆盖原始折线的线型为实线,最后统一图例样式:
df %>% ggplot(aes(x = date, y = value, group = group, col = group, linetype = group)) + geom_line(linetype = "solid") + # 覆盖全局线型,让原始折线都是实线 geom_point(shape = 16) + stat_smooth(method = "lm", se = F, color = "black") + scale_linetype_manual(values = c("a" = "solid", "z" = "dashed")) + # 手动设置图例的样式,匹配颜色和线型 guides(linetype = guide_legend(override.aes = list( linetype = c("solid", "dashed"), color = scales::hue_pal()(2) # 自动匹配ggplot默认的颜色 ))) + theme_bw()
之前方法的问题分析
- 图1:没有给
stat_smooth映射linetype,两组拟合线默认都是实线。 - 图2:全局
aes里映射了linetype,但geom_line手动设置linetype='solid'覆盖了这个映射,导致stat_smooth的线型对应关系混乱。 - 图3:用
fct_rev(group)反转了线型映射,但全局aes的linetype会生成独立图例,而geom_line的实线设置未关联该图例,因此出现两个图例。
内容的提问来源于stack exchange,提问作者tassones
相关产品推荐
相关产品推荐

