如何在ggplot2分面图表中为各股票添加多条垂直参考线(vline)
问题
我正尝试绘制股票价格随时间变化的走势图,并在除息日(ex-dates)位置添加垂直参考线(vline)。目前的问题是无法为每只股票的图表添加多条垂直参考线。
现有9只股票的价格及对应除息日数据,希望生成9个分面图表,每个图表标记出对应股票的所有除息日。数据集头部信息如下:
> head(test) ticker ref_date price_open price_high price_low price_close volume price_adjusted ret_adjusted_prices 1 BTI 2023-01-25 37.66 38.15 37.66 38.09 2938600 34.92060 -0.003401351 2 BTI 2023-01-26 37.92 37.94 37.61 37.76 2668200 34.61806 -0.008663758 3 BTI 2023-03-21 36.72 36.79 36.48 36.65 2728300 33.60042 0.007698789 4 BTI 2023-03-22 36.72 36.80 36.19 36.19 3548300 33.17869 -0.012551332 5 BTI 2023-03-27 35.41 35.54 35.36 35.40 3923300 33.09549 0.004255342 6 BTI 2023-01-30 37.70 38.17 37.66 38.07 3399600 34.90226 0.013848386 ret_closing_prices cumret_adjusted_prices Company Ex-Dividend Date Dividend 1 -0.003401388 1.147131 British American Tobacco ADR Mar 21, 2024 0.733059 2 -0.008663739 1.137192 British American Tobacco ADR Mar 21, 2024 0.733059 3 0.007698724 1.103763 British American Tobacco ADR Mar 21, 2024 0.733059 4 -0.012551238 1.089909 British American Tobacco ADR Mar 21, 2024 0.733059 5 0.004255362 1.087176 British American Tobacco ADR Mar 21, 2024 0.733059 6 0.013848215 1.146528 British American Tobacco ADR Mar 21, 2024 0.733059 exdate1 exdate2 exdate3 exdate4 exdate5 exdate6 exdate7 exdate8 exdate9 1 2025-06-27 2025-03-21 2024-12-19 2024-09-26 2024-06-27 2024-03-21 2023-12-21 2023-09-28 2023-07-13 2 2025-06-27 2025-03-21 2024-12-19 2024-09-26 2024-06-27 2024-03-21 2023-12-21 2023-09-28 2023-07-13 3 2025-06-27 2025-03-21 2024-12-19 2024-09-26 2024-06-27 2024-03-21 2023-12-21 2023-09-28 2023-07-13 4 2025-06-27 2025-03-21 2024-12-19 2024-09-26 2024-06-27 2024-03-21 2023-12-21 2023-09-28 2023-07-13 5 2025-06-27 2025-03-21 2024-12-19 2024-09-26 2024-06-27 2024-03-21 2023-12-21 2023-09-28 2023-07-13 6 2025-06-27 2025-03-21 2024-12-19 2024-09-26 2024-06-27 2024-03-21 2023-12-21 2023-09-28 2023-07-13 exdate10 exdate11 exdate12 exdate13 exdate14 exdate15 potential 1 2023-03-23 2022-12-22 2022-09-29 2022-07-07 2022-03-24 2021-12-22 1442.083 2 2023-03-23 2022-12-22 2022-09-29 2022-07-07 2022-03-24 2021-12-22 1442.083 3 2023-03-23 2022-12-22 2022-09-29 2022-07-07 2022-03-24 2021-12-22 1442.083 4 2023-03-23 2022-12-22 2022-09-29 2022-07-07 2022-03-24 2021-12-22 1442.083 5 2023-03-23 2022-12-22 2022-09-29 2022-07-07 2022-03-24 2021-12-22 1442.083 6 2023-03-23 2022-12-22 2022-09-29 2022-07-07 2022-03-24 2021-12-22 1442.083
尝试添加单个除息日列时可以正常生成图表:
charts <- ggplot(data=test, aes(x = ref_date, y = price_close)) charts <- charts + geom_line()+geom_vline(xintercept=c(test[,16]),color='red') charts <- charts + facet_wrap(~ticker, scales = 'free') print(charts)
但添加多个除息日列(test[,16:29])时出现错误:
Error in `geom_vline()`: ! Problem while converting geom to grob. ℹ Error occurred in the 2nd layer. Caused by error in `UseMethod()`: ! no applicable method for 'rescale' applied to an object of class "list" Run `rlang::last_trace()` to see where the error occurred.
需要解决如何为每个股票分面图表添加对应多条垂直参考线的问题。
解决方案
步骤1:重构数据集格式
当前除息日按列存储(exdate1到exdate15)的宽格式不适合ggplot分面匹配,需转换为长格式,将所有除息日整合到一列并保留对应股票代码:
library(tidyr) library(dplyr) # 提取股票代码和所有除息日列,转换为长格式并去重 ex_dates_long <- test %>% select(ticker, starts_with("exdate")) %>% pivot_longer(cols = starts_with("exdate"), names_to = "exdate_col", values_to = "exdate") %>% distinct(ticker, exdate) %>% mutate(exdate = as.Date(exdate)) # 确保日期格式正确
步骤2:绘制分面图表并添加垂直参考线
使用独立的长格式数据集给geom_vline提供除息日数据,ggplot会自动通过ticker匹配对应分面:
library(ggplot2) charts <- ggplot(data = test, aes(x = ref_date, y = price_close)) + geom_line() + # 关联除息日数据集,按股票匹配分面添加参考线 geom_vline(data = ex_dates_long, aes(xintercept = as.numeric(exdate)), # 日期转数值适配x轴 color = 'red', linetype = "dashed") + facet_wrap(~ticker, scales = 'free') + labs(x = "日期", y = "收盘价") + theme_bw() print(charts)
关键说明
- 宽转长:将分散的除息日列合并为一列,是让分面参考线正确匹配的核心操作。
- 独立数据源:
geom_vline使用单独的数据集,避免主数据重复导致的参考线混乱。 - 日期转换:ggplot日期轴底层为数值型,需将
exdate转数值才能被xintercept识别。
内容的提问来源于stack exchange,提问作者majulito
相关产品推荐
相关产品推荐

