【发布时间】:2018-05-04 10:02:18
【问题描述】:
我刚刚将 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 值在 0.17.1 时约为 736500(即自第 0 年以来的天数),但在 0.21.0 时约为 1.5e18(即纳秒纪元时间)。
我对 matplotlib 和 pandas 之间的兼容性中断感到惊讶,因为它们显然被大多数人一起使用。我在为较新版本调用上面的绘图函数的方式上是否遗漏了什么?
更新 如上所述,我更喜欢使用给定的轴对象直接调用plot,但只是为了它,我尝试调用 DataFrame 本身的 plot 方法df.plot()。完成此操作后,所有后续绘图都会正确识别时间戳在同一 python 会话中。就好像设置了一个环境变量,因为我可以重新加载另一个 DataFrame 或使用subplots 创建另一个轴,而1.5e18 没有出现在哪里。正如最新的 pandas 文档所说的 pandas,这真的闻起来像一个错误:
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()
一旦调用了成员 plot,随后在新系列或 DataFrame 上调用 plt.plot 将正确自动格式化,而无需再次调用成员 plot 方法。
【问题讨论】:
标签: python pandas matplotlib plot