2011-11-16 39 views
12

Załóżmy, że ma zbiór danych z oddzielnych wektorów n=2:rysunku wykres korelacji w matplotlib

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

Jak można wykreślić że zestaw danych z matplotlib tak, aby uwidocznić korelacji między tymi dwiema zmiennymi?

Wszelkie proste przykłady kodu byłyby świetne.

Odpowiedz

18
Joe Kington ma poprawną odpowiedź, ale Twój DATA prawdopodobnie jest bardziej skomplikowany, który jest reprezentowany. Może mieć wiele wartości w "a". Sposób, w jaki Joe tworzy wartości osi X, jest szybki, ale działa tylko dla listy unikalnych wartości. Nie może być szybszy sposób to zrobić, ale to w jaki sposób zrealizować go:

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") 

Moja DATA2 zestaw składa się z dwóch wartości dla każdego x wartość osi. To wykreślone na czerwono poniżej: enter image description here

EDIT

pytanie pytasz jest bardzo szeroka. Szukałem "korelacji", a Wikipedia odbyłem dobrą dyskusję na temat współczynnika momentu Pearsona, który charakteryzuje nachylenie liniowego pasowania. Należy pamiętać, że ta wartość jest jedynie wskazówką i nie przewiduje w żaden sposób, czy dopasowanie liniowe jest rozsądnym założeniem, patrz uwagi na powyższej stronie pod adresem correlation and linearity. Oto zaktualizowana plotData metoda, która wykorzystuje numpy.linalg.lstsq zrobić regresji liniowej i numpy.corrcoef obliczyć Pearsona 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) 

Nowa postać jest: enter image description here

spłaszczenie również każdy kierunek i patrząc w poszczególnych dystrybucjach może być przydatne, a ich przykłady to: doing this in matplotlib: enter image description here

Jeśli przybliżenie liniowe jest użyteczne, co można określić jako Po prostu patrząc na dopasowanie, możesz odejść od tego trendu przed zejściem w kierunku y. To pomogłoby pokazać, że macie losowy rozkład Gaussa o liniowym trendzie.

+0

Cześć Yann .. Dzięki za scenariusz. Nie rozumiem, że istnieje wyjątkowa część listy. Konwertujesz wartości zmiennoprzecinkowe na liczby całkowite. Oś X nadal zawiera zduplikowane wartości, prawda? – mdasari

5

Jestem nieco zdezorientowany ... Istnieje kilka sposobów, aby coś z tym zrobić. Pierwsze dwa, które przychodzą na myśl, to prosty wykres trzonu lub wykres punktowy.

Czy chcesz tylko kreślić rzeczy za pomocą takiego wykresu?

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

Albo wykres punktowy tak:

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

Albo coś zupełnie innego?

Powiązane problemy