Working environment:
python 3.7.3, fbprophet 0.5(from conda-forge), pystan 2.19.0, matplotlib 3.1.0 (same error with 3.1.1), numpy 1.16.4, MSYS2 gcc 5.3.0
As to the example:
import pandas as pd
from fbprophet import Prophet
df = pd.read_csv('./example_wp_log_peyton_manning.csv')
df.head()
cell result:
ds | y
-- | --
2007-12-10 | 9.590761
2007-12-11 | 8.519590
2007-12-12 | 8.183677
2007-12-13 | 8.072467
2007-12-14 | 7.893572
m = Prophet()
m.fit(df)
future = m.make_future_dataframe(periods=365)
future.tail()
forecast = m.predict(future)
forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()
cell result:
| ds | yhat | yhat_lower | yhat_upper
-- | -- | -- | -- | --
2017-01-15 | 8.203217 | 7.478939 | 8.893915
2017-01-16 | 8.528203 | 7.785464 | 9.198106
2017-01-17 | 8.315601 | 7.575644 | 9.032620
2017-01-18 | 8.148207 | 7.424915 | 8.832926
2017-01-19 | 8.160103 | 7.410152 | 8.832044
forecast['ds'] = pd.to_datetime(forecast['ds'])
fig1 = m.plot(forecast)
TypeError Traceback (most recent call last)
----> 1 fig1 = m.plot(forecast)
d:\Miniconda3\envs\tsa37\lib\site-packages\fbprophet\forecaster.py in plot(self, fcst, ax, uncertainty, plot_cap, xlabel, ylabel)
1520 return plot(
1521 m=self, fcst=fcst, ax=ax, uncertainty=uncertainty,
-> 1522 plot_cap=plot_cap, xlabel=xlabel, ylabel=ylabel,
1523 )
1524
d:\Miniconda3\envs\tsa37\lib\site-packages\fbprophet\plot.py in plot(m, fcst, ax, uncertainty, plot_cap, xlabel, ylabel, figsize)
68 fig = ax.get_figure()
69 fcst_t = fcst['ds'].dt.to_pydatetime()
---> 70 ax.plot(m.history['ds'].dt.to_pydatetime(), m.history['y'], 'k.')
71 ax.plot(fcst_t, fcst['yhat'], ls='-', c='#0072B2')
72 if 'cap' in fcst and plot_cap:
d:\Miniconda3\envs\tsa37\lib\site-packages\matplotlib\axes_axes.py in plot(self, scalex, scaley, data, args, *kwargs)
1666 lines = [self._get_lines(args, data=data, **kwargs)]
1667 for line in lines:
-> 1668 self.add_line(line)
1669 self.autoscale_view(scalex=scalex, scaley=scaley)
1670 return lines
TypeError: float() argument must be a string or a number, not 'datetime.datetime'
After lots of testing, I found the solution is :
Step 1:
from matplotlib.dates import date2num
import matplotlib.dates as mdates
Step 2 : In plot() function, use date2num convert the datetime64 object to number,
fcst_t = date2num(fcst['ds'].dt.to_pydatetime())
ax.plot(date2num(m.history['ds'].dt.to_pydatetime()), m.history['y'], 'k.', label='y')
Step 3 : Set the format
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m/%d/%Y'))
plt.gca().xaxis.set_major_locator(mdates.DayLocator())
Other methods in plot.py need to do the same work. This method is not fully test.
I meet the same error, I have found a solution: add thispd.plotting.register_matplotlib_converters()
However!I got two pictures every time I plot only once.
pd.plotting.register_matplotlib_converters()
...
my_fig = m.plot(forecast)
Doing an assignment helps preventing duplicated plot.
hm I'm not able to reproduce this error, with the same versions of numpy (1.16.4) and matplotlib (3.1.0). Could you see if this simpler code produces the error? It should be equivalent to what is done in Prophet.plot.
import pandas as pd
from matplotlib import pyplot as plt
df = pd.DataFrame({
'ds': pd.to_datetime([
'2001-01-01',
'2001-01-02',
'2001-01-03',
]),
'y': [1., 2., 1.],
})
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(df['ds'].dt.to_pydatetime(), df['y'], 'k.')
plt.show()
Registering the pandas converter will have it uses pandas to plot the datetimes instead of matplotlib's built-in datetime plotter. But matplotlib's built-in datetime plotter should work. Can you run this command to see how matplotlib is handling datetime plotting?
import matplotlib.units as munits
print(munits.registry)
# mine: {<class 'str'>: <matplotlib.category.StrCategoryConverter object at 0x7f189465e6d8>, <class 'numpy.str_'>: <matplotlib.category.StrCategoryConverter object at 0x7f189465e710>, <class 'bytes'>: <matplotlib.category.StrCategoryConverter object at 0x7f189465e748>, <class 'numpy.bytes_'>: <matplotlib.category.StrCategoryConverter object at 0x7f189465e780>, <class 'datetime.datetime'>: <matplotlib.dates.DateConverter object at 0x7f189bd6dc88>, <class 'datetime.date'>: <matplotlib.dates.DateConverter object at 0x7f189bd6dc50>, <class 'numpy.datetime64'>: <matplotlib.dates.DateConverter object at 0x7f189bd6dc18>}
import pandas as pd
from fbprophet import Prophet
df = pd.read_csv('./example_wp_log_peyton_manning.csv')
df.head()
m = Prophet()
m.fit(df)
future = m.make_future_dataframe(periods=365)
future.tail()
forecast = m.predict(future)
forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()
forecast['ds'] = pd.to_datetime(forecast['ds'])
pd.plotting.register_matplotlib_converters()
fig1 = m.plot(forecast)
Above code works well with python=3.7.3, numpy=1.17, matplotlib=3.1.1, fbphrohet=0.5, pystan=2.19, spyder=3.3.6, pandas=0.25.0
To bletham ,
import pandas as pd
from matplotlib import pyplot as plt
df = pd.DataFrame({
'ds': pd.to_datetime([
'2001-01-01',
'2001-01-02',
'2001-01-03',
]),
'y': [1., 2., 1.],
})
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(df['ds'].dt.to_pydatetime(), df['y'], 'k.')
plt.show()
With the new env: python=3.7.3, numpy=1.17, pandas=0.25.0, matplotlib=3.1.1, fbphrohet=0.5, pystan=2.19, spyder=3.3.6
Above code will cause an warning, advice us to use the new register.
Warning is:
d:\Miniconda3\envs\tsa37\lib\site-packages\pandas\plotting_matplotlib\converter.py:102: FutureWarning: Using an implicitly registered datetime converter for a matplotlib plotting method. The converter was registered by pandas on import. Future versions of pandas will require you to explicitly register matplotlib converters.
To register the converters:
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
warnings.warn(msg, FutureWarning)
It seems a small problem.
Most helpful comment
I meet the same error, I have found a solution: add this
pd.plotting.register_matplotlib_converters()However!I got two pictures every time I plot only once.