web-dev-qa-db-ja.com

pandas DataFrameからの2つのヒストグラムをmatplotlibを使用して1つのサブプロットにプロットする

次のようなpandas dataframeがあります:

df = pd.DataFrame({ 'a_wood' : np.random.randn(100),
                 'a_grassland' : np.random.randn(100),
                 'a_settlement' : np.random.randn(100),
                 'b_wood' : np.random.randn(100),
                 'b_grassland' : np.random.randn(100),
                  'b_settlement' : np.random.randn(100)})

そして、このデータのヒストグラムを1つのサブプロットのすべてのデータフレームヘッダーで作成したいと思います。

fig, ax = plt.subplots(2, 3, sharex='col', sharey='row')

m=0
for i in range(2):
    for j in range(3):

        df.hist(column = df.columns[m], bins = 12, ax=ax[i,j], figsize=(20, 18))
        m+=1

そのため、前のコードは完全に機能しますが、今度は、アイリーaおよびbヘッダー(たとえば、「a_woods」と「b-woods」)を1つのサブプロットに結合して、ヒストグラムが3つだけになるようにします。 2つの列をdf.columns[[m,m+3]]に割り当てようとしましたが、これは機能しません。また、 "day_1"のような文字列を含むインデックス列があります。これは、x軸に配置したいです。誰かが私を助けてくれますか?

これは私がどこまで行ったかです。 Histogram

6
Max2603

あなたの質問を正しく理解したかどうかはわかりませんが、このようなものでプロットを組み合わせることができます。アルファで少し遊んで、ヘッダーを変更したい場合があります。

#NOTE that you might want to specify your bins or they wont line up exactly
fig, ax = plt.subplots(1, 3, sharex='col', sharey='row', figsize=(20, 18))
n = 3
for j in range(n):
    df.hist(column=df.columns[j], bins=12, ax=ax[j], alpha=0.5, color='red')
    df.hist(column=df.columns[j+n], bins=12, ax=ax[j], alpha=0.5, color='blue')
    ax[j].set_title(df.columns[j][2:])

両方を隣同士にプロットするには、次のようにします。

#This example doesnt have the issue with different binsizes within one subplot
fig, ax = plt.subplots(1, 3, sharex='col', sharey='row', figsize=(20, 18))

n = 3
colors = ['red', 'blue']

axes = ax.flatten()
for i,j in Zip(range(n), axes):
    j.hist([df.iloc[:,i], df.iloc[:,i+n]], bins=12, color=colors)
    j.set_title(df.columns[i][2:])

Histogram, multiple bars in same bin

1
Alex

各列をループし、そのデータをヒストグラムにプロットするものが必要ですか?今後のコードで再利用できるいくつかの変更を加えることをお勧めします。コードを提供する前に、役立つヒントがいくつかあります。

  1. データフレームにはループ処理に使用できる属性があることを認識しておく必要があります。たとえば、.columns属性には列のリストを含めることができます。
  2. また、プロットするときに、グリッド上の座標を直接使用してもコードを適応させることができないので、グリッド座標を「フラット化」する必要があることに気づきました。そのため、これを可能にするax.ravel()を使用します。
  3. enumerate()は、i番目の要素とそのインデックスを同時に使用できるようにしながら、オブジェクトをループする場合に常に役立ちます。
  4. pythonのサブプロットを理解することは最初は難しいので、他の人のコードを読むことは非常に役立ちます。scikit関数の例で行われたプロットを確認することを強くお勧めします(これは非常に役立ちました)

これが私のコード提案です:

fig, ax = plt.subplots(1, 3, sharex='col', sharey='row', figsize=(12,7))
ax = ax.ravel() 
# this method helps you to go from a 2x3 array coordinates to 
# 1x6 array, it will be helpful to use as below

for idx in range(3):
    ax[idx].hist(df.iloc[:,idx], bins=12, alpha=0.5)
    ax[idx].hist(df.iloc[:,idx+3], bins=12, alpha=0.5)
    ax[idx].set_title(df.columns[idx]+' with '+df.columns[idx+3])
    ax[idx].legend(loc='upper left')

the result looks like this

これがお役に立てば幸いです。詳細が必要な場合は、遠慮なく質問してください。

注:アレックスの回答を再利用して私の回答を編集しました。詳細については、この matplotlibドキュメント も確認してください。この特定のケースでは、ポイント3は関係ありません。

3
Eric