Отображение нескольких масок разными цветами в pylab

У меня есть массив, который включает достойные наблюдения, нерелевантные наблюдения (которые я хотел бы замаскировать) и области, где нет наблюдений (которые я также хотел бы замаскировать). Я хочу отобразить этот массив как изображение (используя pylab.imshow) с двумя отдельными масками, где каждая маска отображается другим цветом.

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

masked_array = np.ma.array (a, mask=np.isnan(a))
cmap = matplotlib.cm.jet
cmap.set_bad('w',1.)
ax.imshow(masked_array, interpolation='nearest', cmap=cmap)

Если возможно, я бы хотел избежать использования сильно искаженной цветовой карты, но согласен с тем, что это вариант.


person user1824335    schedule 14.11.2012    source источник
comment
Да, это 2D-массив, заполненный числами с плавающей запятой.   -  person user1824335    schedule 14.11.2012


Ответы (4)


Вы можете просто заменить значения в своем массиве некоторым фиксированным значением в зависимости от некоторых условий. Например, если вы хотите замаскировать элементы больше 1 и меньше -1:

val1, val2 = 0.5, 1
a[a<-1]= val1
a[a>1] = val2
ax.imshow(a, interpolation='nearest')

val1 и val2 можно изменить для получения желаемых цветов.

Вы также можете указать цвета явно, но для этого потребуется дополнительная работа:

import matplotlib.pyplot as plt
from matplotlib import colors, cm

a = np.random.randn(10,10)

norm = colors.normalize()
cmap = cm.hsv
a_colors = cmap(norm(a))

col1 = colors.colorConverter.to_rgba('w')
col2 = colors.colorConverter.to_rgba('k')

a_colors[a<-0.1,:] = col1
a_colors[a>0.1,:] = col2
plt.imshow(a_colors, interpolation='nearest')
plt.show()
person btel    schedule 14.11.2012
comment
Это сработает, хотя мне нужно будет явно установить цвет маски, поскольку val1 может быть любым значением, и я не хочу, чтобы он мог искажать отображаемые цвета (например, если мой диапазон значений данных составляет 0-1, а значение val1 равно -999). Какой метод, о котором вы говорите, позволил бы мне явно установить цвет? - person user1824335; 14.11.2012
comment
@ user1824335 Я добавил в свой ответ полную реализацию с явным выбором цвета. - person btel; 14.11.2012

Для меня самый простой способ - рисовать маски напрямую с помощью imshow, передавая разные цветовые карты. Максимальное и минимальное значение цветовой карты используется для значений True и False:

mask1=np.isnan(a)
mask2=np.logical_not(mask1)
plt.imshow(mask1,cmap='gray')
plt.imshow(mask2,cmap='rainbow')

введите описание изображения здесь

Однако этот (и другие предлагаемые подходы) график также ложных значений перекрывает предыдущие графики. Если вы хотите избежать построения значений False, это можно сделать, заменив их на np.nan после преобразования массива в float (np.nan имеет тип float и не может содержаться в логической маске). Значения nan не отображаются:

mmm=mask.astype(np.float)
mmm[np.where(mmm==0)]=np.nan
#the substitution can be done also in one line with:
#mmm=np.where(mask,mask.astype(np.float),np.nan)
plt.imshow(mmm,cmap='rainbow',vmin=0,vmax=1)) #will use only the top color: red. vmin and vmax are needed if there are only one value (1.0=True) in the array.
plt.colorbar()
#repeat for other masks...

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

plt.imshow(mmm*data,cmap='rainbow')

введите описание изображения здесь

person Vincenzooo    schedule 04.12.2015

Чтобы окрасить одни пиксели в красный цвет, а другие в зеленый, как показано на следующем изображении, я использовал приведенный ниже код. (Подробности см. В комментариях к коду.)

Пример использования двух масок с графиком матрицы matplotlib

import numpy as np              #Used for holding and manipulating data
import numpy.random             #Used to generate random data
import matplotlib as mpl        #Used for controlling color
import matplotlib.colors        #Used for controlling color as well
import matplotlib.pyplot as plt #Use for plotting

#Generate random data
a = np.random.random(size=(10,10))

#This 30% of the data will be red
am1 = a<0.3                                 #Find data to colour special
am1 = np.ma.masked_where(am1 == False, am1) #Mask the data we are not colouring

#This 10% of the data will be green
am2 = np.logical_and(a>=0.3,a<0.4)          #Find data to colour special
am2 = np.ma.masked_where(am2 == False, am2) #Mask the data we are not colouring

#Colourmaps for each special colour to place. The left-hand colour (black) is
#not used because all black pixels are masked. The right-hand colour (red or
#green) is used because it represents the highest z-value of the mask matrices
cm1 = mpl.colors.ListedColormap(['black','red'])
cm2 = mpl.colors.ListedColormap(['black','green'])

fig = plt.figure()                          #Make a new figure
ax = fig.add_subplot(111)                   #Add subplot to that figure, get ax

#Plot the original data. We'll overlay the specially-coloured data
ax.imshow(a,   aspect='auto', cmap='Greys', vmin=0, vmax=1)

#Plot the first mask. Values we wanted to colour (`a<0.3`) are masked, so they
#do not show up. The values that do show up are coloured using the `cm1` colour
#map. Since the range is constrained to `vmin=0, vmax=1` and a value of
#`cm2==True` corresponds to a 1, the top value of `cm1` is applied to all such
#pixels, thereby colouring them red.
ax.imshow(am1, aspect='auto', cmap=cm1, vmin=0, vmax=1);
ax.imshow(am2, aspect='auto', cmap=cm2, vmin=0, vmax=1);
plt.show()
person Richard    schedule 25.06.2018

Я не знаю, какие значения находятся в вашем массиве, но вы можете преобразовать замаскированные области так, чтобы значения X стали значениями RGB (A) (кортежи (R,G,B,A)), и в этом случае cmap игнорируется в соответствии с документация по крайней мере.

• cmap: [Нет | Цветовая карта]

Экземпляр matplotlib.colors.Colormap, например. cm.jet. Если нет, по умолчанию используется значение rc image.cmap. cmap игнорируется, если X имеет информацию RGB (A)

person Matti Lyra    schedule 14.11.2012
comment
Спасибо, но поскольку массив заполнен данными с плавающей запятой, я не могу использовать RGB (A), если я не ошибаюсь в этом? - person user1824335; 14.11.2012
comment
Нет, идея состоит в том, что вы заменяете все, что когда-либо в массиве, на цвет RGBA, который вы хотите использовать для графика. - person Matti Lyra; 14.11.2012