2014-10-29 5 views
6

Nach this answer's use of DateFormatter habe ich versucht, eine Zeitreihe zu planen und seine x-Achse mit den Jahren beschriftet Pandas 0.15.0 und matplotlib mit 1.4.2:Warum bekomme ich "python int zu groß, um in C long" -Fehler zu konvertieren, wenn ich DateFormatter von matplotlib verwende, um Daten auf der X-Achse zu formatieren?

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') 

Die letzten Zeile wirft einen Fehler: OverflowError: Python int too large to convert to C long mit diesen Zurückverfolgungs:

C:\Anaconda3\lib\site-packages\IPython\core\formatters.py:239: FormatterWarning: Exception in image/png formatter: Python int too large to convert to C long FormatterWarning, Traceback (most recent call last):

File "", line 1, in runfile('D:/username/latex_template/new_pandas_example.py', wdir='D:/username/latex_template')

File "C:\Anaconda3\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 580, in runfile execfile(filename, namespace)

File "C:\Anaconda3\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 48, in execfile exec(compile(open(filename, 'rb').read(), filename, 'exec'), namespace)

File "D:/username/latex_template/new_pandas_example.py", line 18, in fig.savefig('test.eps')

File "C:\Anaconda3\lib\site-packages\matplotlib\figure.py", line 1470, in savefig self.canvas.print_figure(*args, **kwargs)

File "C:\Anaconda3\lib\site-packages\matplotlib\backend_bases.py", line 2194, in print_figure **kwargs)

File "C:\Anaconda3\lib\site-packages\matplotlib\backends\backend_ps.py", line 992, in print_eps return self._print_ps(outfile, 'eps', *args, **kwargs)

File "C:\Anaconda3\lib\site-packages\matplotlib\backends\backend_ps.py", line 1020, in _print_ps **kwargs)

File "C:\Anaconda3\lib\site-packages\matplotlib\backends\backend_ps.py", line 1110, in _print_figure self.figure.draw(renderer)

File "C:\Anaconda3\lib\site-packages\matplotlib\artist.py", line 59, in draw_wrapper draw(artist, renderer, *args, **kwargs)

File "C:\Anaconda3\lib\site-packages\matplotlib\figure.py", line 1079, in draw func(*args)

File "C:\Anaconda3\lib\site-packages\matplotlib\artist.py", line 59, in draw_wrapper draw(artist, renderer, *args, **kwargs)

File "C:\Anaconda3\lib\site-packages\matplotlib\axes_base.py", line 2092, in draw a.draw(renderer)

File "C:\Anaconda3\lib\site-packages\matplotlib\artist.py", line 59, in draw_wrapper draw(artist, renderer, *args, **kwargs)

File "C:\Anaconda3\lib\site-packages\matplotlib\axis.py", line 1114, in draw ticks_to_draw = self._update_ticks(renderer)

File "C:\Anaconda3\lib\site-packages\matplotlib\axis.py", line 957, in _update_ticks tick_tups = [t for t in self.iter_ticks()]

File "C:\Anaconda3\lib\site-packages\matplotlib\axis.py", line 957, in tick_tups = [t for t in self.iter_ticks()]

File "C:\Anaconda3\lib\site-packages\matplotlib\axis.py", line 905, in iter_ticks for i, val in enumerate(majorLocs)]

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

File "C:\Anaconda3\lib\site-packages\matplotlib\dates.py", line 411, in call dt = num2date(x, self.tz)

File "C:\Anaconda3\lib\site-packages\matplotlib\dates.py", line 345, in num2date return _from_ordinalf(x, tz)

File "C:\Anaconda3\lib\site-packages\matplotlib\dates.py", line 225, in _from_ordinalf dt = datetime.datetime.fromordinal(ix)

OverflowError: Python int too large to convert to C long

Ich verwende DateFormatter falsch hier? Wie kann ich auf der a-Achse einer Matplotlib-Figur Jahre (oder ein beliebiges anderes Zeitformat, da meine Zeitreihe unterschiedlich sein kann) leicht setzen?

Antwort

11

Dies ist eine 'Regression' in pandas 0,15 (aufgrund der Umgestalten der Index), siehe https://github.com/matplotlib/matplotlib/issues/3727 und https://github.com/pydata/pandas/issues/8614, aber wird in 0.15.1 fixiert.


Kurzgeschichte: matplotlib sieht jetzt die Pandas Index als ein Array von datetime64[ns] Werte (die eigentlich sehr große int64s sind), anstelle eines Arrays von Zeitstempel (die Unterklasse von datetime.datetime sind, und können behandelt werden von Matplotlib) in früheren Versionen von Pandas. Der Grund dafür ist, dass matplotlib datetime64 nicht als Datumswerte sondern als Ints behandelt.

Für 0.15.0 Pandas (aber besser auf eine neuere Version aktualisieren), gibt es zwei mögliche Umgehungen:

  • Registrieren Sie den datetime64 Typ, so wird es auch als Datum von matplotlib behandelt werden :

    units.registry[np.datetime64] = pd.tseries.converter.DatetimeConverter() 
    
  • oder die DatetimeIndex (mit datetime64 Werten) in ein Array von datetime.datetime Werten mit dem to_pydatetime Verfahren umwandeln und diese plotten:

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

damit verbundene Frage: Plotting datetimeindex on x-axis with matplotlib creates wrong ticks in pandas 0.15 in contrast to 0.14

+0

Danke für die Antwort; Sie hatten Recht, dass dies in Pandas 0.15.1 fixiert war. Ich habe gerade diesen Morgen aktualisiert und mein ursprüngliches Codebeispiel funktioniert genauso wie beabsichtigt. (Vielleicht bearbeiten Sie Ihre Frage, um das zu integrieren?) –

+0

ja, danke, aktualisiert die Antwort. – joris

+1

Nun, das Problem scheint zu Pandas 0.21.0 .... zurückgekehrt zu sein ....: S – ntg

Verwandte Themen