3
votes

Trying to use ggplotly to graph time series data with a vertical line to indicate dates of interest.

Call fails with Error in Ops.Date(z[[xy]], 86400000) : * not defined for "Date" objects. I have tried unsuccessfully using both the latest CRAN and development versions of ggplot2 (as per plotly recommendation). Other SO questions (e.g., ggplotly and geom_bar when using dates - latest version of plotly (4.7.0)) do not address my concerns.

As illustrated below with plot object p - both ggplot and ggplotly work as expected. However, when a geom_vline() is added to the plot in p2, it only works correctly in ggplot, failing when calling ggplotly(p2).

library(plotly)
library(ggplot2) 
library(magrittr)

set.seed(1)
df <- data.frame(date = seq(from = lubridate::ymd("2019-01-01"), by = 1, length.out = 10),
                 y = rnorm(10))

p <- df %>% 
  ggplot(aes(x = date, y = y)) + 
  geom_line() 
p ## plots as expected
ggplotly(p) ## plots as expected

p2 <- p + geom_vline(xintercept = lubridate::ymd("2019-01-08"), linetype = "dashed")
p2 ## plots as expected
ggplotly(p2) ##fails
2
You should probably just report this as a bug in plotly. As a temporary workaround, you can change date into numeric, and do the axis manually (i.e. use scale_x_continuous with correct breaks and labels).Axeman

2 Answers

1
votes

I just solved this using @Axeman's suggestion. In your case, you can just replace the date:

 lubridate::ymd("2019-01-01")

becomes

 as.numeric(lubridate::ymd("2019-01-01"))

Not pretty, but it works.

0
votes

For future reference:

The pop-up window for vertical lines created via date (or POSIX*) to numeric conversions is rather blank. This is particularly valid for POSIX* applications where the exact time can often not be read off directly.

numeric

In case you need more significant pop-up content, the definition of a text aesthetic could be helpful (just ignore the 'unknown aesthetics' warning as it doesn't seem to apply). Then, simply specify what you want to see during mouse hover via the tooltip argument, ie. rule out xintercept, and you're all set.

p2 = p + 
  geom_vline(
    aes(
      xintercept = as.numeric(lubridate::ymd("2019-01-08"))
      , text = "date: 2019-01-08"
    )
    , linetype = "dashed"
  )

ggplotly(p2, tooltip = c("x", "y", "text"))

date