【问题标题】:Pandas graphing a Timedelta series, with vertical lines at selected timePandas 绘制 Timedelta 系列,在选定时间用垂直线绘制
【发布时间】:2017-07-21 16:44:57
【问题描述】:

我有一个与这个问题非常相似的问题:Pandas graphing a timeseries, with vertical lines at selected dates,但该解决方案不适用于 Timedelta。

考虑这个系列:

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

我可以像这样选择这个系列中的元素:

In:
avg_hr[pd.Timedelta(seconds=3)]

Out:
92.9

我可以生成这样的图表:

In:
avg_hr.plot()

但是,我不能像这样用 TimeDelta 绘制垂直线:

In:
plt.axvline(x=pd.Timedelta(seconds=110), color='r', linestyle='dashed', linewidth=2)

Out:
TypeError: Cannot compare type 'Timedelta' with type 'float64'

不过,如果我使用浮点数或整数,垂直线会出现在位置 0。

In:
plt.axvline(x=110, color='r', linestyle='dashed', linewidth=2)

如何使用这个 timedelta 索引绘制垂直线?

编辑:

即使我直接使用 x 轴上使用的键,我也会遇到同样的错误:

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'

【问题讨论】:

  • avg_hr.index.dtype 返回什么?
  • @Vinícius Aguiar:输出:timedelta64[ns]

标签: python pandas matplotlib timedelta


【解决方案1】:

我发现即使我以秒为单位工作,并且轴标签以秒为单位显示时间,实际上也是以纳秒为单位!

来自文档Pandas Time Deltas

Pandas 表示使用 64 位的纳秒分辨率的 Timedeltas 整数

因此,在我的问题示例中,当我调用它时,垂直线不在位置 0,而是实际上在 110 纳秒的位置(在这个比例下非常接近 0):

plt.axvline(x=110, color='r', linestyle='dashed', linewidth=2)

解决方案只需将 x 值转换为纳秒:

x_ns = pd.Timedelta(seconds=110) / pd.Timedelta(1,'ns') #Seconds to nanoseconds
plt.axvline(x=x_ns, color='r', linestyle='dashed', linewidth=2)

我在尝试更改 xlim 时发现了这一点,然后我发现一切都在纳秒级。因此,需要对 xlim 应用相同的转换。

ax1.set_xlim([0, 110])

结果多条垂直线

完成:

#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)

【讨论】:

  • 真的很整洁,你可以改,重新格式化你的数据框,似乎avg_hr = pd.DataFrame({'data':pd.Series(np.random.randn(240)).cumsum(),'time': pd.to_timedelta(np.arange(240), unit='s')}) ; avg_hr.plot() ; plt.axvline(x=110,color='r', linestyle='dashed', linewidth=2) ; plt.show() 效果很好。
【解决方案2】:

我也遇到过类似的问题。我使用的 TimeDelta 索引的解决方案是 total_seconds 属性,它以秒为单位返回浮点数。 ("timedelta 的总持续时间,以秒为单位(精度为 ns)")

所以,

plt.axvline(pd.Timedelta(seconds=120).total_seconds, color='r', linestyle='dashed', linewidth=2)

应该可以解决问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-03
    • 2013-10-13
    • 2014-02-24
    • 2021-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多