pythonmatplotlibchartsdatetime64

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


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


Solution

  • 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).