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

如何在R中绘制美观的SARIMA模型时间序列预测对比图?

使用ggplot优化SARIMA模型预测与观测值对比图

我在R中实现了SARIMA模型,为直观验证模型性能,编写了如下代码绘制预测值与观测值的对比图:

library(forecast)
Number_of_visitor <- runif(396, 24000,6600000)
tsdata_training <- ts(Number_of_visitor[157:348], frequency = 12, start = c(2003,1))
arima.model <- Arima(tsdata_training,order=c(0, 1, 1),
                 seasonal=list(order=c(0, 1, 1), period=12))

forecast_2019 <- predict(arima.model, n.ahead = 12)$pred # 2019年预测值(用于模型测试)
tsdata_2019_22_observed <- ts(Number_of_visitor[349:396], frequency = 12, start = c(2019,1)) # 2019-2022年观测数据
tsdata_post_pandemic_forecast <- ts(predict(arima.model, n.ahead = 48)$pred[13:48],frequency = 12, start = c(2020,1)) # 2020-2022年预测值 

# 原绘图代码
ts.plot(forecast_2019, tsdata_2019_22_observed, log = "y", lty = c(1,3), xlab="Year", ylab="Number of Visitors")
lines(tsdata_post_pandemic_forecast,col="red")

当前生成的图表美观性不足,希望改用ggplot生成更美观的对比图,要求横轴为Year,纵轴为Number of Visitors,用线条区分预测值与观测值。


解决方案:转换数据格式并使用ggplot绘图

ggplot基于数据框工作,因此需要先将时间序列数据转换为结构化的数据框,再进行可视化:

1. 加载必要的包

library(forecast)
library(tidyverse)
library(lubridate)

2. 生成并整理数据(保留原模型逻辑)

set.seed(123) # 设置随机种子保证结果可复现
Number_of_visitor <- runif(396, 24000, 6600000)
tsdata_training <- ts(Number_of_visitor[157:348], frequency = 12, start = c(2003,1))
arima.model <- Arima(tsdata_training, order=c(0, 1, 1),
                     seasonal=list(order=c(0, 1, 1), period=12))

# 生成完整的48期预测数据
forecast_full <- predict(arima.model, n.ahead = 48)$pred

# 整理2019-2022年观测数据为数据框
observed_df <- tsdata_2019_22_observed %>%
  as.data.frame() %>%
  mutate(
    date = seq.Date(from = ymd("2019-01-01"), by = "month", length.out = n()),
    value = .,
    type = "观测值"
  ) %>%
  select(date, value, type)

# 整理2019年预测数据为数据框
forecast_2019_df <- forecast_full[1:12] %>%
  as.data.frame() %>%
  mutate(
    date = seq.Date(from = ymd("2019-01-01"), by = "month", length.out = n()),
    value = .,
    type = "2019年预测值"
  ) %>%
  select(date, value, type)

# 整理2020-2022年预测数据为数据框
forecast_post_2020_df <- forecast_full[13:48] %>%
  as.data.frame() %>%
  mutate(
    date = seq.Date(from = ymd("2020-01-01"), by = "month", length.out = n()),
    value = .,
    type = "2020-2022年预测值"
  ) %>%
  select(date, value, type)

# 合并所有绘图数据
plot_data <- bind_rows(observed_df, forecast_2019_df, forecast_post_2020_df)

3. 使用ggplot绘制美观的对比图

ggplot(plot_data, aes(x = date, y = value, color = type, linetype = type)) +
  geom_line(linewidth = 1) +
  # 格式化横轴为年份显示
  scale_x_date(date_labels = "%Y", date_breaks = "1 year") +
  # 纵轴添加千分位分隔符
  scale_y_continuous(labels = scales::comma) +
  # 设置标题与标签
  labs(
    x = "Year", 
    y = "Number of Visitors", 
    color = "数据类型", 
    linetype = "数据类型"
  ) +
  # 使用简洁的主题
  theme_minimal() +
  # 自定义主题细节
  theme(
    axis.text = element_text(size = 10),
    axis.title = element_text(size = 12, face = "bold"),
    legend.title = element_text(size = 10, face = "bold"),
    legend.position = "bottom"
  )

说明

  • 通过将时间序列转换为带date列的数据框,让ggplot可以轻松处理时间轴
  • 使用color和linetype双重区分不同类型的数据,提升可读性
  • theme_minimal提供清爽的视觉风格,可根据需求调整颜色、线条粗细等参数

内容的提问来源于stack exchange,提问作者Günal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 12:55:35