ggplot2中如何实现折线按条件染色且不跳过中间不满足条件的点?
你当前的代码出现跨点连线的问题,是ggplot2默认分组逻辑导致的:geom_line()会把color映射对应的同一分组的所有点直接连接,不会考虑中间其他分组的点,因此所有判定为con_val>0的点会跳过中间不符合条件的点直接相连。
下面是两种可直接运行的解决方案:
方案1:使用ggforce包的geom_link2(最简实现)
该函数支持根据每个点的属性给相邻线段赋值颜色,仅需少量修改即可实现需求:
library(tidyverse) library(ggforce) df_plot <- tibble( id = rep(1, times = 10), time = seq(from = 0, to = 25, length.out = 10), y_val = c(seq(from = 50, to = 25, length.out = 5), seq(from = 25, to = 50, length.out = 5)), con_val = c(NA, NA, 1, NA, NA, NA, 5, NA, NA, 2)) %>% # 先明确条件列,把NA统一归为不满足条件 mutate(cond = ifelse(is.na(con_val) | con_val <= 0, FALSE, TRUE)) ggplot(data = df_plot, aes(x = time, y = y_val, color = cond)) + geom_point() + # 用geom_link2代替geom_line,group=1保证所有点按顺序连接 geom_link2(aes(group = 1)) + scale_colour_manual(values = setNames(c('red','gray'), c(TRUE, FALSE)))
方案2:原生ggplot2实现(无需额外安装包)
如果不想安装第三方包,可以先预处理数据,给每一段相邻线段分配颜色后用geom_segment绘制:
library(tidyverse) df_plot <- tibble( id = rep(1, times = 10), time = seq(from = 0, to = 25, length.out = 10), y_val = c(seq(from = 50, to = 25, length.out = 5), seq(from = 25, to = 50, length.out = 5)), con_val = c(NA, NA, 1, NA, NA, NA, 5, NA, NA, 2)) %>% mutate( cond = ifelse(is.na(con_val) | con_val <= 0, FALSE, TRUE), # 给相邻线段分配颜色:当前点和下一点都满足条件则为红色,否则为灰色 seg_cond = ifelse(cond & lead(cond, default = last(cond)), TRUE, FALSE) ) ggplot(data = df_plot, aes(x = time, y = y_val)) + geom_point(aes(color = cond)) + # 逐段绘制线段 geom_segment(aes(xend = lead(time), yend = lead(y_val), color = seg_cond)) + scale_colour_manual(values = setNames(c('red','gray'), c(TRUE, FALSE)))
如果需要线段颜色无过渡、严格按分界显示,优先选择方案2即可。
内容的提问来源于stack exchange,提问作者jsgraydon
相关产品推荐
相关产品推荐

