Значения NaN как особый цвет на графике рассеяния пиплота - PullRequest
1 голос
/ 03 мая 2019

У меня есть график рассеяния (x, y), где каждая точка связана с цветом.Однако некоторые точки не имеют правильного цвета и им назначается NaN.Я хотел бы включить эти точки, но показать их цветом, не содержащимся в карте цветов.

Вот пример кода:

import numpy as np
import matplotlib.colors as mcol
import matplotlib.pyplot as plt

numPoints = 20
nanFrequency = 3
xVec = np.arange(numPoints, dtype=float)
yVec = xVec
colorVec = np.linspace(0,1,numPoints)
colorVec[range(0, numPoints, nanFrequency)] = np.nan

colormap = mcol.LinearSegmentedColormap.from_list("Blue-Red-Colormap", ["b", "r"])

plt.scatter(xVec, yVec, c=colorVec, cmap=colormap)

и соответствующий вывод: Scatter plot not showing points with invalid color

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

Обратите внимание, что есть связанный пост, касающийся imshow () , из которого вдохновлен приведенный выше код.Представленное здесь решение, похоже, не работает для меня.

Заранее большое спасибо.

Ответы [ 2 ]

2 голосов
/ 03 мая 2019

Конечно, вам нужно установить желаемый желтый цвет для вашей карты цветов, colormap.set_bad("yellow").

Итак, это давняя ошибка в matplotlib ( # 4354 ), которая, к счастью, теперь исправлена ​​( # 12422 ).

Таким образом, начиная с matplotlib 3.1 и далее, вы можете использовать аргумент plotnonfinite=True для включения маскированных или недействительных точек в точечные диаграммы.

import numpy as np
import matplotlib.colors as mcol
import matplotlib.pyplot as plt

numPoints = 20
nanFrequency = 3
xVec = np.arange(numPoints, dtype=float)
yVec = xVec
colorVec = np.linspace(0,1,numPoints)
colorVec[range(0, numPoints, nanFrequency)] = np.nan

colormap = mcol.LinearSegmentedColormap.from_list("Blue-Red-Colormap", ["b", "r"])
colormap.set_bad("yellow")

plt.scatter(xVec, yVec, c=colorVec, cmap=colormap, plotnonfinite=True)

plt.show()

enter image description here

1 голос
/ 03 мая 2019

Причина, по которой ваши значения NaN не отображаются, состоит в том, что разброс matplotlib в настоящее время отфильтровывает их перед передачей их в карту цветов.

Для отображения записей NaN вы можете вручную назначить им фиктивное значениес особым смыслом.Например, поскольку ваш список находится в диапазоне [0, 1], вы можете определить, что любое значение > 1 получает специальный цвет.Для этого вам нужно будет зафиксировать диапазон цветовой оси и указать цвет для записей за пределами этого диапазона (в данном случае выше максимального).

В основном вы будете использовать:

cax = ax.scatter(...)
cax.cmap.set_over('y') # assigns yellow to any entry >1
cax.set_clim(0, 1)     # fixes the range of 'normal' colors to (0, 1)

Для вашего примера:

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

numPoints = 20
nanFrequency = 3
xVec = np.arange(numPoints, dtype=float)
yVec = xVec
colorVec = np.linspace(0,1,numPoints)
colorVec[range(0, numPoints, nanFrequency)] = np.NaN

cmap = mpl.colors.LinearSegmentedColormap.from_list("Blue-Red-Colormap", ["b", "r"], numPoints)

# ---

fig, axes = plt.subplots(nrows=2, figsize=(8, 2*6))

# ---

ax = axes[0]

ax.scatter(xVec, yVec, c=colorVec, cmap=cmap)

ax.set_xlim([0, 20])
ax.set_ylim([0, 20])

# ---

ax = axes[1]

colorVec[np.isnan(colorVec)] = 2.0

cax = ax.scatter(xVec, yVec, c=colorVec, cmap=cmap)
cax.cmap.set_over('y')
cax.set_clim(0, 1)

ax.set_xlim([0, 20])
ax.set_ylim([0, 20])

# ---

plt.show()

, который создает два вспомогательных участка: верхний соответствует тому, что у вас было, нижний использует фиктивное значение и присваивает ему желтый:

enter image description here

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