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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 07:05:55