pandas 0.21.0 时间戳与 matplotlib 的兼容性问题

2023-12-30

我刚刚将 pandas 从 0.17.1 更新到 0.21.0 以利用一些新功能,并遇到了与 matplotlib 的兼容性问题(我也将其更新到最新的 2.1.0)。特别是 Timestamp 对象似乎发生了重大变化。

我碰巧有另一台机器仍在运行旧版本的 pandas(0.17.1)/matplotlib(1.5.1),我用来比较差异:

两个版本都显示我的 DataFrame 索引是dtype='datetime64[ns]

DatetimeIndex(['2017-03-13', '2017-03-14', ... '2017-11-17'], type='datetime64[ns]', name='dates', length=170, freq=None)

但是打电话的时候type(df.index[0]), 0.17.1 给出pandas.tslib.Timestamp0.21.0 给出pandas._libs.tslib.Timestamp.

当绘图时df.index作为 x 轴:

plt.plot(df.index, df['data'])

matplotlibs 默认将 x 轴标签格式化为 pandas 0.17.1 的日期,但无法识别 pandas 0.21.0 的日期,并且仅给出原始数字1.5e18(纪元时间,以纳秒为单位)。

我还有一个自定义的光标,通过使用报告在图表上单击的位置matplotlib.dates.DateFormatter对于 0.21.0 失败的 x 值:

OverflowError: signed integer is greater than maximum

我可以在调试中看到,对于 0.17.1,报告的 x 值约为 736500(即自 0 年以来的天数),而对于 0.21.0,则约为 1.5e18(即纳秒纪元时间)。

我对 matplotlib 和 pandas 之间的兼容性中断感到惊讶,因为它们显然被大多数人一起使用。我在为新版本调用上面的绘图函数的方式中是否遗漏了一些东西?

Update正如我上面提到的,我更喜欢直接打电话plot使用给定的坐标区对象,但只是为了它,我尝试调用 DataFrame 本身的绘图方法df.plot()。完成此操作后,所有后续绘图都会正确识别时间戳在同一个 python 会话中。这就好像设置了一个环境变量,因为我可以重新加载另一个 DataFrame 或创建另一个轴subplots并且没有在哪里1.5e18出现。正如最新的 pandas 文档所说,这确实闻起来像一个错误pandas https://pandas.pydata.org/pandas-docs/stable/visualization.html#basic-plotting-plot:

The plot method on Series and DataFrame is just a simple wrapper around plt.plot()

但显然它对 python 会话做了一些事情,以便后续的绘图正确处理时间戳索引。

事实上,只需运行上面的 pandas 链接中的示例即可:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))

取决于是否ts.plot()无论是否被调用,下面的图要么正确地将 x 轴格式设置为日期,要么不正确:

plt.plot(ts.index,ts)
plt.show()

一旦调用成员图,随后调用plt.plot新的 Series 或 DataFrame 将正确自动格式化,无需再次调用成员绘图方法。


有一个pandas 日期时间和 matplotlib 的问题 https://github.com/matplotlib/matplotlib/issues/9610来自最近发布的 pandas 0.21,它不再在导入时注册其转换器。一旦您使用这些转换器一次(在 pandas 内),它们也会被 matplotlib 注册并自动使用。

解决方法是手动注册它们,

import pandas.plotting._converter as pandacnv
pandacnv.register()

无论如何,这个问题在 pandas 和 matplotlib 方面都是众所周知的,因此下一个版本将会有某种修复。熊猫正在思考读取寄存器 https://github.com/pandas-dev/pandas/issues/18301在即将发布的版本中。所以这个问题可能只是暂时存在。还可以选择恢复到 pandas 0.20.x,这样就不会发生这种情况。

Update:对于当前版本的 matplotlib (2.2.2)/pandas(0.23.1) 来说,这不再是问题,而且可能自 2017 年 12 月左右发布以来,许多版本都已修复此问题。

更新2:从 pandas 0.24 或更高版本开始,注册转换器的推荐方法是

from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()

or if pandas已经导入为pd,

pd.plotting.register_matplotlib_converters()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

pandas 0.21.0 时间戳与 matplotlib 的兼容性问题 的相关文章

随机推荐