Code Sample, a copy-pastable example if possible
import pandas as pd
import matplotlib.pyplot as plt
# make a time series
ind = pd.DatetimeIndex(start = '2010', end = '2011', freq='D')
s = pd.Series(data = 1.0, index = ind)
# plottling like this results in integer timestamps on the x-axis
fig, ax = plt.subplots()
ax.plot(s.index, s)
# calling ._mpl_repr() yields proper x-axis timestamps
fig, ax = plt.subplots()
ax.plot(s.index._mpl_repr(), s)
# the original plotting code still results in integer timestamps
fig, ax = plt.subplots()
ax.plot(s.index, s)
# calling the plot() method yields proper timestamps
fig, ax = plt.subplots()
s.plot()
# now the orignal code yields string timestamps!
fig, ax = plt.subplots()
ax.plot(s.index, s)
# now even a whole new series is plotted with string timestamps
ind2 = pd.DatetimeIndex(start = '2014', end = '2015', freq='D')
s2 = pd.Series(data = 2.0, index = ind2)
fig, ax = plt.subplots()
ax.plot(s2.index, s2)
Problem description
This bug appears to have been introduced in v.0.21.0, in my testing v.0.20.3 produced the expected behavior.
For a pandas series s
the code:
fig, ax = plt.subplots()
ax.plot(s.index, s)
produces a plot in which the x-labels are integer timestamps. With previous versions of pandas, this code would yield string timestamps on the x-axis.
However, s.plot()
works correctly, and once it is run, all subsequent plots made within the same kernel using the sytax
fig, ax = plt.subplots()
ax.plot(s.index, s)
work as expected with string timestamps.
A workaround is:
fig, ax = plt.subplots()
ax.plot(s.index._mpl_repr(), s)
but this doesn't affect subsequent plots.
Expected Output
The expected output of:
import pandas as pd
import matplotlib.pyplot as plt
# make a time series
ind = pd.DatetimeIndex(start = '2010', end = '2011', freq='D')
s = pd.Series(data = 1.0, index = ind)
# plottling like this results in integer timestamps on the x-axis
fig, ax = plt.subplots()
ax.plot(s.index, s)
is a plot with string representations of timestamps on the x-axis.
Output of pd.show_versions()
Comment From: gfyoung
cc @TomAugspurger
@mdeceglie : Thanks for reporting this! Do you think you could also post the actual graphs themselves as images in the issue for reference?
Comment From: TomAugspurger
See http://pandas.pydata.org/pandas-docs/stable/whatsnew.html#v0-21-0-october-27-2017 / https://github.com/pandas-dev/pandas/pull/17710 and https://matplotlib.org/faq/howto_faq.html#plot-numpy-datetime64-values
from pandas.tseries import converter
converter.register()
The Series.plot()
call checks whether the converter has been registered, and registers it if needed. That's why doing s.plot()
works and all later ones work as well. If you aren't using s.plot
, then you'll need to register it manually.
Sorry this is confusing, I'm hoping to move some of this over to matplotlib so that they have better formatting for datetime64
out of the box.
Comment From: mdeceglie
Thanks for the explanation @TomAugspurger.