CadentOrange
CadentOrange

Reputation: 3343

Matplotlib x-axis labels alignment off

I'm trying to plot a chart with dates as the x-axis. This plots fine, but the tick marks do not line up with the data points.

from datetime import datetime
import pylab as p
from matplotlib.dates import date2num, num2date

scores = [
        (datetime.strptime("2013-08-07T14:00", "%Y-%m-%dT%H:%M"), 1280),
        (datetime.strptime("2013-08-07T15:00", "%Y-%m-%dT%H:%M"), 1272),
        (datetime.strptime("2013-08-07T16:00", "%Y-%m-%dT%H:%M"), 1252),
        (datetime.strptime("2013-08-07T17:00", "%Y-%m-%dT%H:%M"), 1293),
        (datetime.strptime("2013-08-07T18:00", "%Y-%m-%dT%H:%M"), 1258),
        (datetime.strptime("2013-08-07T19:00", "%Y-%m-%dT%H:%M"), 1240),
        (datetime.strptime("2013-08-07T20:00", "%Y-%m-%dT%H:%M"), 1287),
        (datetime.strptime("2013-08-07T21:00", "%Y-%m-%dT%H:%M"), 1241),
        (datetime.strptime("2013-08-07T22:00", "%Y-%m-%dT%H:%M"), 1286),
        (datetime.strptime("2013-08-07T23:00", "%Y-%m-%dT%H:%M"), 1237),
        (datetime.strptime("2013-08-08T00:00", "%Y-%m-%dT%H:%M"), 1269),
        (datetime.strptime("2013-08-08T01:00", "%Y-%m-%dT%H:%M"), 1269),
        (datetime.strptime("2013-08-08T02:00", "%Y-%m-%dT%H:%M"), 1258),
        (datetime.strptime("2013-08-08T03:00", "%Y-%m-%dT%H:%M"), 1259),
        (datetime.strptime("2013-08-08T04:00", "%Y-%m-%dT%H:%M"), 1265),
        (datetime.strptime("2013-08-08T05:00", "%Y-%m-%dT%H:%M"), 1225),
        (datetime.strptime("2013-08-08T06:00", "%Y-%m-%dT%H:%M"), 1251),
        (datetime.strptime("2013-08-08T07:00", "%Y-%m-%dT%H:%M"), 1297),
        (datetime.strptime("2013-08-08T08:00", "%Y-%m-%dT%H:%M"), 1244),
        (datetime.strptime("2013-08-08T09:00", "%Y-%m-%dT%H:%M"), 1283),
        (datetime.strptime("2013-08-08T10:00", "%Y-%m-%dT%H:%M"), 1253),
        (datetime.strptime("2013-08-08T11:00", "%Y-%m-%dT%H:%M"), 1305),
        (datetime.strptime("2013-08-08T12:00", "%Y-%m-%dT%H:%M"), 1284),
        (datetime.strptime("2013-08-08T13:00", "%Y-%m-%dT%H:%M"), 1318),
        (datetime.strptime("2013-08-08T14:00", "%Y-%m-%dT%H:%M"), 454),
    ]

if __name__ == "__main__":
    fig = p.figure()
    ax = fig.add_subplot(1,1,1)
    x = [date2num(date) for (date, value) in scores]
    y = [value for (date, value) in scores]
    ax.plot(x, y, 'r-x')
    ticks = [num2date(t) for t in x[0::4]]
    ax.set_xticklabels([t.strftime("%H:%M") for t in ticks], rotation="45")
    p.savefig("line_plot.png")

This produces the following graph as its output.

Sample output

The first data point should begin at 14:00, and it's appears to be 3 hours out. The spacing between data points appears to be correct, it's just that the start offset is off. Any ideas why it's doing this?

Update: Based on a comment that appears to have been removed, I had a look at the plot_date method which I managed to somehow miss... I've now changed the code to the following. This gives me a nice graph where the ticks are in the right place.

if __name__ == "__main__":
    fig = p.figure()
    ax = fig.add_subplot(1,1,1)
    x = [date2num(date) for (date, value) in scores]
    y = [value for (date, value) in scores]
    ax.plot_date(x, y, 'r-x')
    fig.autofmt_xdate()
    p.savefig("line_plot.png")

Upvotes: 1

Views: 2111

Answers (1)

Greg
Greg

Reputation: 12234

You have converting the x data to a series of floats which are understood by python's datetime module but when passing them into p.plot(x, y) it just sees a bunch of floats. You are then essentially setting labels arbitrarily.

You should use ax.plot_date(x, y, 'r-x') which accepts x as dates or the float representation. You'll need to remove your manual setting of the x labels to see this. Then see the docs for how to then custom format the x axis.

Upvotes: 1

Related Questions