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

Kev*_* S. 17 python plot matplotlib pandas

我刚刚将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)
Run Code Online (Sandbox Code Playgroud)

但是在打电话时type(df.index[0]),0.17.1给出pandas.tslib.Timestamp,0.21.0给出pandas._libs.tslib.Timestamp.

当用df.indexx轴绘图时:

plt.plot(df.index, df['data'])
Run Code Online (Sandbox Code Playgroud)

默认情况下,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
Run Code Online (Sandbox Code Playgroud)

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

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

更新如上所述,我更喜欢直接plot使用给定的轴对象调用,但仅仅是为了它,我尝试调用DataFrame本身的plot方法df.plot().完成此操作后,所有后续绘图都会正确识别同一python会话中的时间戳.就像设置了一个环境变量一样,因为我可以重新加载另一个DataFrame或创建另一个轴,subplots而不1.5e18显示在哪里.这真的闻起来像一个臭虫,因为最新的熊猫医生说熊猫:

The plot method on Series and DataFrame is just a simple wrapper around plt.plot()
Run Code Online (Sandbox Code Playgroud)

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

实际上,只需在上面的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))
Run Code Online (Sandbox Code Playgroud)

根据是否ts.plot()调用,下图可以正确地将x轴格式化为日期:

plt.plot(ts.index,ts)
plt.show()
Run Code Online (Sandbox Code Playgroud)

一旦调用了成员图,随后调用plt.plot新的Series或DataFrame将自动进行自动格式化,而无需再次调用成员图方法.

Imp*_*est 14

pandas日期和matplotlib问题来自最近发布的pandas 0.21,它在导入时不再注册其转换器.一旦你使用这些转换器(在熊猫中),它们将被注册并由matplotlib自动使用.

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

import pandas.plotting._converter as pandacnv
pandacnv.register()
Run Code Online (Sandbox Code Playgroud)

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

更新:这不再是当前版本的matplotlib(2.2.2)/ pandas(0.23.1)的问题,并且很可能是自2017年12月左右发布以来已经发布的许多问题.

  • 截至2019年5月13日,此问题已返回。我正在使用matplotlib(3.0.3)和pandas(0.24.2)。显式注册转换器确实可以解决它。希望这可以长期解决。 (2认同)

Kev*_* S. 9

在pandas github上打开一个问题之后,我了解到这确实是pandas和matplotlib之间关于单位转换器自动注册的已知问题.事实上,它列在我之前未能看到的新页面上,以及注册转换器的正确方法:

from pandas.tseries import converter
converter.register() 
Run Code Online (Sandbox Code Playgroud)

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

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