web-dev-qa-db-ja.com

pandas plotメソッドを使用してFigureサイズを設定するときの不整合

pandas dataframeのplotメソッドの便利さを使用して、生成される図のサイズを調整しようとしています。(図をファイルに保存し、 Jupyterノートブック)。同じチャートに2本の線をプロットする場合を除き、ほとんどの場合、以下の方法が成功しました-その後、図はデフォルトのサイズに戻ります。

これは、シリーズのプロットとデータフレームのプロットの違いによるものと思われます。

セットアップのサンプルコード:

data = {
    'A': 90 + np.random.randn(366),
    'B': 85 + np.random.randn(366)
}

date_range = pd.date_range('2016-01-01', '2016-12-31')

index = pd.Index(date_range, name='Date')

df = pd.DataFrame(data=data, index=index)

コントロール-このコードは期待される結果を生成します(広いプロット):

fig = plt.figure(figsize=(10,4))

df['A'].plot()
plt.savefig("plot1.png")
plt.show()

結果:

plot1.png

2行のプロット-フィギュアサイズは(10,4)ではありません

fig = plt.figure(figsize=(10,4))

df[['A', 'B']].plot()
plt.savefig("plot2.png")
plt.show()

結果:

plot2.png

これを行う正しい方法は何ですか?選択したシリーズの数に関係なく、フィギュアのサイズが一貫性を持つようになりますか?

11
Bill

2つのケースの違いの理由は、pandas.DataFrame.plot()のロジック内に少し隠れているためです。 ドキュメント で見ることができるように、このメソッドは多くの引数を渡して、あらゆる種類の異なるケースを処理できるようにします。

最初のケースでは、fig = plt.figure(figsize=(10,4))を介してmatplotlibの図を作成し、単一列のDataFrameをプロットします。 pandas plot関数の内部ロジックは、matplotlibステートマシンに既に図が存在するかどうかを確認し、存在する場合は、現在の軸を使用して列値をプロットします。期待どおりに動作します。

ただし、2番目の場合、データは2つの列で構成されます。共有軸または非共有軸などで異なるサブプロットを使用するなど、このようなプロットを処理する方法がいくつかあります。pandasがこれらの可能な要件のいずれかを適用できるようにするには、デフォルトでは、プロットする軸を追加できる新しいFigureを作成します。新しいFigureは、既存のFigureとそのサイズを認識しませんが、figsize引数を指定しない限り、デフォルトのサイズを持ちます。 。

コメントでは、可能な解決策はdf[['A', 'B']].plot(figsize=(10,4))を使用することだと言います。これは正しいですが、最初の図の作成を省略する必要があります。それ以外の場合、2つの数字が生成されますが、これはおそらく望ましくありません。ノートブックではこれは表示されませんが、これを通常のpythonスクリプトを最後にplt.show()で実行すると、2つのFigureウィンドウが開きます。

したがって、pandasがフィギュア作成の面倒を見るようにするソリューションは

_import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({"A":[2,3,1], "B":[1,2,2]})
df[['A', 'B']].plot(figsize=(10,4))

plt.show()
_

新しいFigureの作成を回避する方法は、ax引数がpandas.DataFrame.plot(ax=ax)関数に提供されることです。ここで、axは外部で作成された軸です。この軸は、plt.gca()を介して取得する標準軸にすることができます。

_import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({"A":[2,3,1], "B":[1,2,2]})
plt.figure(figsize=(10,4))
df[['A', 'B']].plot(ax = plt.gca())

plt.show()
_

または、 PaulHからの回答 で見られるよりオブジェクト指向の方法を使用します。

常にFigureおよびAxesオブジェクトに対して明示的に直接操作してください。 pyplot状態マシンに依存しないでください。あなたの場合、それは次のことを意味します:

fig1, ax1 = plt.subplots(figsize=(10,4))
df['A'].plot(ax=ax1)
fig1.savefig("plot1.png")


fig2, ax2 = plt.figure(figsize=(10,4)) 
df[['A', 'B']].plot(ax=ax2)
fig2.savefig("plot2.png")

plt.show()
5
Paul H