Quastiat
Quastiat

Reputation: 1242

Seaborn Barplot Date Axis not formatable

enter image description here

How would one adjust the date formatting of a seaborn x axis? I usually use

ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y'))

but that throws an error

ValueError: DateFormatter found a value of x=0, which is an illegal date

despite the date data is correctly formatted as dtype='datetime64[ns]' and there are no 0 values.

The chart is created by

data = data.melt('Name', var_name='country', value_name='cpi')
data.set_index('Name',inplace=True)
fig, ax = plt.subplots(figsize=(10, 6), dpi=80)
ax = sns.barplot(x=data.index, y='cpi', hue='country', data=data, ax=ax)
fig.autofmt_xdate()

this is how the date axis data looks like:

data.index
Out[286]: 
DatetimeIndex(['2019-04-30', '2019-05-31', '2019-06-30', '2019-07-31',
               '2019-08-31', '2019-09-30', '2019-10-31', '2019-11-30',
               '2019-12-31', '2020-01-31', '2020-02-29', '2020-03-31',
               '2019-04-30', '2019-05-31', '2019-06-30', '2019-07-31',
               '2019-08-31', '2019-09-30', '2019-10-31', '2019-11-30',
               '2019-12-31', '2020-01-31', '2020-02-29', '2020-03-31',
               '2019-04-30', '2019-05-31', '2019-06-30', '2019-07-31',
               '2019-08-31', '2019-09-30', '2019-10-31', '2019-11-30',
               '2019-12-31', '2020-01-31', '2020-02-29', '2020-03-31',
               '2019-04-30', '2019-05-31', '2019-06-30', '2019-07-31',
               '2019-08-31', '2019-09-30', '2019-10-31', '2019-11-30',
               '2019-12-31', '2020-01-31', '2020-02-29', '2020-03-31',
               '2019-04-30', '2019-05-31', '2019-06-30', '2019-07-31',
               '2019-08-31', '2019-09-30', '2019-10-31', '2019-11-30',
               '2019-12-31', '2020-01-31', '2020-02-29', '2020-03-31',
               '2019-04-30', '2019-05-31', '2019-06-30', '2019-07-31',
               '2019-08-31', '2019-09-30', '2019-10-31', '2019-11-30',
               '2019-12-31', '2020-01-31', '2020-02-29', '2020-03-31'],
              dtype='datetime64[ns]', name='Name', freq=None)

Upvotes: 1

Views: 169

Answers (2)

mechanical_meat
mechanical_meat

Reputation: 169274

Your solution seems fine; I upvoted it.
If you want something a little less verbose you can do:

x_dates = data.index.strftime('%b %Y').sort_values().unique()
ax.set_xticklabels(labels=x_dates, rotation=45, ha='right')

With this you don't need the fig.autofmt_xdate() call.

Upvotes: 1

Quastiat
Quastiat

Reputation: 1242

Meanwhile I figured out a working solution using the following adjustment

    ax.set_xticklabels([datetime.strptime(t.get_text(), '%Y-%m-%dT%H:%M:%S.%f000').strftime('%b %Y') for t in ax.get_xticklabels()])

I don't think it's very pretty so if you have any more pythonic way of dealing with this please let me know.

Upvotes: 1

Related Questions