web-dev-qa-db-ja.com

pandas 0.21.0 matplotlibとのタイムスタンプの互換性の問題

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 (エポック時間(ナノ秒))。

また、0.21.0で失敗するx値にmatplotlib.dates.DateFormatterを使用して、グラフ上のクリックされた場所を報告するカスタマイズされたカーソルがあります。

OverflowError: signed integer is greater than maximum

デバッグでは、報告されたx値は0.17.1の場合は約736500(つまり0年からの日数)ですが、0.21.0の場合は約1.5e18(つまりナノ秒エポック時間)です。

Matplotlibとpandasは明らかにほとんどの人が一緒に使用しているため、互換性が失われていることに驚いています。新しいバージョンで上記のプロット関数を呼び出す方法に何か不足していますか?

Update上記のように、特定のAxesオブジェクトを使用してplotを直接呼び出すことを好みますが、それだけではなく、 DataFrame自体のプロットメソッドdf.plot()。これが完了するとすぐに、後続のすべてのプロットがタイムスタンプを正しく認識します同じpython session内)。別のリロードできるので、環境変数が設定されているようですDataFrameまたはsubplotsを使用して別の座標軸を作成し、1.5e18はどこにも表示されません。これは、最新のpandas docが言うように、バグのようなにおいがします 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()

メンバープロットが呼び出された後、新しいSeriesまたはDataFrameでplt.plotを呼び出すと、メンバープロットメソッドを再度呼び出す必要なく、正しくオートフォーマットされます。

18
Kevin S.

/ pandas datetime and matplotlib の問題があり、pandas 0.21、インポート時にコンバーターを登録しなくなります。これらのコンバーターを一度使用すると(pandas内で)、それらは登録され、matplotlibによっても自動的に使用されます。

回避策は、それらを手動で登録することです。

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

いずれにせよ、この問題はpandasとmatplotlibの両方でよく知られているため、次のリリースでは何らかの修正が行われる予定です。Pandasは考えています レジスタの読み取り 今後のリリースで発生するため、この問題は一時的にのみ発生する可能性があります。pandas 0.20。 xこれが発生してはならない場所。

更新:これは、matplotlib(2.2.2)/ pandas(0.23.1)の現在のバージョンの問題ではなくなりました。これが修正された2017年12月頃からリリースされています。

Update 2:現在、pandas 0.24以上では、コンバータを登録するための推奨方法は

from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()

または、pandasがすでにpdとしてインポートされている場合、

pd.plotting.register_matplotlib_converters()

pandas githubで issue を開いた後、これが実際にpandasとmatplotlibの間で単位変換の自動登録に関して既知の issue であることがわかりました。実際、これは以前に確認できなかった新機能 page にリストされており、コンバーターを登録する適切な方法も示しています。

from pandas.tseries import converter
converter.register() 

これは、メンバープロットメソッドがSeriesまたはDataFrameで初めて呼び出されたときにも実行されます。

これは、matplotlibがpandas日時の基本的なサポートを実装することになっているように見えますが、実際には、このような中断には何らかの非推奨警告が役立つ可能性があります。ただし、matplotlibが実際にそのようなサポート(またはある種の遅延登録メカニズム)を実装するまで、実際には常にこれらの2行をpandasインポートに配置します。したがって、matplotlib側で準備が整う前に、pandasがインポート時の自動登録を無効にする理由がわかりません。

11
Kevin S.