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()

[paste the output of ``pd.show_versions()`` here below this line] INSTALLED VERSIONS ------------------ commit: None python: 2.7.14.final.0 python-bits: 64 OS: Darwin OS-release: 16.7.0 machine: x86_64 processor: i386 byteorder: little LC_ALL: en_US.UTF-8 LANG: en_US.UTF-8 LOCALE: None.None pandas: 0.21.0 pytest: 3.2.1 pip: 9.0.1 setuptools: 36.5.0.post20170921 Cython: 0.26.1 numpy: 1.13.3 scipy: 0.19.1 pyarrow: None xarray: None IPython: 5.4.1 sphinx: 1.6.3 patsy: 0.4.1 dateutil: 2.6.1 pytz: 2017.3 blosc: None bottleneck: 1.2.1 tables: 3.4.2 numexpr: 2.6.2 feather: None matplotlib: 2.1.0 openpyxl: 2.4.8 xlrd: 1.1.0 xlwt: 1.2.0 xlsxwriter: 1.0.2 lxml: 4.1.0 bs4: 4.6.0 html5lib: 0.999999999 sqlalchemy: 1.1.13 pymysql: None psycopg2: None jinja2: 2.9.6 s3fs: None fastparquet: None pandas_gbq: None pandas_datareader: None

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.