From df4b6158ebe977044867664e005edb38cd7fe936 Mon Sep 17 00:00:00 2001 From: Ben Letham Date: Thu, 13 Apr 2017 02:08:34 -0700 Subject: [PATCH] Allow shifting the start date of the yearly seasonality plot --- R/R/prophet.R | 18 +++++++++++++----- R/man/plot_yearly.Rd | 6 +++++- R/man/prophet_plot_components.Rd | 6 +++++- python/fbprophet/forecaster.py | 16 ++++++++++++---- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/R/R/prophet.R b/R/R/prophet.R index 887b712..32b8ee8 100644 --- a/R/R/prophet.R +++ b/R/R/prophet.R @@ -990,13 +990,17 @@ plot.prophet <- function(x, fcst, uncertainty = TRUE, plot_cap = TRUE, #' @param weekly_start Integer specifying the start day of the weekly #' seasonality plot. 0 (default) starts the week on Sunday. 1 shifts by 1 day #' to Monday, and so on. +#' @param yearly_start Integer specifying the start day of the yearly +#' seasonality plot. 0 (default) starts the year on Jan 1. 1 shifts by 1 day +#' to Jan 2, and so on. #' #' @return Invisibly return a list containing the plotted ggplot objects #' #' @export #' @importFrom dplyr "%>%" -prophet_plot_components <- function(m, fcst, uncertainty = TRUE, - plot_cap = TRUE, weekly_start = 0) { +prophet_plot_components <- function( + m, fcst, uncertainty = TRUE, plot_cap = TRUE, weekly_start = 0, + yearly_start = 0) { df <- df_for_plotting(m, fcst) # Plot the trend panels <- list(plot_trend(df, uncertainty, plot_cap)) @@ -1010,7 +1014,7 @@ prophet_plot_components <- function(m, fcst, uncertainty = TRUE, } # Plot yearly seasonality, if present if ("yearly" %in% colnames(df)) { - panels[[length(panels) + 1]] <- plot_yearly(m, uncertainty) + panels[[length(panels) + 1]] <- plot_yearly(m, uncertainty, yearly_start) } # Make the plot. grid::grid.newpage() @@ -1119,12 +1123,16 @@ plot_weekly <- function(m, uncertainty = TRUE, weekly_start = 0) { #' #' @param m Prophet model object. #' @param uncertainty Boolean to plot uncertainty intervals. +#' @param yearly_start Integer specifying the start day of the yearly +#' seasonality plot. 0 (default) starts the year on Jan 1. 1 shifts by 1 day +#' to Jan 2, and so on. #' #' @return A ggplot2 plot. -plot_yearly <- function(m, uncertainty = TRUE) { +plot_yearly <- function(m, uncertainty = TRUE, yearly_start = 0) { # Compute yearly seasonality for a Jan 1 - Dec 31 sequence of dates. df.y <- data.frame( - ds=seq.Date(zoo::as.Date('2017-01-01'), by='d', length.out=365), cap=1.) + ds=seq.Date(zoo::as.Date('2017-01-01'), by='d', length.out=365) + + yearly_start, cap=1.) df.y <- setup_dataframe(m, df.y)$df seas <- predict_seasonal_components(m, df.y) seas$ds <- df.y$ds diff --git a/R/man/plot_yearly.Rd b/R/man/plot_yearly.Rd index a14e762..50169b8 100644 --- a/R/man/plot_yearly.Rd +++ b/R/man/plot_yearly.Rd @@ -4,12 +4,16 @@ \alias{plot_yearly} \title{Plot the yearly component of the forecast.} \usage{ -plot_yearly(m, uncertainty = TRUE) +plot_yearly(m, uncertainty = TRUE, yearly_start = 0) } \arguments{ \item{m}{Prophet model object.} \item{uncertainty}{Boolean to plot uncertainty intervals.} + +\item{yearly_start}{Integer specifying the start day of the yearly +seasonality plot. 0 (default) starts the year on Jan 1. 1 shifts by 1 day +to Jan 2, and so on.} } \value{ A ggplot2 plot. diff --git a/R/man/prophet_plot_components.Rd b/R/man/prophet_plot_components.Rd index fdd9da0..34ce1ee 100644 --- a/R/man/prophet_plot_components.Rd +++ b/R/man/prophet_plot_components.Rd @@ -7,7 +7,7 @@ Prints a ggplot2 with panels for trend, weekly and yearly seasonalities if present, and holidays if present.} \usage{ prophet_plot_components(m, fcst, uncertainty = TRUE, plot_cap = TRUE, - weekly_start = 0) + weekly_start = 0, yearly_start = 0) } \arguments{ \item{m}{Prophet object.} @@ -23,6 +23,10 @@ figure, if available.} \item{weekly_start}{Integer specifying the start day of the weekly seasonality plot. 0 (default) starts the week on Sunday. 1 shifts by 1 day to Monday, and so on.} + +\item{yearly_start}{Integer specifying the start day of the yearly +seasonality plot. 0 (default) starts the year on Jan 1. 1 shifts by 1 day +to Jan 2, and so on.} } \value{ Invisibly return a list containing the plotted ggplot objects diff --git a/python/fbprophet/forecaster.py b/python/fbprophet/forecaster.py index 71605fc..13ee2e4 100644 --- a/python/fbprophet/forecaster.py +++ b/python/fbprophet/forecaster.py @@ -915,7 +915,7 @@ class Prophet(object): return fig def plot_components(self, fcst, uncertainty=True, plot_cap=True, - weekly_start=0): + weekly_start=0, yearly_start=0): """Plot the Prophet forecast components. Will plot whichever are available of: trend, holidays, weekly @@ -930,6 +930,9 @@ class Prophet(object): weekly_start: Optional int specifying the start day of the weekly seasonality plot. 0 (default) starts the week on Sunday. 1 shifts by 1 day to Monday, and so on. + yearly_start: Optional int specifying the start day of the yearly + seasonality plot. 0 (default) starts the year on Jan 1. 1 shifts + by 1 day to Jan 2, and so on. Returns ------- @@ -958,7 +961,8 @@ class Prophet(object): artists += self.plot_weekly(ax=ax, uncertainty=uncertainty, weekly_start=weekly_start) elif plot == 'yearly': - artists += self.plot_yearly(ax=ax, uncertainty=uncertainty) + artists += self.plot_yearly(ax=ax, uncertainty=uncertainty, + yearly_start=yearly_start) fig.tight_layout() return artists @@ -1072,7 +1076,7 @@ class Prophet(object): ax.set_ylabel('weekly') return artists - def plot_yearly(self, ax=None, uncertainty=True): + def plot_yearly(self, ax=None, uncertainty=True, yearly_start=0): """Plot the yearly component of the forecast. Parameters @@ -1080,6 +1084,9 @@ class Prophet(object): ax: Optional matplotlib Axes to plot on. One will be created if this is not provided. uncertainty: Optional boolean to plot uncertainty intervals. + yearly_start: Optional int specifying the start day of the yearly + seasonality plot. 0 (default) starts the year on Jan 1. 1 shifts + by 1 day to Jan 2, and so on. Returns ------- @@ -1091,7 +1098,8 @@ class Prophet(object): ax = fig.add_subplot(111) # Compute yearly seasonality for a Jan 1 - Dec 31 sequence of dates. df_y = pd.DataFrame( - {'ds': pd.date_range(start='2017-01-01', periods=365), 'cap': 1.}) + {'ds': pd.date_range(start='2017-01-01', periods=365) + + pd.Timedelta(days=yearly_start), 'cap': 1.}) df_y = self.setup_dataframe(df_y) seas = self.predict_seasonal_components(df_y) artists += ax.plot(df_y['ds'], seas['yearly'], ls='-',