#python #matplotlib #colors #scatter-plot #scatter
#python #matplotlib #Цвет #точечный график #разброс
Вопрос:
Я пытаюсь построить точечный график, где каждая точка на точечном графике должна соответствовать определенному оттенку заданного цвета по моему выбору. В документации mpl указано, что если я установлю что-то вроде:
color = '0.7'
это дает мне оттенок серого с такой масштабируемой интенсивностью 0.7
. Я считываю интенсивность цветов из массива со значениями от 0 до 1, и каждое значение соответствует интенсивности этой точки на точечной диаграмме. Мой приведенный ниже код выглядит следующим образом:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
import math
tsne_embeddings = np.load("tsne_embeddings.npy")
labels = np.load('labels.npy')
weights = np.load('weights.npy')
# Scale the weights from 0 to 1
max_weight = max(weights)
min_weight = min(weights)
weights = (weights - min_weight)/(max_weight - min_weight)
print(tsne_embeddings.shape)
x = list(tsne_embeddings[:,0])
y = list(tsne_embeddings[:,1])
labels = list(labels)
weights = np.round(weights,decimals=2)
weights = (np.exp(weights) - 1)/(np.exp(1) - 1)
weights = list(weights)
print(min(weights),max(weights))
for i, shade in enumerate(weights):
plt.scatter(x[i],y[i],color=shade,marker = ' ')
plt.show()
Я масштабирую эти веса экспоненциально, надеясь на лучшее изменение.
Итак, по сути, мои вопросы:
- Как мне изменить цвет, скажем, на оттенки синего, красного или зеленого, а не только на оттенки серого?
- Правильный ли подход, которому я следую для оттенков серого?
Спасибо!
Ответ №1:
Чтобы ваш подход работал для оттенков серого, вам нужно преобразовать значение в строку, так plt.scatter(..., color=str(shade))
что .
Более стандартным способом работы с matplotlib было бы прямое использование весов, без их масштабирования до диапазона 0
1
, использование цветовой карты и вызов scatter напрямую с массивами. Веса входят в c=
параметр. Для значений серого это будет plt.scatter(x, y, c=weights, cmap='Greys', marker=' ')
. Дополнительной особенностью matplotlib является то, что с помощью этой информации он может автоматически создавать цветовую панель, сопоставляющую значения серого с соответствующим весом. Если создается только один точечный график, plt.colorbar()
без параметров будет отображаться эта цветовая панель.
Аналогичные цветовые карты существуют для «пурпурных», «синих», «зеленых», «оранжевых», «красных», … Смотрите Официальный документ с полным списком. Если диапазон между светлым и темным идет не так, добавление ‘_r’ к имени будет использовать противоположный цветовой диапазон (так, ‘Greys’ переходит от белого к черному, а ‘Greys_r’ переходит от черного к белому).
Вот рабочий пример, использующий значения от 1 до 10 для трех массивов:
from matplotlib import pyplot as plt
import numpy as np
x = np.arange(1, 11)
y = np.arange(1, 11)
weights = np.arange(1, 11)
plt.scatter(x, y, c=weights, cmap='Greys', marker=' ')
plt.colorbar()
plt.show()
Ответ №2:
Вы можете использовать colormaps в python для генерации различных оттенков синего, зеленого и т.д. https://matplotlib.org/3.1.0/tutorials/colors/colormaps.html Здесь я использую карту синего цвета
import matplotlib.pyplot as plt
import matplotlib as mpl
norm = mpl.colors.Normalize(vmin=min(weights), vmax=max(weights))
cmap = mpl.cm.ScalarMappable(norm=norm, cmap=mpl.cm.Blues)
for i, xi in enumerate(x):
plt.scatter(x[i],y[i],color=cmap.to_rgba(i 1),marker = ' ')
plt.show()
Комментарии:
1. Большое спасибо! Как мне точно передать свои веса? Или это передается автоматически в norm = mpl.colors . ……… строка, когда вызываются max и min? По сути, мой вопрос в том, как я
scatter
узнаю, откуда tp выбирает веса?