Диаграмма рассеяния Python: как использовать цветовую карту, которая имеет те же цвета, что и цветовой цикл - PullRequest
0 голосов
/ 21 февраля 2019

Я пытаюсь раскрасить кластеры на диаграмме рассеяния, и мне удалось двумя разными способами.

В первом я итеративно строю каждый кластер, во втором я рисую все данные сразу и окрашиваю кластерыв соответствии с их ярлыками [0, 1, 2, 3, 4].

Я доволен результатом, который получаю в example1 и example3, но я не понимаю, почему цвет меняется так резкопри раскраске кластеров в соответствии с метками вместо итеративного построения каждого кластера.

Кроме того, почему второй кластер (несмотря на наличие всегда метки "1") имеет другой цвет в example1 и example3?

import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight') #irrelevant here, but coherent with the examples=)

fig, ax = plt.subplots(figsize=(6,4))
for clust in range(kmeans.n_clusters):
    ax.scatter(X[kmeans.labels_==clust],Y[kmeans.labels_==clust])
    ax.set_title("example1")`

example1

и

plt.figure(figsize = (6, 4))
plt.scatter(X,Y,c=kmeans.labels_.astype(float))
plt.title("example2")

example2

(я знаю, что могу явноопределить цветовую карту для второго метода, но я не смог найти ни одного, который воспроизводит результаты в примере 1)

Вот минимальный рабочий пример

import matplotlib.pyplot as plt
import pandas as pd
plt.style.use('fivethirtyeight') #irrelevant here, but coherent with the examples=)
X=pd.Series([1, 2, 3, 4, 5, 11, 12, 13, 14, 15])
Y=pd.Series([1,1,1,1,1,2,2,2,2,2])
clusters=pd.Series([0,0,0,0,0,1,1,1,1,1])


fig, ax = plt.subplots(figsize=(6,4))
for clust in range(2):
ax.scatter(X[clusters==clust],Y[clusters==clust])
ax.set_title("example3")

example3

plt.figure(figsize = (6, 4))
plt.scatter(X,Y, c=clusters)
plt.title("example4")

example4

1 Ответ

0 голосов
/ 22 февраля 2019

Когда вы зацикливаете кластеры и наносите на график scatter без указания какого-либо цвета, будут использоваться цвета по умолчанию активного свойства cycler (цветовой цикл).Активное свойство cycler определено в rcParams.Он устанавливается через используемый стиль;в вашем случае, используя 'fivethirtyeight'

print(plt.rcParams["axes.prop_cycle"])
> cycler('color', ['#008fd5', '#fc4f30', '#e5ae38', '#6d904f', '#8b8b8b', '#810f7c'])

Первые два цвета этого ('# 008fd5', '# fc4f30') - это тот, который вы видите на графике.

Когда вы используете scatter с clusters в качестве аргумента цвета, эти значения будут сопоставлены с цветом с помощью карты цветов.Если цветовая карта не указана, будет использоваться цветовая карта по умолчанию, определенная в rcParam.

print(plt.rcParams["image.cmap"])
> "viridis"

Стиль 'fivethirtyeight' не определяет никакой специальной карты цветов, поэтому значение по умолчанию не изменится.(Тот факт, что на вашей картинке вы видите цветную карту, отличную от viridis, объясняется тем, что был еще какой-то еще активный код, который не показан в вопросе.)

На этом этапе мне нужно начать интерпретацию.;Я думаю, что ваш вопрос на самом деле заключается в том, как заставить единый разброс использовать цветовую карту, которая имеет те же цвета, что и цветовой цикл.Ни одна из предопределенных цветовых карт не содержит цветов тридцатитысячного цикла.Следовательно, вы должны определить эту цветовую карту вручную, взяв цвета из цикла ,

import matplotlib.colors as mcolors
cmap = mcolors.ListedColormap(plt.rcParams['axes.prop_cycle'].by_key()['color'])

Теперь вам нужен способ индексировать цветовую карту, потому что у вас есть отдельные кластеры.

n = len(clusters.unique())
norm = mcolors.BoundaryNorm(np.arange(n+1)-0.5, n)

Конечно, для этого необходимо, чтобы количество цветов в цветовой карте было больше или равно количеству классов, как здесь.

Собираем все вместе (я добавил другую категорию,чтобы сделать его более наглядным)

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import matplotlib.colors as mcolors

plt.style.use('fivethirtyeight') #relevant here!!

X=pd.Series([1, 2, 3, 4, 5, 11, 12, 13, 14, 15])
Y=pd.Series([1,1,1,1,1,2,2,2,2,2])
clusters=pd.Series([0,0,0,0,0,1,1,1,1,2])

cmap = mcolors.ListedColormap(plt.rcParams['axes.prop_cycle'].by_key()['color'])
n = len(clusters.unique())
norm = mcolors.BoundaryNorm(np.arange(n+1)-0.5, n)

plt.figure(figsize = (6, 4))
sc = plt.scatter(X,Y, c=clusters, cmap=cmap, norm=norm)
plt.colorbar(sc, ticks=clusters.unique())
plt.title("example4")

plt.show()

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...