ggplot2同时使用geom_vline与geom_hline如何实现独立分开图例
问题原因
geom_hline未显示:你在scale_linetype_manual中只定义了os 1、os 2两个取值的映射,geom_hline中映射的dashed取值没有被包含在内,导致该图层的linetype映射失效,图层无法正常渲染。- 图例合并为十字:所有横线、竖线都绑定到了同一个
linetype美学通道,ggplot2默认会将同一美学的不同图层映射合并到同一个图例中,因此出现竖线和横线叠加成十字的情况。
解决方案
使用ggnewscale包新增独立的linetype美学通道,分别给竖线、横线分配不同的linetype scale,二者图例就会分开,同时补全所有linetype取值的映射即可解决图层不显示问题。
修改后可直接运行的代码如下:
library(tidyverse) library(lubridate) # 加载ggnewscale用来新增独立美学通道 library(ggnewscale) y <- rnorm(100) df <- tibble(y) %>% mutate(os = factor(rep_len(1:5, 100)), date = seq(from = ymd('2013-01-01'), by = 1, length.out = 100)) ggplot(df, aes(x = date, y = y, colour = os)) + geom_line() + # 先处理竖线的linetype映射和scale geom_vline( aes(xintercept = min(date), linetype = 'os 1'), colour = 'red') + geom_vline( aes(xintercept = median(date), linetype = 'os 2'), colour = 'blue') + scale_linetype_manual( name = '竖线标识', values = c('os 1' = 1, 'os 2' = 1), guide = guide_legend(override.aes = list(colour = c('red', 'blue')))) + # 新增独立的linetype scale,后续的linetype映射会绑定到新通道 new_scale("linetype") + # 处理横线的linetype映射和scale geom_hline( aes(yintercept = 1, linetype = "阈值线"), colour = "black" ) + scale_linetype_manual( name = "横线标识", values = c("阈值线" = "dashed") )
核心修改点
- 引入
ggnewscale包的new_scale("linetype")函数,将竖线和横线的linetype映射拆分到两个独立的美学通道,二者会生成独立的图例,不会合并 - 补全了横线linetype取值的映射定义,确保图层可以正常渲染
- 两个图例分别命名区分,标识形状会自动匹配对应图层的线类型(竖线图例为竖线,横线图例为横线)
内容的提问来源于stack exchange,提问作者Bear Bile Farming is Torture
相关产品推荐
相关产品推荐

