Search code examples
pythonpandasmatplotlibtimedelta

Formatting timedelta for axis in matplotlib


I don't understand how I use and format a timedelta axis properly in matplotlib.

For example, for the following code

import pandas as pd # for plot generation
import matplotlib.pyplot as plt

index = pd.timedelta_range(timedelta(days=0), timedelta(days=30), freq='H', closed='right')
s = pd.Series(range(0, 720), index=index)

fig, ax = plt.subplots(figsize=(5, 5))

s.plot(ax=ax)

I get the plot

enter image description here

But obviously, the tick positions and the labels are useless and not in a meaningful distance (e.g., one day). I could not find in documentation how to deal with timedelta. Related questions ([1] or [2]) describe how to format the string but don't seem to handle the ticks layout.

How can I specify the ticks and the labels? For example, major ticks to days, minor ticks to hours with a proper label?

I also wonder if there is a simple, clean, pythonic solution. I mean timedelta in plots isn't that rare, is it? :)


Solution

  • Here is a workaround. It doesn't change the label formatting but reduces the number of ticks and labels so at least you can see them.

    I figured out that the pandas TimeSeries_TimedeltaFormatter‎ is based on integers representing 1e-9 seconds.

    You can figure this out using the following:

    x_ticks = ax.get_xticks()
    print(x_ticks)
    

    Output:

    [0.0e+00 5.0e+14 1.0e+15 1.5e+15 2.0e+15 2.5e+15 3.0e+15]
    

    Big numbers!

    So let's say you want to reduce the number of ticks and labels to show only one every 15 days.

    Then use this:

    index = pd.timedelta_range(
        pd.Timedelta(days=0), 
        pd.Timedelta(days=30),
        freq='H', closed='right'
    )
    s = pd.Series(range(0, 720), index=index)
    
    fig, ax = plt.subplots(figsize=(5, 5))
    
    s.plot(ax=ax)
    
    one_day = 1e9 * 60 * 60 * 24
    ax.set_xticks(one_day * np.linspace(0, 30, 3))
    
    plt.tight_layout()
    plt.show()
    

    enter image description here