1. ホーム
  2. python

[解決済み] Pythonのpandasでデータフレームからmatplotlibの散布図を作成する

2023-05-29 04:55:55

質問

を使用して一連の散布図を作成する最も良い方法は何でしょうか? 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 を呼び出し、その値で各ポイントを色付け(またはサイズ変更)するのですか?の非ナ値を引き出す必要があります。 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)
    
    

これはどうやったらできるのでしょうか?

EDIT crewbumに返信する。

条件ごとにプロットするのが一番良いということですね(例えば subset_a , subset_b ) に分けてプロットすることができます。例えば、散布図を4種類またはそれ以上の点に分割し、それぞれを異なる形状/色でプロットしたい場合など、多くの条件がある場合はどうすればよいでしょうか。条件a、b、cなどをエレガントに適用し、最後のステップとして"the rest"(これらの条件のいずれでもないもの)を確実にプロットするにはどうしたらよいでしょうか?

同様に、あなたがプロットする例では col1,col2 に基づいて異なる col3 の間の関連性を壊すような NA 値があるとしたらどうでしょう? col1,col2,col3 ? 例えば、すべての col2 の値を col3 の値に基づいていますが、一部の行では col1 または col3 を使用することを余儀なくされます。 dropna を先に使わざるを得ません。だから、あなたはそうするでしょう。

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

であれば mydata を使ってプロットできます。 col1,col2 の値を使って col3 . しかし mydata の値を持ついくつかの点が欠落します。 col1,col2 には値があるが col3 についてはNAであり、それらはまだプロットされなければなりません。では、基本的にどのようにデータの残りの部分、つまり でなく でない点です。 mydata ?

どのように解決するのですか?

のカラムを渡してみてください。 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 を各点タイプについて一度だけ呼び出すことです。

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 は単に x/y 座標が NA であるか、スタイル設定 (例: 色/サイズ) が NA である点をスキップします。 NAのためにスキップされた点を見つけるには、以下のようにします。 isnull メソッドを試してみてください。 df[df.col3.isnull()]

点のリストを多くの種類に分割するには、次のようにします。 numpy select これはベクトル化された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()

<イグ