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

时间:2017-11-21 03:22:44

标签: python pandas matplotlib plot

我刚刚将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.Timestamp,而0.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(以纳秒为单位的纪元时间)。

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

OverflowError: signed integer is greater than maximum

我可以在调试中看到,报告的x值约为736500(即自0年以来的日数)为0.17.1,但约为1.5e18(即纳秒时间段)为0.21.0。

我对matplotlib和熊猫之间的兼容性中断感到惊讶,因为它们显然是大多数人一起使用的。我是否错过了上面为新版本调用上述情节函数的方法?

如上所述

更新,我更喜欢直接使用给定的轴对象调用plot,但仅仅是为了它,我尝试调用DataFrame本身的绘图方法{{ 1}}。完成此操作后,所有后续绘图都会正确识别同一个python会话中的Timestamp 。就像设置了一个环境变量一样,因为我可以重新加载另一个DataFrame或用df.plot()创建另一个轴,而subplots没有出现在哪里。这真的闻起来像一个臭虫,因为最新的熊猫文档说pandas

1.5e18

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

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

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

根据是否调用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)) ,以下图表正确地将x轴格式化为日期:

ts.plot()

调用成员图后,随后在新系列或DataFrame上调用plt.plot(ts.index,ts) plt.show() 将自动格式化,无需再次调用成员绘图方法。

3 个答案:

答案 0 :(得分:14)

最近发布的pandas 0.21有一个issue with pandas datetimes and matplotlib,它在导入时不再注册其转换器。一旦你使用这些转换器(在熊猫中),它们就会被matplotlib注册并自动使用。

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

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

无论如何,这个问题在pandas和matplotlib方面都是众所周知的,因此对于下一个版本会有一些修复。熊猫正在考虑readding the register在一个上升的版本中。所以这个问题可能只是暂时存在。一个选项也是恢复到pandas 0.20.x,这不应该发生。

更新:这不再是当前版本的matplotlib(2.2.2)/ pandas(0.23.1)的问题,可能还有很多自2017年12月左右发布以来已修复的版本。

答案 1 :(得分:8)

在pandas github上打开issue之后,我了解到这确实是pandas和matplotlib之间关于单位转换器自动注册的已知issue。实际上,它列在我之前未见过的新page内,以及注册转换器的正确方法:

from pandas.tseries import converter
converter.register() 

第一次在Series或DataFrame上调用成员绘图方法时也会这样做,这解释了我在上面观察到的内容。

似乎已经完成了matplotlib应该为pandas datetime实现一些基本支持的意图,但实际上某种类型的弃用警告对于这样的中断可能是有用的。然而,直到matplotlib实际上实现了这种支持(或某种惰性注册机制),实际上我总是将这两行放在pandas导入中。所以我不确定为什么pandas会想要在matplotlib方面准备就绪之前禁用导入时的自动注册。

答案 2 :(得分:0)

看起来这个问题已经在 matplotlib 的未来版本中修复了。

尝试运行“pip install --upgrade matplotlib”。

我遇到了同样的问题“AttributeError: 'numpy.datetime64' object has no attribute 'toordinal'”。升级包 matplotlib 时已修复。