Как изменить маркер графика подмножества точек при использовании функции разброса Matplotlib в Python 3 - PullRequest
1 голос
/ 01 октября 2019

У меня есть много пользовательских 2d точечных объектов, каждый из которых имеет:

  • координаты x и y
  • метка 1 ° (целое число от -1 до + inf): это будет представленов цвете маркеров (индекс cmap)
  • метка 2 ° (целое число в диапазоне [1 3]): я хочу, чтобы этот был представлен в типе маркера

Дело в том, что многие точки будут иметь значение метки 1 °, но могут отличаться на метке 2 ° и наоборот.

Я попытался извлечь точки, относящиеся к значению метки 2 °, и построить их отдельно, таким образом:

pointsSubset1 = getPointsWithLabel2Value1()
pointsSubset2 = getPointsWithLabel2Value2()
pointsSubset3 = getPointsWithLabel2Value3()

# just assume x y and labels values are obtained correctly

plt.scatter(x1, y1, c=listOfLabels1ForSubset1, cmap="nipy_spectral", marker='s') # plotting pointsSubset1

plt.scatter(x2, y2, c=listOfLabels1ForSubset2, cmap="nipy_spectral", marker='.') # plotting pointsSubset2

plt.scatter(x3, y3, c=listOfLabels1ForSubset3, cmap="nipy_spectral", marker='<') # plotting pointsSubset3

Я думал, что это будет работать, но это не так. Маркеры установлены правильно, но не цвета ...

Пример игнорирования координат x и y:

  • subset1 =

    • point1:
      • label1: -1
      • label2: 1
  • subset2 =

    • point2:
      • label1: 1
      • label2: 2

В этом случае point1 из подмножества1 будету маркера, отличного от point2, от subset2, но оба будут иметь один и тот же цвет (черный), потому что, когда они отображаются отдельно, хотя они имеют разные значения label1, оба будут отображены на первый цвет в спектре ....

Я хочу, чтобы индексы цветов в cmap совпадали между подмножествами точек, и я не думаю, что передача пользовательского массива цветов - это решение, поскольку метка 1 возможных значений находится в диапазоне [-1, + inf](и я не знаю, как управлять нормализацией cmap).

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 01 октября 2019

Я думаю, добрался бы туда, куда ты хочешь

Npoints = 50
x,y = np.random.random(size=(2,Npoints))
label1 = np.random.choice([-1,1,2,3], size=(Npoints,))
label2 = np.random.choice([1,2,3],size=(Npoints,))

label1_min = min(label1)
label1_max = max(label1)
marker_dict = {1:'s',2:'o',3:'<'}

fig, ax = plt.subplots()
for i,m in marker_dict.items():
    ax.scatter(x[label2==i], y[label2==i], marker=m, c=label1[label2==i], cmap='nipy_spectral', vmin=label1_min, vmax=label1_max)

enter image description here

0 голосов
/ 01 октября 2019

Простой способ:

Я поделюсь тем, что нашел, на случай, если кто-то столкнется с той же проблемой. Оказывается, вы можете вызвать plt.scatter () один раз и предоставить массив пользовательских размеров для маркеров. Таким образом, вы можете «играть», изменяя размер маркера в соответствии с заданным критерием (в моем случае это значение метки 2), и вы можете видеть разницу между подмножествами точек при построении.

Это было бы что-то вродеэто:

s = getMarkerCustomSizeForEachPoint()
# x is a list of every x coordinate
# y is a list of every y coordinate
# clusters is a list of every point label (label 1 value in my case)
# marker='s' -> squares
plt.scatter(x, y, c=clusters, cmap="nipy_spectral", marker='s', alpha=0.8, s=s)

Установка размера маркера на действительно маленькое число, это почти как наличие точек, поэтому вы можете использовать квадраты и 'точки', пока вы только указываете marker = 's':)

Помните, что при создании разных списков совпадающие индексы представляют одну и ту же точку (в x, y, кластерах и с)

enter image description here

...