Search code examples
rdateplotlyshapes

How to override the shapes function in plotly (R) to set custom x axis date range?


I'd like to create plot where there is blue shading between y=0 and y=1 across the entire x-axis range. I started to do this using "shapes" in plotly, however, I am running into an issue as I have dates on the x-axis. In the end I'd like this shading to be visible no matter what the dates are on the x-axis (i.e., -Infinity to Infinity).

My current way of solving this problem is by hard-coding dates, but this isn't scalable. My code is as follows:

library(plotly)

x <- data.frame(seq(as.Date("2015-01-01"),as.Date("2015-04-10"),1))
random_y <- rnorm(100, mean = 0)
data <- data.frame(x, random_y)
colnames(data)=c("date","num")

fig <- plot_ly(data, type = 'scatter', mode = 'lines')%>%
  add_trace(x = ~date, y = ~num)%>%
  layout(showlegend = F)%>%
  layout(shapes = list(type = "rect",fillcolor = "blue", line = list(color = "blue"), opacity = 0.1,y0 = 0, y1 = 1,yref="y",x0 = "2015-01-01", x1 = "2015-04-10",xref="x"))
fig

I have two questions. 1. Is there a way to set the shape x-axis dates from -Inf to Inf? 2. Is there a way to set the axis limits to override the shape limits (i.e., to show a smaller date range)? In the code example, what if I wanted to set the axis limits to February 1 to February 28, 2015, but wanted the shape to extend past these dates?

Thank you


Solution

  • A few mods: xref = "paper", x0 = 0, x1 = 1, this indicates across the entire domain of the x-axis. By default Plotly's axes' domains are [0:1], that's where the values come from.

    library(plotly)
    
    x <- data.frame(seq(as.Date("2015-01-01"),as.Date("2015-04-10"),1))
    random_y <- rnorm(100, mean = 0)
    data <- data.frame(x, random_y)
    colnames(data)=c("date","num")
    
    fig <- plot_ly(data, type = 'scatter', mode = 'lines') %>%
      add_trace(x = ~date, y = ~num) %>%
      layout(showlegend = F) %>%
      layout(shapes = list(
        type = "rect", fillcolor = "blue", line = list(color = "blue"), opacity = 0.1, 
        y0 = 0, y1 = 1, yref = "y", x0 = 0, x1 = 1, xref = "paper" # use x domain
      ))
    fig
    

    Let me know if you have any questions.

    enter image description here