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

标签 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.时间戳

当使用 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 约为 1.5e18(即纳秒纪元时间)。

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

更新 正如我上面提到的,我更喜欢使用给定的轴对象直接调用 plot 但只是为了它,我尝试调用 DataFrame 的 plot 方法本身 df.plot()。完成此操作后,所有后续绘图都会在同一 python session 中正确识别时间戳 。就好像设置了一个环境变量,因为我可以重新加载另一个 DataFrame 或使用 subplots 创建另一个轴,而 1.5e18 不会出现在哪里。正如最新的 pandas 文档所说,这真的闻起来像一个错误 pandas :

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

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

事实上,只需运行上述 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()

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

最佳答案

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

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

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

无论如何,这个问题在 pandas 和 matplotlib 方面都是众所周知的,因此下一个版本将会有某种修复。 Pandas 在想readding the register在即将发布的版本中。所以这个问题可能只是暂时存在的。还可以选择恢复到不应发生这种情况的 pandas 0.20.x。

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

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

from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()

或者如果 pandas 已经导入为 pd

pd.plotting.register_matplotlib_converters()

关于python - pandas 0.21.0 时间戳与 matplotlib 的兼容性问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47404653/

相关文章:

python - numpy pandas 的构建轮失败

python - pandas:如何限制 str.contains 的结果?

python - Pandas 按总和分组仅保留索引之一作为列

python - 选择 matplotlib xticks 频率

python - 夹层的菜单页

python - python socket.sendall 成功返回是什么意思?

python - 如何在不必手动处理数据 block 的情况下散列大文件?

python - 将 URL 转换为 HTML 链接

python - 在墨卡托投影仪中在 map 上绘制数据看起来纬度翻转了 90 度

python - 如何绘制列中的某些值(子图)