2011-11-16 34 views
12

Supongamos que tengo un conjunto de datos de los vectores discretos con n=2:Dibujo de un gráfico de correlación en matplotlib

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

¿Cómo puede trazar I que conjunto de datos con matplotlib fin de visualizar cualquier correlación entre las dos variables?

Cualquier ejemplo de código simple sería genial.

Respuesta

18

Joe Kington tiene la respuesta correcta, pero su DATA probablemente sea más complicado que lo que se representa. Puede tener valores múltiples en 'a'. La forma en que Joe construye los valores del eje x es rápida, pero solo funcionaría para una lista de valores únicos. Puede haber una manera más rápida de hacer esto, pero esto cómo lo logró:

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

Mi DATA2 conjunto tiene dos valores para cada valor del eje x. Se representa en rojo a continuación: enter image description here

EDITAR

La pregunta que se plantea es muy amplio. Busqué "correlación" y Wikipedia tuve una buena discusión sobre el coeficiente producto-momento de Pearson, que caracteriza la pendiente de un ajuste lineal. Tenga en cuenta que este valor es solo una guía, y de ninguna manera predice si un ajuste lineal es una suposición razonable o no, vea las notas en la página anterior en correlation and linearity. Aquí está una versión actualizada plotData método, que utiliza numpy.linalg.lstsq hacer regresión lineal y numpy.corrcoef para calcular R de Pearson:

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) 

La nueva cifra es: enter image description here

también aplanando cada dirección y mirando a las distribuciones individuales podrían ser útil, y sus son ejemplos de doing this in matplotlib: enter image description here

Si una aproximación lineal es útil, que puede determinar cualitativo simplemente mirando el ajuste, es posible que desee restar esta tendencia antes de nivelar la dirección y. Esto ayudaría a mostrar que tiene una distribución aleatoria gaussiana sobre una tendencia lineal.

+0

Hola Yann .. Gracias por el guión. No entendí sobre la parte única de la lista. Solo está convirtiendo valores de coma flotante en enteros. El eje x todavía contiene valores duplicados ¿no? – mdasari

5

Estoy un poco confundido ... Hay varias maneras de hacer algo en ese sentido. Los dos primeros que se me ocurren son un diagrama de tallo simple o un diagrama de dispersión.

¿Solo quieres trazar cosas con un diagrama de tallo como este?

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

O un gráfico de dispersión de esta manera:

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

o algo completamente distinto?

Cuestiones relacionadas