EN VI

Adding multiple vlines to facetted charts?

2024-03-14 14:30:05
How to Adding multiple vlines to facetted charts

I'm trying to create plots of stock prices over time and add vertical lines at the ex-dates. The only thing giving me trouble now is getting multiple lines on the same chart for each stock.

For example I currently have data on 9 stocks and their ex-dates. I want to create 9 charts each one havings its own ex-dates marked off using vline.

Here is the head of the

> 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

currently I've tried

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)

which gives me chart produced

but if i try

charts <- ggplot(data=test, aes(x = ref_date, y = price_close))
charts <- charts + geom_line()+geom_vline(xintercept=c(test[,16:29]),color='red')
charts <- charts + facet_wrap(~ticker, scales = 'free') 
print(charts)

I get the following error:

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.

Solution:

The issue is that in your second approach you pass a data.frame to xintercept which results in an error.

Instead, to achieve your desired result create a separate data frame containing the dates for the vlines by ticker:

library(ggplot2)
library(tidyr)
library(dplyr, warn = FALSE)

dat_vline <- test |>
  dplyr::select(ticker, dplyr::starts_with("exdate")) |>
  tidyr::pivot_longer(-ticker, names_to = "exdate") |>
  # Keep only the distinct dates per ticker
  dplyr::distinct(ticker, value)

ggplot(test, aes(ref_date, price_close)) +
  geom_line() +
  geom_vline(
    data = dat_vline,
    aes(xintercept = value),
    color = "red"
  ) +
  # Just for the reprex
  scale_x_date(
    limits = range(dat_vline$value)
  ) +
  #
  facet_wrap(~ticker, scales = "free")

DATA

test <- data.frame(
  ticker = c("BTI", "BTI", "BTI", "BTI", "BTI", "BTI"),
  ref_date = as.Date(c("2023-01-25", "2023-01-26", "2023-03-21", "2023-03-22", "2023-03-27", "2023-01-30")),
  price_open = c(37.66, 37.92, 36.72, 36.72, 35.41, 37.70),
  price_high = c(38.15, 37.94, 36.79, 36.80, 35.54, 38.17),
  price_low = c(37.66, 37.61, 36.48, 36.19, 35.36, 37.66),
  price_close = c(38.09, 37.76, 36.65, 36.19, 35.40, 38.07),
  volume = c(2938600, 2668200, 2728300, 3548300, 3923300, 3399600),
  price_adjusted = c(34.92060, 34.61806, 33.60042, 33.17869, 33.09549, 34.90226),
  ret_adjusted_prices = c(-0.003401351, -0.008663758, 0.007698789, -0.012551332, 0.004255342, 0.013848386),
  ret_closing_prices = c(-0.003401388, -0.008663739, 0.007698724, -0.012551238, 0.004255362, 0.013848215),
  cumret_adjusted_prices = c(1.147131, 1.137192, 1.103763, 1.089909, 1.087176, 1.146528),
  Company = c("British American Tobacco ADR", "British American Tobacco ADR", "British American Tobacco ADR", "British American Tobacco ADR", "British American Tobacco ADR", "British American Tobacco ADR"),
  `Ex-Dividend Date` = as.Date(c("2024-03-21", "2024-03-21", "2024-03-21", "2024-03-21", "2024-03-21", "2024-03-21")),
  Dividend = c(0.733059, 0.733059, 0.733059, 0.733059, 0.733059, 0.733059),
  exdate1 = as.Date("2025-06-27"),
  exdate2 = as.Date("2025-03-21"),
  exdate3 = as.Date("2024-12-19"),
  exdate4 = as.Date("2024-09-26"),
  exdate5 = as.Date("2024-06-27"),
  exdate6 = as.Date("2024-03-21"),
  exdate7 = as.Date("2023-12-21"),
  exdate8 = as.Date("2023-09-28"),
  exdate9 = as.Date("2023-07-13"),
  exdate10 = as.Date("2023-03-23"),
  exdate11 = as.Date("2022-12-22"),
  exdate12 = as.Date("2022-09-29"),
  exdate13 = as.Date("2022-07-07"),
  exdate14 = as.Date("2022-03-24"),
  exdate15 = as.Date("2021-12-22"),
  potential = c(1442.083, 1442.083, 1442.083, 1442.083, 1442.083, 1442.083)
)
Answer

Login


Forgot Your Password?

Create Account


Lost your password? Please enter your email address. You will receive a link to create a new password.

Reset Password

Back to login