Search code examples
rfacebook-prophet

How to change type of line in prophet plot?


Facebook's Prophet in R (there's also a Python version) is used to generate time series forecasts.

A model m is created by:

m <- prophet(df)
future <- make_future_dataframe(m, periods = 365)
forecast <- predict(m, future)
plot(m, forecast)

Which returns a very nicely formatted graph, like:

enter image description here

I would like to change the line type, to get not dots but a usual thin line.

I had tried this

lines(m$history$y,lty=1)

but got an error

 In doTryCatch(return(expr), name, parentenv, handler)

Are there are any suggestions how to convert those dots into a line?


Solution

  • The plot method for prophet objects uses ggplot2, so base R graphics functions like lines() won't work. You can use ggplot2::geom_line() to add lines, but at the moment I don't see an easy way to replace the points by lines ...

    Example from ?prophet:

    history <- data.frame(ds = seq(as.Date('2015-01-01'), as.Date('2016-01-01'), by = 'd'),
                               y = sin(1:366/200) + rnorm(366)/10)
         m <- prophet(history)
    future <- make_future_dataframe(m, periods = 365)
    forecast <- predict(m, future)
    pp <- plot(m,forecast)
    

    Add lines:

    library(ggplot2)
    pp + geom_line()
    

    This question provides a (hacky) way forward:

    pp2 <- pp + geom_line()
    qq2 <- ggplot_build(pp2)
    qq2$data[[2]]$colour <- NA
    plot(ggplot_gtable(qq2))
    

    enter image description here

    But obviously something went wrong with the hack. The better bet would be to look at the plot method(prophet:::plot.prophet) and modify it to behave as you want ... Here is the bare-bones version:

    df <- prophet:::df_for_plotting(m, forecast)
    gg <-ggplot(df, aes(x = ds, y = y)) + labs(x = "ds", y = "y")
    gg <- gg + geom_ribbon(ggplot2::aes(ymin = yhat_lower, 
            ymax = yhat_upper), alpha = 0.2, fill = "#0072B2", 
            na.rm = TRUE)
    ## replace first geom_point() with geom_line() in next line ...
    gg <- gg + geom_line(na.rm = TRUE) + geom_line(aes(y = yhat), 
        color = "#0072B2", na.rm = TRUE) + theme(aspect.ratio = 3/5)
    

    I may have stripped out some components that exist in your data/forecast, though ...

    enter image description here