Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python pandas 0.21.0与matplotlib的时间戳兼容性问题_Python_Pandas_Matplotlib_Plot - Fatal编程技术网

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

Python pandas 0.21.0与matplotlib的时间戳兼容性问题,python,pandas,matplotlib,plot,Python,Pandas,Matplotlib,Plot,我刚刚将pandas从0.17.1更新到0.21.0,以利用一些新功能,并遇到了与matplotlib的兼容性问题(我还更新到了最新的2.1.0)。特别是,Timestamp对象似乎发生了显著的变化 我碰巧有另一台机器仍在运行pandas(0.17.1)/matplotlib(1.5.1)的旧版本,我用它来比较差异: 两个版本都将我的数据帧索引显示为dtype='datetime64[ns] DatetimeIndex(['2017-03-13', '2017-03-14', ... '2017

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

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

两个版本都将我的数据帧索引显示为
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.\u 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
我可以在调试中看到,对于0.17.1,报告的x值约为736500(即从0年开始的天数),但对于0.21.0,报告的x值约为1.5e18(即纳秒历元时间)

我很惊讶matplotlib和pandas之间兼容性的中断,因为它们显然被大多数人一起使用。对于较新版本,我调用上面的plot函数的方式是否遗漏了什么

Update如上所述,我更喜欢使用给定的Axis对象直接调用
plot
,但为了检查一下,我尝试调用数据帧本身的plot方法
df.plot()
。完成后,所有后续绘图都会正确识别同一python会话中的时间戳。就好像设置了一个环境变量,因为我可以重新加载另一个数据帧或使用
子批次创建另一个轴
,而
1.5e18
在哪里不显示。正如最新的熊猫博士所说,这闻起来真像一只虫子:

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

事实上,只需在上述链接上运行示例:

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()
调用成员plot后,随后调用新系列或数据帧上的
plt。plot
将自动正确格式化,无需再次调用成员plot方法。

最近发布的pandas 0.21中有一个版本,在导入时不再注册其转换器。一旦您使用这些转换器一次(在pandas中),它们也将被注册并自动由matplotlib使用

解决方法是手动注册它们

import pandas.plotting._converter as pandacnv
pandacnv.register()
无论如何,这个问题在pandas和matplotlib方面都是众所周知的,所以下一个版本将有一些修复。熊猫们正在考虑一个即将发布的版本。所以这个问题可能只是暂时的。还有一个选项是在不应出现这种情况的情况下恢复到0.20.x

更新:matplotlib(2.2.2)/pandas(0.23.1)的当前版本不再存在此问题,可能许多版本都是从2017年12月左右发布的,当时已修复此问题

更新2:从0.24或更高版本开始,建议使用以下方法注册转换器:

from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
或者,如果已将
pandas
作为
pd
导入

pd.plotting.register_matplotlib_converters()
在打开pandas github上的一个应用程序后,我了解到这确实是pandas和matplotlib之间关于单元转换器自动注册的一个已知的例子。事实上,它被列在我以前没有看到的新功能上,以及注册转换器的正确方法:

from pandas.tseries import converter
converter.register() 
这也是第一次在序列或数据帧上调用成员plot方法时完成的,这解释了我在上面观察到的情况


这样做的目的似乎是为了让matplotlib实现对pandas datetime的一些基本支持,但实际上,某种类型的弃用警告对于这种中断可能很有用。然而,在matplotlib真正实现这种支持(或某种延迟注册机制)之前,实际上我总是将这两行放在导入中。因此,我不确定pandas为什么要在matplotlib端准备就绪之前禁用导入时的自动注册。

看来matplotlib的未来版本已经解决了这个问题

尝试运行“pip安装--升级matplotlib”


我遇到了相同的问题“AttributeError:'numpy.datetime64'对象没有属性'toordinal'。升级matplotlib包时已修复。

没错,我在pandas github上打开的问题上也得到了类似的响应。我在熊猫网站上发布了一个稍微正式一点的方法,我已经尝试过了。你在这里也尝试过这个方法吗?你能报告它是否有效吗(理论上应该有效,但我无法尝试,如果无效,我最好删除答案)。我确实尝试过,但也有效——我最终使用了熊猫网站上的两行文字,因为它们更可能是未来的证明。这一问题已于2019年5月13日返回。我正在使用matplotlib(3.0.3)和pandas(0.24.2)。但是,显式注册转换器确实可以解决这个问题。希望这可以长期解决。@Ben是的,我用目前推荐的注册转换器的方法更新了答案。
from pandas.tseries import converter
converter.register()