如何通过模型函数在lattice图中添加双曲线/指数曲线
在Lattice的xyplot中绘制双曲线/指数模型曲线
核心说明
panel.abline()只能用来画线性模型的直线拟合结果,比如简单的一次线性回归lm(dist ~ speed),对于双曲线、指数这类非线性曲线,得换用panel.lines结合预测值,或者panel.curve代入拟合好的模型参数来实现,下面分两种模型具体说明:
一、双曲线模型(以倒数线性模型为例)
常见的双曲线形式是 dist = a + b*(1/speed),这个模型可以用线性回归直接拟合:
- 先拟合模型
# 拟合倒数形式的双曲线模型 hyper_model <- lm(dist ~ I(1/speed), data = cars)
- 两种绘制曲线的方式:
方式1:用predict生成拟合值,再画曲线
library(lattice) xyplot(dist ~ speed, data = cars, panel = function(x, y, ...) { panel.xyplot(x, y, ...) # 先画原始散点 # 生成覆盖speed范围的预测数据 pred_df <- data.frame(speed = seq(min(x), max(x), length.out = 100)) # 计算拟合值 pred_df$dist_pred <- predict(hyper_model, newdata = pred_df) # 绘制拟合曲线 panel.lines(pred_df$speed, pred_df$dist_pred, col = "red", lwd = 2) })
方式2:提取模型系数,用panel.curve直接画函数
coefs <- coef(hyper_model) xyplot(dist ~ speed, data = cars, panel = function(x, y, ...) { panel.xyplot(x, y, ...) # 代入拟合好的系数,直接绘制双曲线函数 panel.curve(coefs[1] + coefs[2]*(1/x), from = min(x), to = max(x), col = "red", lwd = 2) })
二、指数模型
指数模型常用形式是 dist = exp(a + b*speed),可以通过对dist取对数转换成线性模型拟合:
- 拟合模型
# 拟合对数线性模型,等价于指数模型 exp_model <- lm(log(dist) ~ speed, data = cars)
- 绘制曲线的两种方式:
方式1:predict生成拟合值(记得反转换)
xyplot(dist ~ speed, data = cars, panel = function(x, y, ...) { panel.xyplot(x, y, ...) pred_df <- data.frame(speed = seq(min(x), max(x), length.out = 100)) # 先预测对数后的值,再指数转换还原 pred_df$dist_pred <- exp(predict(exp_model, newdata = pred_df)) panel.lines(pred_df$speed, pred_df$dist_pred, col = "blue", lwd = 2) })
方式2:提取系数用panel.curve绘制
exp_coefs <- coef(exp_model) xyplot(dist ~ speed, data = cars, panel = function(x, y, ...) { panel.xyplot(x, y, ...) # 代入系数绘制指数函数曲线 panel.curve(exp(exp_coefs[1] + exp_coefs[2]*x), from = min(x), to = max(x), col = "blue", lwd = 2) })
进阶:非线性模型的曲线绘制
如果要用更复杂的非线性双曲线(比如dist ~ a/(speed + b)),可以用nls拟合,再用同样的预测方式绘制:
# 用nls拟合非线性双曲线模型 nls_hyper <- nls(dist ~ a/(speed + b), data = cars, start = list(a=100, b=1)) xyplot(dist ~ speed, data = cars, panel = function(x, y, ...) { panel.xyplot(x, y, ...) pred_df <- data.frame(speed = seq(min(x), max(x), length.out = 100)) pred_df$dist_pred <- predict(nls_hyper, newdata = pred_df) panel.lines(pred_df$speed, pred_df$dist_pred, col = "green", lwd = 2) })
内容的提问来源于stack exchange,提问作者12666727b9
相关产品推荐
相关产品推荐

