如何在ggplot2中用dummy变量高亮时段并绘制yield与fx时间序列?
解决方法:用ggplot2绘制双时间序列并高亮指定区域
没问题,这需求很常见,咱们一步步来实现:
第一步:数据预处理
首先得把date列转成日期格式(不然ggplot没法正确识别时间轴),同时如果你的dummy是分散的1,最好先把连续的1合并成高亮区间(避免画一堆小矩形)。
先加载需要的包,处理示例数据:
# 加载tidyverse(包含ggplot2、dplyr、lubridate等工具) library(tidyverse) # 你的原始数据(这里用示例数据演示) df <- tibble( date = c("1/1/1990", "1/2/1990", "1/3/1990", "1/4/1990", "1/5/1990", "1/6/1990", "1/7/1990", "1/8/1990", "1/9/1990", "1/10/1990"), dummy = c(0,0,0,0,0,1,1,1,1,1), yield = c(10.029, 10.036, 10.119, 10.02, 10.013, 10.066, 10.057, 10.057, 10.067, 10.186), fx = c(1.261184049, 1.261008068, 1.258932591, 1.261410528, 1.261586847, 1.260255526, 1.260481006, 1.260481006, 1.260230488, 1.257272051) ) %>% mutate(date = mdy(date)) # 把字符型日期转成日期格式 # 生成连续的高亮区间(处理dummy=1的连续时间段) highlight_regions <- df %>% mutate(group = rleid(dummy)) %>% # 给连续相同的dummy值分组 filter(dummy == 1) %>% group_by(group) %>% summarise(xmin = min(date), xmax = max(date)) # 每个连续组的起止日期
第二步:绘图方案(两种可选)
方案1:双Y轴同图对比
适合需要在同一时间轴上直接对比两个序列的场景,注意要调整缩放系数让两个序列都清晰显示:
ggplot(df, aes(x = date)) + # 先画高亮阴影(要放在最底层,避免挡住折线) geom_rect(data = highlight_regions, aes(xmin = xmin, xmax = xmax, ymin = -Inf, ymax = Inf), fill = "lightblue", alpha = 0.3, inherit.aes = FALSE) + # 绘制yield序列(左Y轴) geom_line(aes(y = yield, color = "Yield"), size = 1) + # 绘制fx序列(右Y轴,这里用*8做缩放,你可以根据自己的数据调整系数) geom_line(aes(y = fx * 8, color = "FX"), size = 1) + # 设置双Y轴 scale_y_continuous( name = "Yield", sec.axis = sec_axis(~ . / 8, name = "FX Rate") ) + # 自定义颜色和标签 scale_color_manual(values = c("Yield" = "darkred", "FX" = "darkblue")) + labs(title = "Yield & FX Time Series", x = "Date", color = "Series") + theme_minimal() + theme(legend.position = "top")
方案2:分面展示(更清晰,无缩放误导)
如果不想用双Y轴(避免视觉误导),可以把两个序列分成上下面板,阴影会跨面板显示:
# 先把数据转成长格式 df_long <- df %>% pivot_longer(cols = c(yield, fx), names_to = "variable", values_to = "value") ggplot(df_long, aes(x = date, y = value)) + geom_rect(data = highlight_regions, aes(xmin = xmin, xmax = xmax, ymin = -Inf, ymax = Inf), fill = "lightblue", alpha = 0.3, inherit.aes = FALSE) + geom_line(aes(color = variable), size = 1) + # 分面,每个序列一个面板,Y轴自由缩放 facet_wrap(~variable, scales = "free_y", ncol = 1) + labs(title = "Yield & FX Time Series with Dummy Highlight", x = "Date", y = "Value", color = "Series") + scale_color_manual(values = c("yield" = "darkred", "fx" = "darkblue")) + theme_minimal()
关键注意点
geom_rect的inherit.aes = FALSE必须加,不然会继承主图的y映射导致报错- 双Y轴的缩放系数需要根据你的实际数据范围调整,确保两个序列都在可视范围内
- 如果你的
dummy=1是分散的(非连续),rleid也能自动分组,生成多个独立的高亮区块
内容的提问来源于stack exchange,提问作者Clemens
相关产品推荐
相关产品推荐

