How can i get matplotlib to correctly format these datetime64 objects?

57 views Asked by At

I'm trying to plot a horizontal bar chart in python of the following data:

table

Using the following code:

import matplotlib.pyplot as plt

plt.barh(subset['sources'], width=subset['repairDate'], left=subset['appearanceDate'])

but the output gives me the dates in the x-axis as some sort of integer.

first_chart

I tried to use a custom date formatter to maybe fix that but I honestly can't tell what went on behind the scenes there, it just multiplied the number of xticks dramatically and the labels themselves seem to still be integers:

fig, ax = plt.subplots(1, 1)

ax.barh(subset['sources'], width=subset['repairDate'], left=subset['appearanceDate'])
ax.xaxis.set_major_locator(mdates.YearLocator(1))
ax.xaxis.set_major_formatter(mdates.ConciseDateFormatter(ax.xaxis.get_major_locator()))
ax.set_xticklabels(ax.get_xticks(), rotation=90);

attempt 1

2

There are 2 answers

2
Jody Klymak On BEST ANSWER

You need the width to be deltas, which works fine with Matplotlib. However, barh doesn't trigger the datetime units machinery (which seems an oversight), so you need to do it manually:

import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
start = np.array([np.datetime64('2012-01-01'), np.datetime64('2012-02-01'), np.datetime64('2012-01-15')])
stop = np.array([np.datetime64('2012-02-07'), np.datetime64('2012-02-13'), np.datetime64('2012-02-12')])
# force x axis to be times:
l, = ax.plot(stop, [0, 1, 3], '.')
ax.barh([0,1, 3], width=stop-start, left=start)
l.remove()

Note I've used numpy.datetim64, but I think pandas timedeltas should work as well (I don't use pandas so can't really test easily).

1
minoizee On

If you have a look at the matplotlib documentation, you have to use syntax like this:

matplotlib.pyplot.barh(y, width, height=0.8, left=None,*,align='center',**kwargs)

rather than just using plt.barh