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

R语言如何用ts.plot为不同尺度ts对象添加双轴实现叠加绘图

R 基于ts.plot实现双坐标轴时间序列绘制

原有代码

library(tseries)
library(readxl)

data = read_excel(.......)

# 构建时间序列对象
equity = ts(data$EQUITY, start = c(2015,01,01), end = c(2020,01,01), frequency = 12)
cci = ts(data$CCI, start = c(2015,01,01), end = c(2020,01,01), frequency = 12)

# 初始绘制:两个序列尺度差异大,无法叠加
ts.plot(equity, cci, lty = c(1:2))

核心需求

  • 保留ts.plot作为绘图函数,兼容后续tseries对象绘制需求,不使用ggplot2方案
  • 新增第二纵坐标轴,解决两序列尺度差异导致的图形分离问题,实现同面板叠加显示
  • 支持自定义图例

可直接运行的实现方案

基础R的ts.plot没有内置双轴参数,通过线性尺度映射+手动新增坐标轴的方式即可实现,完全保留ts对象的原生渲染效果,代码如下:

# 1. 预定义尺度映射规则,将CCI的取值范围线性映射到EQUITY的取值区间
eq_val_range <- range(equity, na.rm = TRUE)
cci_val_range <- range(cci, na.rm = TRUE)

# 正向映射:CCI原始值 -> 适配EQUITY轴的缩放值
map_cci2eq <- function(cci_val) {
  eq_val_range[1] + (eq_val_range[2] - eq_val_range[1]) * 
    (cci_val - cci_val_range[1]) / (cci_val_range[2] - cci_val_range[1])
}

# 反向映射:EQUITY轴刻度值 -> CCI原始值,用于生成第二轴刻度标签
map_eq2cci <- function(eq_val) {
  cci_val_range[1] + (cci_val_range[2] - cci_val_range[1]) * 
    (eq_val - eq_val_range[1]) / (eq_val_range[2] - eq_val_range[1])
}

# 2. 调整画布边距,为右侧第二坐标轴预留空间
par(mar = c(5, 4, 4, 4) + 0.1)

# 3. 调用ts.plot绘制第一序列+缩放后的第二序列
ts.plot(
  equity, map_cci2eq(cci),
  lty = c(1, 2),
  col = c("#1f77b4", "#ff7f0e"),
  ylab = "EQUITY",
  main = "EQUITY与CCI时序双轴图"
)

# 4. 添加右侧第二纵轴
axis(
  side = 4,
  at = axTicks(side = 2),
  labels = round(map_eq2cci(axTicks(side = 2)), 2)
)
mtext("CCI", side = 4, line = 2.5)

# 5. 添加图例
legend(
  "topleft",
  legend = c("EQUITY", "CCI"),
  lty = c(1, 2),
  col = c("#1f77b4", "#ff7f0e"),
  bty = "n"
)

方案说明

  • 传入ts.plot的对象始终保持ts类型,时间轴渲染、刻度间隔完全和原生ts.plot效果一致,不存在第三方库的适配问题
  • 双轴刻度自动对齐,不需要手动调整刻度位置
  • 后续新增更多时间序列时,只需新增对应尺度映射函数、提前预留画布边距即可继续叠加
  • 线型、颜色、图例位置、标签均可根据需求自定义调整

内容的提问来源于stack exchange,提问作者Christian Bozzetto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 17:54:25