在R中绘制时间序列标准差:阴影/虚线包裹序列的实现
哈哈,我完全懂你想要的那种效果!刚好之前处理过类似的需求,给你两种实用的方案,都是基于你的zoo时间序列来操作的:
方法一:用ggplot2实现(推荐,更灵活)
ggplot2处理时间序列可视化非常方便,不管是加虚线还是阴影都很容易:
步骤1:把zoo对象转成数据框
ggplot更适配数据框格式,我们可以用下面的代码转换:
library(zoo) library(ggplot2) # 假设你的zoo对象叫df df_df <- data.frame(date = index(df), value = coredata(df))
情况1:添加整体序列的标准差范围
如果是想给整个序列的均值加减1倍标准差做范围:
# 计算均值和标准差 mean_val <- mean(df_df$value, na.rm = TRUE) sd_val <- sd(df_df$value, na.rm = TRUE) upper_bound <- mean_val + sd_val lower_bound <- mean_val - sd_val # 绘图:同时加虚线和阴影(可以二选一) ggplot(df_df, aes(x = date, y = value)) + geom_line(color = "black", linewidth = 1) + # 原始时间序列 # 红色虚线标注上下标准差 geom_hline(yintercept = upper_bound, color = "red", linetype = "dashed") + geom_hline(yintercept = lower_bound, color = "red", linetype = "dashed") + # 红色半透明阴影填充范围(可选) geom_ribbon(aes(ymin = lower_bound, ymax = upper_bound), alpha = 0.2, fill = "red") + labs(x = "日期", y = "数值", title = "时间序列 + 整体标准差范围") + theme_minimal()
情况2:添加滚动标准差的范围
如果是想展示滑动窗口内的标准差(比如7天窗口),用rollapply计算:
# 计算滚动均值和滚动标准差(窗口设为7,可根据需求调整) df_df$roll_mean <- rollapply(df_df$value, width = 7, FUN = mean, fill = NA, align = "center") df_df$roll_sd <- rollapply(df_df$value, width = 7, FUN = sd, fill = NA, align = "center") df_df$roll_upper <- df_df$roll_mean + df_df$roll_sd df_df$roll_lower <- df_df$roll_mean - df_df$roll_sd # 绘图 ggplot(df_df, aes(x = date, y = value)) + geom_line(color = "black", linewidth = 1) + # 滚动标准差的红色虚线 geom_line(aes(y = roll_upper), color = "red", linetype = "dashed") + geom_line(aes(y = roll_lower), color = "red", linetype = "dashed") + # 滚动范围的阴影(可选) geom_ribbon(aes(ymin = roll_lower, ymax = roll_upper), alpha = 0.2, fill = "red", na.rm = TRUE) + labs(x = "日期", y = "数值", title = "时间序列 + 滚动标准差范围") + theme_minimal()
方法二:用R基础绘图实现
如果习惯用基础包,也可以轻松实现:
情况1:整体序列的标准差范围
# 先绘制原始时间序列 plot(df, col = "black", lwd = 1, xlab = "日期", ylab = "数值", main = "时间序列 + 整体标准差范围") # 计算均值和标准差 mean_val <- mean(coredata(df), na.rm = TRUE) sd_val <- sd(coredata(df), na.rm = TRUE) upper_bound <- mean_val + sd_val lower_bound <- mean_val - sd_val # 添加红色虚线 abline(h = upper_bound, col = "red", lty = 2) abline(h = lower_bound, col = "red", lty = 2) # 可选:添加半透明阴影 x_vals <- as.numeric(index(df)) # 把日期转成数值方便polygon处理 y_upper <- rep(upper_bound, length(x_vals)) y_lower <- rep(lower_bound, length(x_vals)) # 绘制阴影(边框设为NA避免多余线条) polygon(c(x_vals, rev(x_vals)), c(y_upper, rev(y_lower)), col = adjustcolor("red", alpha.f = 0.2), border = NA) # 把原始线再画一遍,避免被阴影盖住 lines(df, col = "black", lwd = 1)
情况2:滚动标准差的范围
# 计算滚动均值和标准差 roll_mean <- rollapply(coredata(df), width = 7, FUN = mean, fill = NA, align = "center") roll_sd <- rollapply(coredata(df), width = 7, FUN = sd, fill = NA, align = "center") roll_upper <- roll_mean + roll_sd roll_lower <- roll_mean - roll_sd # 转成zoo对象和原序列对齐 roll_upper_zoo <- zoo(roll_upper, index(df)) roll_lower_zoo <- zoo(roll_lower, index(df)) # 绘图 plot(df, col = "black", lwd = 1, xlab = "日期", ylab = "数值", main = "时间序列 + 滚动标准差范围") # 添加滚动标准差虚线 lines(roll_upper_zoo, col = "red", lty = 2) lines(roll_lower_zoo, col = "red", lty = 2) # 可选:添加阴影 x_vals <- as.numeric(index(df)) polygon(c(x_vals, rev(x_vals)), c(coredata(roll_upper_zoo), rev(coredata(roll_lower_zoo))), col = adjustcolor("red", alpha.f = 0.2), border = NA) # 重新绘制原始线 lines(df, col = "black", lwd = 1)
你可以根据自己的需求选择整体或滚动的版本,虚线和阴影也可以自由组合~
内容的提问来源于stack exchange,提问作者aipam
相关产品推荐
相关产品推荐

