Как изменить тип линии в сюжете пророка? - PullRequest
0 голосов
/ 27 декабря 2018

Пророк Facebook в R (есть также версия Python) используется для генерации прогнозов временных рядов.

Модель m создается:

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

, которая возвращает оченькрасиво отформатированный график, например:

enter image description here

Я хотел бы изменить тип линии, чтобы получить не точки, а обычную тонкую линию.

Я пробовал это

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

, но получил ошибку

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

Есть какие-нибудь предложения, как преобразовать эти точки в линию?

Ответы [ 2 ]

0 голосов
/ 28 декабря 2018

можно сделать такие манипуляции с dyplot.prophet(m, forecast) (html-версия сюжета) :) до этого, мы должны переписать функцию как здесь:

dyplot.prophet <- function(x, fcst, uncertainty=TRUE, 
                           ...) 
{
  forecast.label='Predicted'
  actual.label='Actual'
  # create data.frame for plotting
  df <- prophet:::df_for_plotting(x, fcst)

  # build variables to include, or not, the uncertainty data
  if(uncertainty && exists("yhat_lower", where = df))
  {
    colsToKeep <- c('y', 'yhat', 'yhat_lower', 'yhat_upper')
    forecastCols <- c('yhat_lower', 'yhat', 'yhat_upper')
  } else
  {
    colsToKeep <- c('y', 'yhat')
    forecastCols <- c('yhat')
  }
  # convert to xts for easier date handling by dygraph
  dfTS <- xts::xts(df %>% dplyr::select_(.dots=colsToKeep), order.by = df$ds)

  # base plot
  dyBase <- dygraphs::dygraph(dfTS)

  presAnnotation <- function(dygraph, x, text) {
    dygraph %>%
      dygraphs::dyAnnotation(x, text, text, attachAtBottom = TRUE)
  }

  dyBase <- dyBase %>%
    # plot actual values
    dygraphs::dySeries(
      'y', label=actual.label, color='black',stepPlot = TRUE, strokeWidth=1
    ) %>%
    # plot forecast and ribbon
    dygraphs::dySeries(forecastCols, label=forecast.label, color='blue') %>%
    # allow zooming
    dygraphs::dyRangeSelector() %>% 
    # make unzoom button
    dygraphs::dyUnzoom()
  if (!is.null(x$holidays)) {
    for (i in 1:nrow(x$holidays)) {
      # make a gray line
      dyBase <- dyBase %>% dygraphs::dyEvent(
        x$holidays$ds[i],color = "rgb(200,200,200)", strokePattern = "solid")
      dyBase <- dyBase %>% dygraphs::dyAnnotation(
        x$holidays$ds[i], x$holidays$holiday[i], x$holidays$holiday[i],
        attachAtBottom = TRUE)
    }
  }
  return(dyBase)
}

strokeWidth=0 было раньше, и мы имеемизменил его на strokeWidth=1 и добавил stepPlot = TRUE

весь базовый код находится здесь: https://rdrr.io/cran/prophet/src/R/plot.R

0 голосов
/ 27 декабря 2018

Метод plot для prophet объектов использует ggplot2, поэтому базовые графические функции R, такие как lines(), не будут работать.Вы можете использовать от ggplot2::geom_line() до добавления линий, но на данный момент я не вижу простого способа заменить точек линиями ...

Примерс ?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)

Добавить строки:

library(ggplot2)
pp + geom_line()

Этот вопрос предоставляет (хакерский) путь вперед:

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

enter image description here

Но, очевидно, что-то пошло не так с хаком.Лучше было бы взглянуть на метод сюжета (prophet:::plot.prophet) и изменить его так, чтобы он вел себя так, как вам хочется ... Вот простая версия:

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)

Возможно, я вычеркнул некоторые из них.компоненты, которые существуют в ваших данных / прогнозе, хотя ...

enter image description here

...