Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom date range (x-axis) in time series with matplotlib

My code to plot a time series is this:

def plot_series(x, y):
    fig, ax = plt.subplots()
    ax.plot_date(x, y, fmt='g--') # x = array of dates, y = array of numbers

    fig.autofmt_xdate()
    plt.grid(True)
    plt.show()

I have a few thousand data points and so matplotlib creates x-axis range of 3 months. This is what my time series looks like right now:

enter image description here

However, I want a weekly/fortnightly series. How do I change the way matplotlib computes date ranges the x-axis, and since I have almost 1 year of data, how do I make sure all of it fits nicely in one single chart?

like image 739
KGo Avatar asked Feb 04 '26 01:02

KGo


1 Answers

To change the frequency of tickmarks on your x-axis, you have to set its locator.

To have tickmarks for every monday of every week, you can use the WeekdayLocator provided by the dates module of matplotlib.

(Untested code):

from matplotlib.dates import WeekdayLocator

def plot_series(x, y):
    fig, ax = plt.subplots()
    ax.plot_date(x, y, fmt='g--') # x = array of dates, y = array of numbers        

    fig.autofmt_xdate()

    # For tickmarks and ticklabels every week
    ax.xaxis.set_major_locator(WeekdayLocator(byweekday=MO))

    # For tickmarks and ticklabels every other week
    #ax.xaxis.set_major_locator(WeekdayLocator(byweekday=MO, interval=2))

    plt.grid(True)
    plt.show()

This may get a bit crowded on the x-axis when using only one plot, as this generates approximately 52 ticks.

One possible work-around to this is to have ticklabels for every n-th week (e.g. every 4th week), and only tickmarks (i.e. no ticklabels) for every week:

from matplotlib.dates import WeekdayLocator

def plot_series(x, y):
    fig, ax = plt.subplots()
    ax.plot_date(x, y, fmt='g--') # x = array of dates, y = array of numbers        

    fig.autofmt_xdate()

    # For tickmarks and ticklabels every fourth week
    ax.xaxis.set_major_locator(WeekdayLocator(byweekday=MO, interval=4))

    # For tickmarks (no ticklabel) every week
    ax.xaxis.set_minor_locator(WeekdayLocator(byweekday=MO))

    # Grid for both major and minor ticks
    plt.grid(True, which='both')
    plt.show()
like image 152
sodd Avatar answered Feb 12 '26 18:02

sodd