Matplotlib DateFormatter for axis label not working Matplotlib DateFormatter for axis label not working pandas pandas

Matplotlib DateFormatter for axis label not working


pandas just doesn't work well with custom date-time formats.

You need to just use raw matplotlib in cases like this.

import numpyimport matplotlib.pyplot as pltimport matplotlib.dates as mdatesimport pandasN = 20numpy.random.seed(N)dates = pandas.date_range('1/1/2014', periods=N, freq='m')df = pandas.DataFrame(    data=numpy.random.randn(N),     index=dates,    columns=['A'])fig, ax = plt.subplots(figsize=(10, 6))ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))ax.bar(df.index, df['A'], width=25, align='center')

And that gives me:

enter image description here


I stepped into the same problem and I used an workaround to transform the index from date time format into the desired string format:

import numpy as npimport matplotlib.dates as mdatesimport matplotlib.pyplot as pltimport pandas as pdrng = pd.date_range('1/1/2014', periods=20, freq='m')blah = pd.DataFrame(data = np.random.randn(len(rng)), index=rng)fig = plt.figure(figsize = (10,6))ax = fig.add_subplot(111)# transform index to stringsblah_test = blah.copy()str_index = []for s_year,s_month in zip(blah.index.year.values,blah.index.month.values):    # build string accorind to format "%Y-%m"    string_day = '{}-{:02d}'.format(s_year,s_month)    str_index.append(string_day)blah_test.index = str_indexblah_test.plot(ax=ax, kind='bar', rot=45)plt.show()

which results in the following figure:figure with labels formatted correctly


Solution with pandas only

You can create nicely formatted ticks by using the DatetimeIndex and taking advantage of the datetime properties of the timestamps. Tick locators and formatters from matplotlib.dates are not necessary for a case like this unless you would want dynamic ticks when using the interactive interface of matplotlib for zooming in and out (more relevant for time ranges longer than in this example).

import numpy as np   # v 1.19.2import pandas as pd  # v 1.1.3# Create sample time series with month start frequency, plot it with a pandas bar chartrng = np.random.default_rng(seed=1) # random number generatordti = pd.date_range('1/1/2014', periods=20, freq='m')df = pd.DataFrame(data=rng.normal(size=dti.size), index=dti)ax = df.plot.bar(figsize=(10,4), legend=None)# Set major ticks and tick labelsax.set_xticks(range(df.index.size))ax.set_xticklabels([ts.strftime('%b\n%Y') if ts.year != df.index[idx-1].year                    else ts.strftime('%b') for idx, ts in enumerate(df.index)])ax.figure.autofmt_xdate(rotation=0, ha='center');

pd_bar_chart_date_ticks