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
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? :)
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()