Partially shaded background for ggplotly-object

2019-07-11 19:28发布

问题:

I'm trying to create a lineplot of a timeseries with ggplot2 and convert it to plotly. A part of the background of this plot is supposed to be shaded in a different color (like this one: Using geom_rect for time series shading in R). Unfortunately annotate() as well as geom_rect aren't transferred to the ggplotly-object as it seems. Therefore I tried to retroactively add a shape using plotly-code (based on this example: https://plot.ly/r/shapes/), but it is not working either, as shown in this reproducible example:

library(plotly)
library(ggplot2)

plot <-ggplot(data = economics, aes(x = date, y = unemploy)) + geom_line() 

plot <- ggplotly(plot)

layout(plot,
       shapes = list(
         list(type = "rect",
              fillcolor = "blue", line = list(color = "blue"), opacity = 0.9,
              x0 = "1980-01-01", x1 = "1990-01-01",
              y0 = 0, y1 = 4000
         )
       )
)

So how can I get this shading for my ggplotly-object? Recreating the whole plot in plotly is unfortunately not possible.

Thanks!

回答1:

As quoted in previous answer, we can access the shapes through plot[['x']][['layout']][['shapes']], and then use the function layout(...) to create the new shapes.

But the plot <- layout(...) function didn't work for me. (throwing unused argument error) Thus, I tried to just use plot[['x']][['layout']][['shapes']] functionality only, and it works.

plot[['x']][['layout']][['shapes']] <- list(
              list(type = "rect",
                   fillcolor = "lightgreen", line = list(color = "lightgreen"), opacity = 0.3,
                   x0 = 0, x1 = 30, xref = "x",
                   y0 = -100, y1 = 100, yref = "y"))

Hope that helps for others who can't use the layout(..) function.



回答2:

In order to make ggplotly work with shapes you would need to first clear the shapes coming from the conversion (beats me why they are there in the first place).

plot[['x']][['layout']][['shapes']] <- c()

and you would need to assign the layout function to your plot object.

plot <- layout(plot,
       shapes = list(
         list(type = "rect",
              fillcolor = "blue", line = list(color = "blue"), opacity = 0.9,
              x0 = "1980-01-01", x1 = "1990-01-01",
              y0 = 0, y1 = 4000
         )
       )
)


library(plotly)
library(ggplot2)

plot <-ggplot(data = economics, aes(x = date, y = unemploy)) + geom_line()
plot <- ggplotly(plot)

plot[['x']][['layout']][['shapes']] <- c()

plot <- layout(plot,
       shapes = list(
         list(type = "rect",
              fillcolor = "blue", line = list(color = "blue"), opacity = 0.5,
              x0 = "1980-01-01", x1 = "1990-01-01",
              y0 = 6000, y1 = 8000
         )
       )
)
plot

Update: It seems that either plotly` orgplot`` changed it's way of handling dates. Instead of passing a string dates, one would need to pass in integers now, i.e. it should be:

x0 = 315532800000, x1 = 631152000000

to get the correct result.



标签: r ggplot2 plotly