如何在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
相关产品推荐
相关产品推荐

