Several years ago I had problems plotting a bar chart without overlapping the date labels. I received an answer that worked.
Today I encountered the same situation, but that old solution won't work in my real example (it does continue to work in the toy example.) I cannot figure out the difference between my real example and the toy.
The toy index is a datetime64[ns]
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
'2017-01-05', '2017-01-06', '2017-01-07', '2017-01-08',
'2017-01-09', '2017-01-10', '2017-01-11', '2017-01-12',
'2017-01-13', '2017-01-14', '2017-01-15', '2017-01-16',
'2017-01-17', '2017-01-18', '2017-01-19', '2017-01-20',
'2017-01-21', '2017-01-22', '2017-01-23', '2017-01-24',
'2017-01-25', '2017-01-26', '2017-01-27', '2017-01-28',
'2017-01-29', '2017-01-30', '2017-01-31', '2017-02-01',
'2017-02-02', '2017-02-03', '2017-02-04', '2017-02-05',
'2017-02-06', '2017-02-07', '2017-02-08', '2017-02-09',
'2017-02-10', '2017-02-11'],
dtype='datetime64[ns]', freq=None)
which looks like my real index:
DatetimeIndex(['2011-01-01', '2011-02-01', '2011-03-01', '2011-04-01',
'2011-05-01', '2011-06-01', '2011-07-01', '2011-08-01',
'2011-09-01', '2011-10-01',
...
'2019-03-01', '2019-04-01', '2019-05-01', '2019-06-01',
'2019-07-01', '2019-08-01', '2019-09-01', '2019-10-01',
'2019-11-01', '2019-12-01'],
dtype='datetime64[ns]', name='date', length=108, freq=None)
The data in the problematic DataFrame is real numbers:
My code to generate the plot is almost verbatim to the toy example:
residuals = pd.DataFrame(overfit.predict(X_train)-y_train)
#https://stackoverflow.com/questions/49231052/datetime-x-axis-matplotlib-labels-causing-uncontrolled-overlap
#plt.bar(pd.to_datetime(residuals.index), residuals['efs'].values, ) # this has the same result as below
plt.bar(residuals.index, residuals['efs'], )
plt.gca().xaxis.set_major_locator(mdates.DayLocator((1,15)))
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%d %b %Y"))
plt.gcf().autofmt_xdate()
plt.title("foo")
plt.show()
But the result looks terrible -- the axes overlpap + lots of the data bars vanish:
This is the original answer toy code for comparison:
import pandas as pd
import numpy as np; np.random.seed(42)
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
datelist = pd.date_range(pd.datetime(2017, 1, 1).strftime('%Y-%m-%d'), periods=93).tolist()
df = pd.DataFrame(np.cumsum(np.random.randn(93)),
columns=['error'], index=pd.to_datetime(datelist))
plt.bar(df.index, df["error"].values)
plt.gca().xaxis.set_major_locator(mdates.DayLocator((1,15)))
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%d %b %Y"))
plt.gcf().autofmt_xdate()
plt.show()