You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ggplot2中绘制含多项式函数的双Y轴折线图?

在R中实现双Y轴图表并添加多项式拟合曲线

示例实现(ggplot2版本)

下面是可直接运行的完整示例,用模拟数据演示双Y轴+多项式拟合的效果,你可以直接替换成自己的数据:

library(ggplot2)

# 模拟示例数据
set.seed(123)
df <- data.frame(
  x = 1:20,
  y1 = 3 + 2*x + rnorm(20, 0, 3),  # 第一个Y轴数据(线性趋势)
  y2 = 10 - 1.5*x + 0.2*x^2 + rnorm(20, 0, 2)  # 第二个Y轴数据(二次趋势)
)

# 拟合y2的二次多项式模型
poly_model <- lm(y2 ~ poly(x, 2, raw = TRUE), data = df)
# 生成拟合预测值
df$y2_fit <- predict(poly_model, newdata = df)

# 计算双Y轴的转换比例(让两个轴的范围适配)
y1_range <- range(df$y1)
y2_range <- range(df$y2)
scale_factor <- diff(y1_range)/diff(y2_range)
shift <- y1_range[1] - y2_range[1]*scale_factor

# 绘制双Y轴图表
ggplot(df, aes(x = x)) +
  # 第一个Y轴:散点+拟合线
  geom_point(aes(y = y1), color = "#2E86AB", size = 2) +
  geom_smooth(aes(y = y1), method = "lm", se = FALSE, color = "#2E86AB", linetype = "dashed") +
  # 第二个Y轴:散点+多项式拟合线
  geom_point(aes(y = y2*scale_factor + shift), color = "#F24C4E", size = 2) +
  geom_line(aes(y = y2_fit*scale_factor + shift), color = "#F24C4E", size = 1.2) +
  # 设置双Y轴
  scale_y_continuous(
    name = "第一个Y轴标签",
    sec.axis = sec_axis(~ (. - shift)/scale_factor, name = "第二个Y轴标签")
  ) +
  labs(x = "X轴标签", title = "双Y轴+多项式拟合示例") +
  theme_minimal() +
  theme(
    axis.title.y = element_text(color = "#2E86AB"),
    axis.title.y.right = element_text(color = "#F24C4E")
  )

关键步骤说明

  • 多项式拟合:用lm(y ~ poly(x, n, raw=TRUE))拟合n阶多项式,raw=TRUE保证使用原始多项式项(而非正交多项式),便于理解系数含义。
  • 双Y轴刻度转换:ggplot2不支持直接独立的双Y轴,需通过缩放第二个Y轴的数据适配第一个Y轴范围,再用sec_axis反向转换显示正确刻度。
  • 样式区分:用不同颜色、符号区分两个Y轴的元素,避免混淆。

Base R实现方案

如果习惯用Base R绘图,可参考以下代码:

# 模拟数据同上
set.seed(123)
df <- data.frame(
  x = 1:20,
  y1 = 3 + 2*x + rnorm(20, 0, 3),
  y2 = 10 - 1.5*x + 0.2*x^2 + rnorm(20, 0, 2)
)

# 拟合多项式模型
poly_model <- lm(y2 ~ poly(x, 2, raw=TRUE), data=df)
x_seq <- seq(min(df$x), max(df$x), length.out=100)
y2_fit <- predict(poly_model, newdata=data.frame(x=x_seq))

# 创建双Y轴绘图
par(mar = c(5,4,4,4) + 0.1)  # 调整右侧边距

# 绘制第一个Y轴
plot(df$x, df$y1, pch=16, col="#2E86AB", xlab="X轴标签", ylab="第一个Y轴标签", main="双Y轴+多项式拟合")
abline(lm(y1~x, data=df), col="#2E86AB", lty=2)

# 添加第二个Y轴
par(new=TRUE)
plot(df$x, df$y2, pch=17, col="#F24C4E", axes=FALSE, xlab="", ylab="")
lines(x_seq, y2_fit, col="#F24C4E", lwd=2)
axis(side=4)
mtext("第二个Y轴标签", side=4, line=3, col="#F24C4E")
legend("topleft", legend=c("Y1数据", "Y1拟合", "Y2数据", "Y2多项式拟合"), 
       col=c("#2E86AB","#2E86AB","#F24C4E","#F24C4E"), pch=c(16,NA,17,NA), lty=c(NA,2,NA,1))

注意事项

  • 双Y轴易造成数据误解,非必要场景建议避免使用;若必须使用,务必用清晰的视觉元素区分两个数据系列。
  • 如果你有自己的代码片段,可以贴出来,我会帮你针对性修改。

内容的提问来源于stack exchange,提问作者Cesar Barrientos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 16:30:58