ggplot2使用geom_line按Signal着色时,如何移除分段间的连接直线?
解决方法
你遇到的问题是因为geom_line默认会按x轴顺序连接所有点,哪怕相邻点属于不同的Signal分组,所以才会出现跨分组的连接线。要解决这个问题,只需要让ggplot只连接同一连续Signal段内的点,具体做法如下:
方法一:添加分组列后绘图
先给数据框添加一个分组ID,标记每一段连续相同的Signal区块:
df$skew <- Skew df$kurtosis <- Kurtosis df <- df %>% mutate(Signal = if_else(skew >= 1, 'Yes', 'No'), # 每当Signal变化时,分组号自动递增 group_id = cumsum(Signal != lag(Signal, default = first(Signal)))) # 绘图时指定group参数 pPrice <- ggplot() + ggtitle(df$symbol) + geom_line(data = df, aes(x = date, y = adjusted, color = Signal, group = group_id)) + xlab('') + ylab('Price') + theme_bw()
方法二:直接在绘图时计算分组(无需额外列)
如果不想新增列,可以直接在aes里计算分组逻辑:
df$skew <- Skew df$kurtosis <- Kurtosis df <- df %>% mutate(Signal = if_else(skew >= 1, 'Yes', 'No')) #plot pPrice <- ggplot() + ggtitle(df$symbol) + geom_line(data = df, aes(x = date, y = adjusted, color = Signal, # 动态生成连续Signal段的分组ID group = cumsum(Signal != lag(Signal, default = first(Signal))))) + xlab('') + ylab('Price') + theme_bw()
原理说明
cumsum(Signal != lag(Signal, default = first(Signal)))这个逻辑会为每一段连续相同的Signal生成唯一的分组ID:
lag(Signal, default = first(Signal))用来获取当前行的上一行Signal值,第一行没有上一行就用自身的Signal值- 当当前行Signal和上一行不同时,
Signal != lag(...)返回TRUE(即1),cumsum会累加这个值,生成新的分组号 geom_line只会连接同一group内的点,不同分组的点之间不会产生连接线,完美解决你的问题
内容的提问来源于stack exchange,提问作者MadDog
相关产品推荐
相关产品推荐

