2

I am plotting such data:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas as pd


a = pd.DatetimeIndex(start='2010-01-01',end='2011-06-01' , freq='M')
b = pd.Series(np.random.randn(len(a)), index=a)

I would like the plot to be in the format of bars, so I use this:

b.plot(kind='bar')

This is what I get:

enter image description here

As you can see, the dates are formatted in full, which is very ugly and unreadable. I happened to test this command which creates a very nice Date format:

b.plot()

As you can see: enter image description here

I like this format very much, it includes the months, marks the beginning of the year and is easily readable.

After doing some search, the closest I could get to that format is using this:

fig, ax = plt.subplots()
ax.plot(b.index, b)
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b'))

However the output looks like this: enter image description here

I am able to have month names on x axis this way, but I like the first formatting much more. That is much more elegant. Does anyone know how I can get the same exact xticks for my bar plot?

Moh
  • 1,887
  • 3
  • 18
  • 29
  • Does [this](http://stackoverflow.com/questions/5902371/matplotlib-bar-chart-with-dates) helps? – Nuageux May 20 '17 at 09:38
  • @Nuageux Thank you for your comment. That is a nice post, but is not exactly what I want. It would be great if I could add the year only every January, like the second figure. – Moh May 20 '17 at 09:44

1 Answers1

0

Here's a solution that will get you the format you're looking for. You can edit the tick labels directly, and use set_major_formatter() method:

fig, ax = plt.subplots()

ax.bar(b.index, b)

ticklabels = [item.strftime('%b') for item in b.index] #['']*len(b.index)
ticklabels[::12] = [item.strftime('%b\n%Y') for item in b.index[::12]]
ax.xaxis.set_major_formatter(matplotlib.ticker.FixedFormatter(ticklabels))
ax.set_xticks(b.index)
plt.gcf().autofmt_xdate()

Output: enter image description here

Andrew L
  • 6,618
  • 3
  • 26
  • 30