web-dev-qa-db-ja.com

matplotlibで相関グラフを描く

n=2の離散ベクトルのデータセットがあるとします。

DATA = [
    ('a', 4),
    ('b', 5),
    ('c', 5),
    ('d', 4),
    ('e', 2),
    ('f', 5),
]

2つの変数間の相関関係を視覚化するために、matplotlibを使用してそのデータセットをプロットするにはどうすればよいですか?

簡単なコード例があれば素晴らしいでしょう。

13
Yuval Adam

Joe Kingtonが正解ですが、あなたのDATAはおそらくもっと複雑です。 'a'に複数の値がある場合があります。 Joeがx軸の値を作成する方法は迅速ですが、一意の値のリストに対してのみ機能します。これを行うためのより速い方法があるかもしれませんが、これは私がそれを達成した方法です:

import matplotlib.pyplot as plt

def assignIDs(list):
    '''Take a list of strings, and for each unique value assign a number.
    Returns a map for "unique-val"->id.
    '''
    sortedList = sorted(list)

    #taken from
    #http://stackoverflow.com/questions/480214/how-do-you-remove-duplicates-from-a-list-in-python-whilst-preserving-order/480227#480227
    seen = set()
    seen_add = seen.add
    uniqueList =  [ x for x in sortedList if x not in seen and not seen_add(x)]

    return  dict(Zip(uniqueList,range(len(uniqueList))))

def plotData(inData,color):
    x,y = Zip(*inData)

    xMap = assignIDs(x)
    xAsInts = [xMap[i] for i in x]


    plt.scatter(xAsInts,y,color=color)
    plt.xticks(xMap.values(),xMap.keys())


DATA = [
    ('a', 4),
    ('b', 5),
    ('c', 5),
    ('d', 4),
    ('e', 2),
    ('f', 5),
]


DATA2 = [
    ('a', 3),
    ('b', 4),
    ('c', 4),
    ('d', 3),
    ('e', 1),
    ('f', 4),
    ('a', 5),
    ('b', 7),
    ('c', 7),
    ('d', 6),
    ('e', 4),
    ('f', 7),
]

plotData(DATA,'blue')
plotData(DATA2,'red')

plt.gcf().savefig("correlation.png")

私のDATA2セットには、x軸の値ごとに2つの値があります。以下に赤でプロットされています。 enter image description here

[〜#〜]編集[〜#〜]

あなたが尋ねた質問は非常に広いです。 'correlation'を検索したところ、 Wikipedia は、線形フィットの傾きを特徴付けるピアソンの積率係数について良い議論をしました。この値は単なるガイドであり、線形フィットが妥当な仮定であるかどうかを予測するものではないことに注意してください。上記のページの注 相関と線形性 を参照してください。更新されたplotDataメソッドは、numpy.linalg.lstsqを使用して線形回帰を実行し、numpy.corrcoefを使用してピアソンのRを計算します。

import matplotlib.pyplot as plt
import numpy as np

def plotData(inData,color):
    x,y = Zip(*inData)

    xMap = assignIDs(x)
    xAsInts = np.array([xMap[i] for i in x])

    pearR = np.corrcoef(xAsInts,y)[1,0]
    # least squares from:
    # http://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.lstsq.html
    A = np.vstack([xAsInts,np.ones(len(xAsInts))]).T
    m,c = np.linalg.lstsq(A,np.array(y))[0]

    plt.scatter(xAsInts,y,label='Data '+color,color=color)
    plt.plot(xAsInts,xAsInts*m+c,color=color,
             label="Fit %6s, r = %6.2e"%(color,pearR))
    plt.xticks(xMap.values(),xMap.keys())
    plt.legend(loc=3)

新しい図は次のとおりです。 enter image description here

また、各方向を平坦化し、個々の分布を調べることも役立つ場合があります。これらは、 matplotlibでこれを行う の例です。 enter image description here

近似を見るだけで定性的に決定できる線形近似が役立つ場合は、y方向を平坦化する前にこの傾向を差し引くことをお勧めします。これは、線形トレンドに関するガウスランダム分布があることを示すのに役立ちます。

19
Yann

私は少し混乱しています...それらの線に沿って何かをするいくつかの方法があります。頭に浮かぶ最初の2つは、単純な幹葉図または散布図です。

このような幹葉図を使用して物事をプロットしたいだけですか?

import matplotlib.pyplot as plt
data = [
    ('a', 4),
    ('b', 5),
    ('c', 5),
    ('d', 4),
    ('e', 2),
    ('f', 5),
]
labels, y = Zip(*data)

x = range(len(y))
plt.stem(x, y)
plt.xticks(x, labels)
plt.axis([-1, 6, 0, 6])
plt.show()

enter image description here

または、次のような散布図:

import matplotlib.pyplot as plt
data = [
    ('a', 4),
    ('b', 5),
    ('c', 5),
    ('d', 4),
    ('e', 2),
    ('f', 5),
]
labels, y = Zip(*data)

x = range(len(y))
plt.plot(x, y, 'o')
plt.xticks(x, labels)
plt.axis([-1, 6, 0, 6])
plt.show()

enter image description here

または完全に何か他のもの?

6
Joe Kington