How to scale the x-axis (in datetime format) of dataframes graphs to the same scale ? Python Pandas

Viewed 183

I have several dataframe graphics on a single figure. The X axis is a timestamp in the format: dd/mm/yy HH:MM:SS

The problem is that the time axis is not on the same scale and I can't put them on the same scale. I tried this but it doesn't work:

df1:

Timestamp,Value
2018-11-13 00:26:43.267725,68.9999980926514
2018-11-13 00:26:52.194564,488.389312744141
2018-11-13 00:26:52.479555,549.0
2018-11-13 00:27:11.812900,535.6854553222661
2018-11-13 00:27:12.080380,549.0
2018-11-13 00:27:12.348114,509.51171875
2018-11-13 00:27:20.346217,47.54024255275726
2018-11-13 00:28:39.572289,68.9999980926514
2018-11-13 00:28:46.264423,86.6078643798828
2018-11-13 00:28:50.782171,549.0
2018-11-13 00:29:12.807073,68.9999980926514


df2:

Timestamp,Value
2018-12-10 20:22:30.088260,120.8003616333008
2018-12-10 20:22:31.893382,549.0
2018-12-10 20:22:49.872620,478.66650390625
2018-12-10 20:22:50.129706,427.010375976562
2018-12-10 20:22:50.437430,353.003936767578
2018-12-10 20:22:50.762730,277.003540039062
2018-12-10 20:22:51.081120,232.50846862793
2018-12-10 20:22:51.338931,198.633895874023
2018-12-10 20:22:51.677225,164.06259918212902
2018-12-10 20:22:52.002505,147.7807312011719

cols = 1
rows = 2

nb_figs = rows

# create the figure with multiple axes
fig, axes = plt.subplots(nrows=rows, ncols=cols, figsize=(10, 13))

ax = df1.plot(x='Timestamp', y='Value', ax=axes[0])
xlocator = mdates.SecondLocator(interval = 15)
ax.xaxis.set_major_locator(xlocator)
ax.xaxis.set_major_formatter(mdates.DateFormatter('%d/%m/%y %H:%M:%S'))

ax = df2.plot(x='Timestamp', y='Value', ax=axes[1])
xlocator = mdates.SecondLocator(interval = 15)
ax.xaxis.set_major_locator(xlocator)
ax.xaxis.set_major_formatter(mdates.DateFormatter('%d/%m/%y %H:%M:%S'))

The result is:

enter image description here

I want the two plots to span the same duration (say 20 minutes), not necessarily show the same time interval? Am I missing a parameter? Or do I need another method?

1 Answers

You can take the view interval of both Axes and enlarge the smaller one to match the bigger, then set the new interval around its center:

fig, axes = plt.subplots(nrows=2, figsize=(10, 8), layout='constrained')

ax1 = df1.plot(x='Timestamp', y='Value', ax=axes[0])
xlocator = mdates.SecondLocator(interval = 15)
ax1.xaxis.set_major_locator(xlocator)
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%d/%m/%y %H:%M:%S'))

ax2 = df2.plot(x='Timestamp', y='Value', ax=axes[1])
xlocator = mdates.SecondLocator(interval = 15)
ax2.xaxis.set_major_locator(xlocator)
ax2.xaxis.set_major_formatter(mdates.DateFormatter('%d/%m/%y %H:%M:%S'))

vi1 = ax1.xaxis.get_view_interval()
vi2 = ax2.xaxis.get_view_interval()
if vi1.ptp() > vi2.ptp():
    ax2.set_xlim(vi2.mean() - vi1.ptp() / 2, vi2.mean() + vi1.ptp() / 2)
else:
    ax1.set_xlim(vi1.mean() - vi2.ptp() / 2, vi1.mean() + vi2.ptp() / 2)

enter image description here

Instead of get_view_interval() you could also use get_xlim() but the former has the advantage that it returns the interval as a numpy array that makes the calculation of the new interval a bit easier.


If you don't want to center but both data start at the left edge, you can simply use:
if vi1.ptp() > vi2.ptp():
    ax2.set_xlim(vi2[0], vi2[0] + vi1.ptp())
else:
    ax1.set_xlim(vi1[0], vi1[0] + vi2.ptp())
Related