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


问题内容

遵循此答案对DateFormatter的使用之后,我尝试使用pandas
0.15.0和matplotlib 1.4.2绘制时间序列并用年份标记其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')

最后一行抛出一个错误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’)

运行文件execfile中的文件“ C:\ Anaconda3 \ lib \ site-packages \ spyderlib \ widgets
\ externalshell \ sitecustomize.py”,行580(文件名,名称空间)

文件“ C:\ Anaconda3 \ lib \ site-packages \ spyderlib \ widgets \
externalshell \ sitecustomize.py”,第48行,位于execfile
exec(compile(open(filename,’rb’)。read(),filename,’e​​xec ‘),名称空间)

图savefig(’test.eps’)中的文件“
D:/username/latex_template/new_pandas_example.py”,第18行

在savefig self.canvas.print_figure( args,* kwargs)中的文件“ C:\ Anaconda3 \ lib
\ site-packages \ matplotlib \ figure.py”,行1470

文件“ C:\ Anaconda3 \ lib \ site-packages \ matplotlib \
backend_bases.py”,行2194,在print_figure ** kwargs中)

文件“ C:\ Anaconda3 \ lib \ site-packages \ matplotlib \ backends \
backend_ps.py”在print_eps中返回self._print_ps(outfile,’eps’, args,* kwargs)

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

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

文件“ C:\ Anaconda3 \ lib \ site-packages \ matplotlib \
artist.py”,行59,位于draw_wrapper绘图(艺术家,渲染器, args,* kwargs)中

画图函数(* args)中的文件“ C:\ Anaconda3 \ lib \ site-packages \ matplotlib \
figure.py”,行1079

文件“ C:\ Anaconda3 \ lib \ site-packages \ matplotlib \
artist.py”,行59,位于draw_wrapper绘图(艺术家,渲染器, args,* kwargs)中

文件a.draw(renderer)中的文件“ C:\ Anaconda3 \ lib \ site-packages \ matplotlib \
axes_base.py”,行2092

文件“ C:\ Anaconda3 \ lib \ site-packages \ matplotlib \
artist.py”,行59,位于draw_wrapper绘图(艺术家,渲染器, args,* kwargs)中

文件1114行中的文件“ C:\ Anaconda3 \ lib \ site-packages \ matplotlib \ axis.py”
ticks_to_draw = self._update_ticks(renderer)

文件“ C:\ Anaconda3 \ lib \ site-packages \ matplotlib \
axis.py”,第957行,位于_update_ticks tick_tups = [t为self.iter_ticks()中的t

文件“ C:\ Anaconda3 \ lib \ site-packages \ matplotlib \
axis.py”,第957行,在tick_tups = [t为self.iter_ticks()中的t表示]

文件“ C:\ Anaconda3 \ lib \ site-packages \ matplotlib \
axis.py”,第905行,在iter_ticks中,用于i,在枚举(val)中包含(majorLocs)]

文件“ C:\ Anaconda3 \ lib \ site-packages \ matplotlib \
axis.py”,第905行,用于i,枚举中的val(majorLocs)]

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

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

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

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

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


问题答案:

这是熊猫0.15中的``回归’‘(由于Index的重构),请参见https://github.com/matplotlib/matplotlib/issues/3727https://github.com/pydata/pandas/issues/8614,但
已在0.15.1中固定


简而言之:matplotlib现在将pandas索引视为一个datetime64[ns]值数组(实际上是非常大的int64s),而不是先前版本的pandas中的Timestamps数组(属于datetime.datetime的子类,可以由matplotlib处理)。
。因此,根本原因是matplotlib不会将datetime64作为日期值处理,而是将其作为整数。

对于熊猫0.15.0(但最好将其升级到新版本),有两种可能的 解决方法

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

    units.registry[np.datetime64] = pd.tseries.converter.DatetimeConverter()
    
  • 或DatetimeIndex(具有datetime64值)转换成的阵列datetime.datetime值与to_pydatetime方法,并绘制这样的:

    ax1.plot(data.index.to_pydatetime(), data.GS10)
    

相关问题:使用matplotlib在x轴上绘制datetimeindex会在熊猫0.15中产生错误的刻度,而0.14则相反