plotly prophet

Solutions on MaxInterview for plotly prophet by the best coders in the world

showing results for - "plotly prophet"
Albin
24 Nov 2017
1import pandas as pd
2from fbprophet import Prophet
3import plotly.plotly as py
4import plotly.graph_objs as go
5import datetime
6from scipy.stats import boxcox
7from scipy.special import inv_boxcox
8from datetime import date
9
10# Dummy Data
11import numpy as np
12dummy_df = pd.DataFrame()
13dummy_df['ds_day'] = pd.date_range(start='1/1/2018', end='1/1/2019')
14dummy_df['row_num'] = range(1, dummy_df.shape[0] + 1)
15dummy_df['multiplier'] = np.random.randint(10,50, dummy_df.shape[0])
16dummy_df['y$_revenue'] = dummy_df['row_num'] * dummy_df['multiplier']
17df = dummy_df[['ds_day', 'y$_revenue']]
18
19# Helper function that formats values as $ or %
20def format(column):
21  if column.startswith('y$'):
22    return '$.3s'
23  elif column.startswith('y%'):
24    return '.0%'
25  else:
26    return '.3s'
27
28# Helper Function that removes underscores
29def column_name(column):
30  return column.split('_', 1)[1].replace('_',' ').title()
31
32# Helper function that determines the intended aggregation based on column name
33def aggregation(ds_col):
34  return ds_col.split('_', 1)[1].lower()
35
36# Check for in progress data, will exclude later
37def in_progress(dt, agg):
38  now = datetime.datetime.now()
39  if agg == 'hour':
40    return (now.year == dt.year and now.month == dt.month and now.day == dt.day and now.hour == dt.hour)
41  elif agg == 'day':
42    return (now.year == dt.year and now.month == dt.month and now.day == dt.day)
43  elif agg == 'week':
44    return (now.year == dt.year and now.isocalendar()[1] == dt.isocalendar()[1])
45  elif agg == 'month':
46    return (now.year == dt.year and now.month == dt.month)
47  elif agg == 'quarter':
48    return (now.year == dt.year and int(now.month / 4) == int(dt.month / 4))
49  elif agg == 'year':
50    return (now.year == dt.year)
51
52# Lowercase the column names
53df.columns = [c.lower() for c in df.columns]
54# Determine which is Y axis
55y_col = [c for c in df.columns if c.startswith('y')][0]
56# Determine which is X axis
57ds_col = [c for c in df.columns if c.startswith('ds')][0]
58# Determine what the aggregation is
59agg = aggregation(ds_col)
60
61# Data cleanup and in-progress analysis
62df['y'] = pd.to_numeric(df[y_col])
63df['y'], lam = boxcox(df['y'])
64df['ds'] = pd.to_datetime(df[ds_col])
65df['in_progress'] = df.apply(lambda x: in_progress(x['ds'], agg), axis=1)
66
67# Instantiate Prophet and fit the model
68m = Prophet()
69m.fit(df.query('in_progress == False')[['ds','y']])
70
71# Create the predictions dataframe that includes future dates
72if agg == 'hour':
73  future = m.make_future_dataframe(periods=72, freq='H')
74elif agg == 'day':
75    future = m.make_future_dataframe(periods=30)
76elif agg == 'week':
77  future = m.make_future_dataframe(periods=183)
78  future['day_diff'] = future.apply(lambda x: (df['ds'].max() - x['ds']).days, axis=1)
79  future = future[future['day_diff'] % 7 == 0]
80elif agg == 'month':
81  future = m.make_future_dataframe(periods=365)
82  future = future[future['ds'].dt.day == 1]
83elif agg == 'quarter':
84  future = m.make_future_dataframe(periods=365)
85  future = future[(future['ds'].dt.month % 3 == 1) & (future['ds'].dt.day == 1)]
86elif agg == 'year':
87  future = m.make_future_dataframe(periods=731)
88  future = future[(future['ds'].dt.month == 1) & (future['ds'].dt.day == 1)]
89
90# Predict the future
91forecast = m.predict(future)
92forecast[['yhat','yhat_upper','yhat_lower']] = forecast[['yhat','yhat_upper','yhat_lower']].apply(lambda x: inv_boxcox(x, lam))
93
94# Create the plotly figure
95yhat = go.Scatter(
96  x = forecast['ds'],
97  y = forecast['yhat'],
98  mode = 'lines',
99  marker = {
100    'color': '#3bbed7'
101  },
102  line = {
103    'width': 3
104  },
105  name = 'Forecast',
106)
107
108yhat_lower = go.Scatter(
109  x = forecast['ds'],
110  y = forecast['yhat_lower'],
111  marker = {
112    'color': 'rgba(0,0,0,0)'
113  },
114  showlegend = False,
115  hoverinfo = 'none',
116)
117
118yhat_upper = go.Scatter(
119  x = forecast['ds'],
120  y = forecast['yhat_upper'],
121  fill='tonexty',
122  fillcolor = 'rgba(231, 234, 241,.75)',
123  name = 'Confidence',
124  hoverinfo = 'none',
125  mode = 'none'
126)
127
128actual = go.Scatter(
129  x = df['ds'],
130  y = df[y_col],
131  mode = 'markers',
132  marker = {
133    'color': '#fffaef',
134    'size': 4,
135    'line': {
136      'color': '#000000',
137      'width': .75
138    }
139  },
140  name = 'Actual'
141)
142
143layout = go.Layout(
144  yaxis = {
145    'title': column_name(y_col),
146    'tickformat': format(y_col),
147    'hoverformat': format(y_col)
148  },
149  hovermode = 'x',
150  xaxis = {
151    'title': agg.title()
152  },
153  margin = {
154    't': 20,
155    'b': 50,
156    'l': 60,
157    'r': 10
158  },
159  legend = {
160    'bgcolor': 'rgba(0,0,0,0)'
161  }
162)
163data = [yhat_lower, yhat_upper, yhat, actual]
164
165fig = dict(data = data, layout = layout)
166periscope.plotly(fig)