86

Pythonのデータフレームmatplotlibから使用して一連の散布図を作成するための最良の方法は何ですか?pandas

たとえば、df関心のある列がいくつかあるデータフレームがある場合、通常はすべてを配列に変換します。

import matplotlib.pylab as plt
# df is a DataFrame: fetch col1 and col2 
# and drop na rows if any of the columns are NA
mydata = df[["col1", "col2"]].dropna(how="any")
# Now plot with matplotlib
vals = mydata.values
plt.scatter(vals[:, 0], vals[:, 1])

プロットする前にすべてを配列に変換する際の問題は、データフレームから抜け出すことを余儀なくされることです。

完全なデータフレームを持つことがプロットに不可欠である次の2つのユースケースを検討してください。

  1. たとえばcol3、呼び出しでプロットした対応する値のすべての値を確認しscatter、各ポイント(またはサイズ)にその値で色を付けたい場合はどうでしょうか。戻って、のna以外の値を引き出しcol1,col2、対応する値を確認する必要があります。

    データフレームを保持しながらプロットする方法はありますか?例えば:

    mydata = df.dropna(how="any", subset=["col1", "col2"])
    # plot a scatter of col1 by col2, with sizes according to col3
    scatter(mydata(["col1", "col2"]), s=mydata["col3"])
    
  2. 同様に、いくつかの列の値に応じて、各ポイントを異なる方法でフィルタリングまたは色付けしたいとします。たとえば、特定のカットオフを満たすポイントのラベルをcol1, col2それらの横に自動的にプロットしたり(ラベルがdfの別の列に格納されている場合)、Rのデータフレームで行うように、これらのポイントに異なる色を付けたりする場合はどうでしょうか。例:

    mydata = df.dropna(how="any", subset=["col1", "col2"]) 
    myscatter = scatter(mydata[["col1", "col2"]], s=1)
    # Plot in red, with smaller size, all the points that 
    # have a col2 value greater than 0.5
    myscatter.replot(mydata["col2"] > 0.5, color="red", s=0.5)
    

これはどのように行うことができますか?

編集クルーバムへの返信:

最善の方法は、各条件(subset_a、などsubset_b)を個別にプロットすることです。多くの条件がある場合、たとえば、散乱を4種類以上のポイントに分割し、それぞれを異なる形状/色でプロットしたい場合はどうでしょうか。条件a、b、cなどをエレガントに適用し、最後のステップとして「残り」(これらの条件のいずれにも当てはまらないもの)をプロットするようにするにはどうすればよいですか?

col1,col2同様に、に基づいて異なる方法でプロットする例ではcol3、間の関連付けを壊すNA値がある場合はどうなりcol1,col2,col3ますか?たとえば、すべてのcol2値をそれらの値に基づいてプロットしたいが、一部の行にはまたはのいずれかcol3にNA値があり、最初に使用する必要がある場合です。だからあなたはするでしょう:col1col3dropna

mydata = df.dropna(how="any", subset=["col1", "col2", "col3")

次に、次のようにプロットできます。の値を使用してmydata間の分散をプロットします。しかし、の値はあるがNAであるいくつかのポイントが欠落し、それらはまだプロットする必要があります...では、基本的にデータの「残り」、つまりフィルター処理されたセットにないポイントをどのようにプロットしますか?col1,col2col3mydatacol1,col2col3mydata

4

3 に答える 3

120

DataFrame以下の例のように、列をnumpy配列として抽出するのではなく、直接matplotlibに渡してみてください。

df = pd.DataFrame(np.random.randn(10,2), columns=['col1','col2'])
df['col3'] = np.arange(len(df))**2 * 100 + 100

In [5]: df
Out[5]: 
       col1      col2  col3
0 -1.000075 -0.759910   100
1  0.510382  0.972615   200
2  1.872067 -0.731010   500
3  0.131612  1.075142  1000
4  1.497820  0.237024  1700

別の列に基づいて散布点のサイズを変更する

plt.scatter(df.col1, df.col2, s=df.col3)
# OR (with pandas 0.13 and up)
df.plot(kind='scatter', x='col1', y='col2', s=df.col3)

ここに画像の説明を入力してください

別の列に基づいて散布点の色を変更する

colors = np.where(df.col3 > 300, 'r', 'k')
plt.scatter(df.col1, df.col2, s=120, c=colors)
# OR (with pandas 0.13 and up)
df.plot(kind='scatter', x='col1', y='col2', s=120, c=colors)

ここに画像の説明を入力してください

凡例の散布図

ただし、凡例を使用して散布図を作成する最も簡単な方法は、plt.scatterポイントタイプごとに1回呼び出すことです。

cond = df.col3 > 300
subset_a = df[cond].dropna()
subset_b = df[~cond].dropna()
plt.scatter(subset_a.col1, subset_a.col2, s=120, c='b', label='col3 > 300')
plt.scatter(subset_b.col1, subset_b.col2, s=60, c='r', label='col3 <= 300') 
plt.legend()

ここに画像の説明を入力してください

アップデート

私の知る限り、matplotlibは、NA x / y座標またはNAスタイル設定(色/サイズなど)のポイントをスキップするだけです。NAが原因でスキップされたポイントを見つけるには、次のisnull方法を試してください。df[df.col3.isnull()]

ポイントのリストを多くのタイプに分割するには、 numpyselectを見てください。これは、ベクトル化されたif-then-else実装であり、オプションのデフォルト値を受け入れます。例えば:

df['subset'] = np.select([df.col3 < 150, df.col3 < 400, df.col3 < 600],
                         [0, 1, 2], -1)
for color, label in zip('bgrm', [0, 1, 2, -1]):
    subset = df[df.subset == label]
    plt.scatter(subset.col1, subset.col2, s=120, c=color, label=str(label))
plt.legend()

ここに画像の説明を入力してください

于 2013-01-13T18:48:58.397 に答える
7

ギャレットの素晴らしい答えに追加することはほとんどありませんが、パンダにもscatter方法があります。それを使用すると、それは同じくらい簡単です

df = pd.DataFrame(np.random.randn(10,2), columns=['col1','col2'])
df['col3'] = np.arange(len(df))**2 * 100 + 100
df.plot.scatter('col1', 'col2', df['col3'])

col3からcol1-col2へのサイズのプロット

于 2017-10-15T10:28:43.657 に答える
5

seabornデータプロット用のより強力なツールを使用する別の方法を使用することをお勧めします。カラム3をととして使用seaborn scatterplotおよび定義できます。huesize

作業コード:

import pandas as pd
import seaborn as sns
import numpy as np

#creating sample data 
sample_data={'col_name_1':np.random.rand(20),
      'col_name_2': np.random.rand(20),'col_name_3': np.arange(20)*100}
df= pd.DataFrame(sample_data)
sns.scatterplot(x="col_name_1", y="col_name_2", data=df, hue="col_name_3",size="col_name_3")

ここに画像の説明を入力してください

于 2019-06-23T10:55:37.177 に答える