问题
I got a very similar question to this one : Pandas graphing a timeseries, with vertical lines at selected dates but the solution doesn't works with Timedelta.
Consider this series:
In:
avg_hr.head()
Out:
00:00:00     69.000000
00:00:01     93.750000
00:00:02     93.125000
00:00:03     92.900000
00:00:04     93.222222
00:00:05     93.222222
...
Name: bpm, Length: 253, dtype: float64
I can select element in this series like this:
In:
avg_hr[pd.Timedelta(seconds=3)]
Out:
92.9
I can generate a graph like this:
In:
avg_hr.plot()
But, I can't plot vertical lines with TimeDelta like this:
In:
plt.axvline(x=pd.Timedelta(seconds=110), color='r', linestyle='dashed', linewidth=2)
Out:
TypeError: Cannot compare type 'Timedelta' with type 'float64'
Though, if I use a float or int, the vertical lines appear at position 0.
In:
plt.axvline(x=110, color='r', linestyle='dashed', linewidth=2)
How can I plot vertical lines using this timedelta index?
EDIT:
Even if I use directly the keys used on x-axis, I got the same error:
In:
for key in avg_hr.keys():
    ax.axvline(x=key, color='r', linestyle='dashed', linewidth=2)
Out:
TypeError: Cannot compare type 'Timedelta' with type 'float64'
    回答1:
I figured out that even if I work in seconds, and that the axis label show the time in second, it's in fact in nanoseconds!
From the documentation Pandas Time Deltas:
Pandas represents Timedeltas in nanosecond resolution using 64 bit integers
So, in the example of my question, when I called this, the vertical line was not at position 0, but in fact at position 110 nanoseconds (so very close to 0 with this scale):
plt.axvline(x=110, color='r', linestyle='dashed', linewidth=2)
The solution is simply to convert your x value in nanoseconds:
x_ns = pd.Timedelta(seconds=110) / pd.Timedelta(1,'ns') #Seconds to nanoseconds
plt.axvline(x=x_ns, color='r', linestyle='dashed', linewidth=2)
I found this when I tried to change the xlim, then I saw that everything was scale to nanoseconds. So, the same conversion needed to be applied to xlim.
ax1.set_xlim([0, 110])
The result with multiple verticals lines
Done with:
#Add verticals lines for specific event
plt.axvline(x=pd.Timedelta(seconds=120) / pd.Timedelta(1,'ns'), color='r', linestyle='dashed', linewidth=2)
plt.axvline(x=pd.Timedelta(seconds=185) / pd.Timedelta(1, 'ns'), color='r', linestyle='dashed', linewidth=2)
plt.axvline(x=pd.Timedelta(seconds=210) / pd.Timedelta(1, 'ns'), color='r', linestyle='dashed', linewidth=2)
plt.axvline(x=pd.Timedelta(seconds=225) / pd.Timedelta(1, 'ns'), color='r', linestyle='dashed', linewidth=2)
    回答2:
I have encountered a similar problem. The solution for the TimeDelta index I used was the total_seconds property which returns float in seconds. ("Total duration of timedelta in seconds (to ns precision)")
So,
plt.axvline(pd.Timedelta(seconds=120).total_seconds, color='r', linestyle='dashed', linewidth=2)
should do the trick.
来源:https://stackoverflow.com/questions/45242784/pandas-graphing-a-timedelta-series-with-vertical-lines-at-selected-time