如何将ggplot2中geom_smooth拟合线按Y=0截线分色(红上绿下)
实现loess拟合线分色显示的方法
要实现loess拟合线在Y=0上方红、下方绿的效果,不能直接用geom_smooth()的默认参数,得先手动计算拟合值,再拆分数据分别绘制。具体步骤如下:
1. 准备示例数据(可替换成你的真实数据)
先模拟一个和你结构一致的数据集,方便测试:
set.seed(123) # 固定随机种子,结果可复现 df <- data.frame( SL = 1:100, log = rnorm(100, mean = 0, sd = 1) + seq(-2, 2, length.out = 100) )
2. 计算loess拟合的预测值
用loess()函数拟合模型,然后生成包含SL、拟合值的数据集,同时根据拟合值是否大于0标记分组:
# 拟合loess模型 loess_model <- loess(log ~ SL, data = df) # 生成预测数据,按SL排序避免线条错乱 pred_df <- data.frame(SL = df$SL) pred_df$fit <- predict(loess_model, newdata = pred_df) # 添加分组列:区分拟合值在Y=0上下的部分 pred_df$color_group <- ifelse(pred_df$fit > 0, "above_zero", "below_zero")
3. 用ggplot绘制图形
先画散点图和Y=0的水平线,再用geom_line()绘制拆分后的拟合线:
library(ggplot2) ggplot(df, aes(x = SL, y = log)) + geom_point(alpha = 0.5) + # 散点图,alpha设小点避免重叠 geom_hline(yintercept = 0, linetype = "dashed", color = "gray50") + # Y=0截距线 geom_line(data = pred_df, aes(y = fit, color = color_group), linewidth = 1) + # 分色拟合线 scale_color_manual( values = c("above_zero" = "red", "below_zero" = "green"), guide = "none" # 不需要显示图例的话加这行 ) + labs(x = "序号(SL)", y = "表达值(log)") + theme_minimal()
关键说明
- 手动计算拟合值是核心:
geom_smooth()内部也是用loess拟合,但不会返回拆分后的拟合数据,所以必须手动生成预测集。 - 一定要按
SL排序:如果预测数据的SL顺序乱了,绘制的线条会出现交叉,所以确保pred_df的SL和原数据一致。 - 若需要保留
geom_smooth()的置信区间:可以先画默认的置信区间(用geom_smooth(se=TRUE, color=NA)),再叠加分色的拟合线,这样置信区间不受颜色影响。
内容的提问来源于stack exchange,提问作者Jishan
相关产品推荐
相关产品推荐

