Подтвердить что ты не робот

Рисование графика корреляции в matplotlib

Предположим, что у меня есть набор данных дискретных векторов с n=2:

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

Как я могу построить этот набор данных с помощью matplotlib, чтобы визуализировать любую корреляцию между двумя переменными?

Любые простые примеры кода были бы замечательными.

4b9b3361

Ответ 1

У Джо Кингтона есть правильный ответ, но ваш DATA, вероятно, более сложный, который представлен. Он может иметь несколько значений в 'a'. То, как Джо строит значения оси 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")

My DATA2 set имеет два значения для каждого значения оси x. Он изображен красным цветом ниже: enter image description here

ИЗМЕНИТЬ

Вопрос, который вы задали, очень широк. Я искал "корреляцию", а Wikipedia имел хорошее обсуждение коэффициента момента продукта Пирсона, характеризующего наклон линейной подгонки. Имейте в виду, что это значение является только ориентиром и никоим образом не предсказывает, является ли линейное соответствие разумным предположением, см. Примечания на предыдущей странице на корреляции и линейности. Ниже приведен обновленный метод plotData, который использует numpy.linalg.lstsq для выполнения линейной регрессии и numpy.corrcoef для вычисления Pearson 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. Это поможет показать, что у вас есть случайное распределение Гаусса относительно линейного тренда.

Ответ 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

Или что-то еще?