当我使用matplotlib的DateFormatter格式化x轴上的日期时,为什么我的"python int太大而无法转换为C long"错误?

Mic*_*l A 6 python matplotlib python-3.x pandas

这个答案使用DateFormatter后,我尝试使用pandas 0.15.0和matplotlib 1.4.2绘制时间序列并用x年标记其x轴:

import datetime as dt
import matplotlib as mpl
import matplotlib.pyplot as plt
import pandas.io.data as pdio
import scipy as sp

t1 = dt.datetime(1960, 1, 1)
t2 = dt.datetime(2014, 6, 1)
data = pdio.DataReader("GS10", "fred", t1, t2).resample("Q", how=sp.mean)

fig, ax1 = plt.subplots()
ax1.plot(data.index, data.GS10)
ax1.set_xlabel("Year")
ax1.set_ylabel("Rate (%)")
ax1.xaxis.set_major_formatter(mpl.dates.DateFormatter("%Y"))
fig.suptitle("10-yr Treasury Rate", fontsize=14)

fig.savefig('test.eps')
Run Code Online (Sandbox Code Playgroud)

最后一行引发错误:OverflowError: Python int too large to convert to C long 使用此回溯:

C:\ Anaconda3\lib\site-packages\IPython\core\formatters.py:239:FormatterWarning:image/png格式化程序中的异常:Python int太大而无法转换为C long FormatterWarning,Traceback(最近一次调用最后一次):

文件"",第1行,在runfile中('D:/username/latex_template/new_pandas_example.py',wdir ='D:/ username/latex_template')

文件"C:\ Anaconda3\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py",第580行,在runfile execfile(filename,namespace)中

文件"C:\ Anaconda3\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py",第48行,在execfile exec中(编译(open(filename,'rb').read(),filename,'e​​xec '),命名空间)

文件"D:/username/latex_template/new_pandas_example.py",第18行,在fig.savefig('test.eps')中

文件"C:\ Anaconda3\lib\site-packages\matplotlib\figure.py",第1470行,保存为self.canvas.print_figure(*args,**kwargs)

文件"C:\ Anaconda3\lib\site-packages\matplotlib\backend_bases.py",第2194行,print_figure**kwargs)

print_eps中的文件"C:\ Anaconda3\lib\site-packages\matplotlib\backends\backend_ps.py",第992行返回self._print_ps(outfile,'eps',*args,**kwargs)

文件"C:\ Anaconda3\lib\site-packages\matplotlib\backends\backend_ps.py",第1020行,在_print_ps**kwargs)

文件"C:\ Anaconda3\lib\site-packages\matplotlib\backends\backend_ps.py",第1110行,在_print_figure self.figure.draw(renderer)中

文件"C:\ Anaconda3\lib\site-packages\matplotlib\artist.py",第59行,在draw_wrapper中绘制(艺术家,渲染器,*args,**kwargs)

文件"C:\ Anaconda3\lib\site-packages\matplotlib\figure.py",第1079行,在draw func(*args)中

文件"C:\ Anaconda3\lib\site-packages\matplotlib\artist.py",第59行,在draw_wrapper中绘制(艺术家,渲染器,*args,**kwargs)

文件"C:\ Anaconda3\lib\site-packages\matplotlib\axes_base.py",第2092行,在draw a.draw(渲染器)中

文件"C:\ Anaconda3\lib\site-packages\matplotlib\artist.py",第59行,在draw_wrapper中绘制(艺术家,渲染器,*args,**kwargs)

文件"C:\ Anaconda3\lib\site-packages\matplotlib\axis.py",第1114行,在绘图中ticks_to_draw = self._update_ticks(渲染器)

文件"C:\ Anaconda3\lib\site-packages\matplotlib\axis.py",第957行,在_update_ticks中tick_tups = [t for self in self.iter_ticks()]

文件"C:\ Anaconda3\lib\site-packages\matplotlib\axis.py",第957行,在tick_tups = [t for self in self.iter_ticks()]

文件"C:\ Anaconda3\lib\site-packages\matplotlib\axis.py",第905行,iter_ticks为i,val为枚举(majorLocs)]

文件"C:\ Anaconda3\lib\site-packages\matplotlib\axis.py",第905行,in for i,val in enumerate(majorLocs)]

文件"C:\ Anaconda3\lib\site-packages\matplotlib\dates.py",第411行,调用 dt = num2date(x,self.tz)

文件"C:\ Anaconda3\lib\site-packages\matplotlib\dates.py",第345行,在num2date中返回_from_ordinalf(x,tz)

文件"C:\ Anaconda3\lib\site-packages\matplotlib\dates.py",第225行,在_from_ordinalf dt = datetime.datetime.fromordinal(ix)

OverflowError:Python int太大而无法转换为C long

DateFormatter在这里使用不正确吗?我怎样才能轻松地在matplotlib图的a轴上放置年(或任何时间格式,因为我的时间序列可能不同)?

jor*_*ris 11

这是pandas 0.15中的"回归"(由于Index的重构),请参阅https://github.com/matplotlib/matplotlib/issues/3727https://github.com/pydata/pandas/issues/8614,但固定在0.15.1.


简短的说明:matplotlib现在将pandas索引视为一个datetime64[ns]值数组(实际上是非常大的int64),而不是在以前版本的pandas中的Timestamps数组(它们是datetime.datetime的子类,并且可以由matplotlib处理) .因此,潜在的原因是matplotlib不会将datetime64作为日期值处理,而是作为整数处理.

对于pandas 0.15.0(但更好地升级到更新版本),有两种可能的解决方法:

  • 注册datetime64类型,因此它也将被matplotlib作为日期处理:

    units.registry[np.datetime64] = pd.tseries.converter.DatetimeConverter()
    
    Run Code Online (Sandbox Code Playgroud)
  • 或者datetime.datetime使用该to_pydatetime方法将DatetimeIndex(使用datetime64值)转换为值数组,并绘制以下内容:

    ax1.plot(data.index.to_pydatetime(), data.GS10)
    
    Run Code Online (Sandbox Code Playgroud)

相关问题:使用matplotlib在x轴上绘制datetimeindex会在pandas 0.15中创建错误的刻度,与0.14相比