2016-11-21 1 views
0

Dites que je veux distinguer les NaNs dans un colormap matplotlib. Puis:Masque deux groupes de valeurs dans matormlib colormap avec colorscheme progressive

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

# create a (4,5) matrix with values ranging from 0 to 19 
np_data = np.arange(20).reshape((4,5)).astype(float) 
# add a row with NaNs in the middle 
np_data = np.insert(np_data,2,[np.nan for x in range(0,5)],axis=0) 
# mask invalid data (NaNs) 
np_data = np.ma.masked_invalid(np_data) 

# get figure and ax objects from plot 
fig, ax = plt.subplots() 
# Draw an "X" on transparent values (masked values) 
ax.patch.set(hatch='x', edgecolor='blue') 

# get a predefined color scheme 
reds_cm = plt.get_cmap("Reds") 
# Plot heatmap, add a colorbar and show it 
heatmap = ax.pcolor(np_data, cmap=reds_cm) 
cbar = fig.colorbar(heatmap) 
plt.show() 

Terrains à bâtir: heatmap

maintenant NaN sont facilement identifiables dans l'intrigue. Maintenant, disons que je veux être capable de distinguer facilement entre les NaNs, les 0 et le reste des valeurs.

Si je masque maintenant les 0, je ne serai pas capable de distinguer les NaN et les 0. Comment puis-je différencier 2 groupes de valeurs dans une palette de couleurs? Dans ce cas, NaNs d'une part et 0s de l'autre.

+0

Des questions pertinentes ici sont http://stackoverflow.com/questions/35905393/python-leave-numpy-nan-values-from-matplotlib-heatmap-and-its-legend/35905483 # 35905483 et http://stackoverflow.com/questions/16120481/matplotlib-grayscale-heatmap-with-visually-distinct-na-squares-fields – ImportanceOfBeingErnest

Répondre

0

J'ai trouvé this answer de @unutbu dans une question sans rapport. J'ai adapté sa réponse à mon problème et ai également fixé le problème que les nouvelles trappes sont également incluses dans les cellules de NaN. Pour éviter cela, il suffit d'obtenir les cellules avec la valeur 0 avant de masquer le tableau numpy (je voudrais commenter sa réponse pour le signaler dans son contexte mais je n'ai pas la réputation requise). J'inclus seulement le code changé de ma question.

# (previous imports) 
# Import to add patches to "non transparent" cells 
import matplotlib.patches as mpatches 


# (generate np_data) 

# Get mask positions of 0 values before masking NaNs so NaN cells aren't included 
cells_with_0 = np_data == 0 
# mask invalid data (NaNs) 
np_data = np.ma.masked_invalid(np_data) 

# (get color scheme, plot heatmap, plot colorbar) 

#set the background color as gray so the transparent values (NaNs here) use that color 
ax.patch.set_facecolor((0.6, 0.6, 0.6, 1.0)) 
# Draw an "X" on transparent values (masked values) 
ax.patch.set(hatch='x', edgecolor='black') 
# Put an x over cells which have value 0 
for j, i in np.column_stack(np.where(cells_with_0)): 
     ax.add_patch(
      mpatches.Rectangle(
       (i, j),  # (x,y) 
       1,   # width 
       1,   # height 
       fill=False, 
       edgecolor='blue', 
       snap=False, 
       hatch='x' # the more slashes, the denser the hash lines 
     )) 

plt.show() 

Nouveau heatmap: enter image description here

+0

Je pense que le questionneur veut une solution en utilisant 'pcolor'. Ajouter beaucoup de rectangles n'est pas toujours une bonne solution. – ImportanceOfBeingErnest

2

Si vous voulez dire la première ou appart dernière valeur de votre colormap la solution suivante est une bonne façon d'aller. Vous pouvez modifier la palette de couleurs de sorte que ces valeurs deviennent assez facilement une couleur différente

reds_cm = plt.get_cmap("name of colormap") 
# init colormap such that its members are available 
reds_cm._init() 
# set the first value to black 
reds_cm._lut[0,: ] = (0,0,0,1) #this is an RGBA tuple 
# set the last value to lightgreen 
reds_cm._lut[-4:,: ] = np.array([149,238,58,255])/255. 

Voici une solution complète.

import numpy as np 
import matplotlib.pyplot as plt 

# create a (4,5) matrix with values ranging from 0 to 19 
np_data = np.arange(20).reshape((4,5)).astype(float) 
# add a row with NaNs in the middle 
np_data = np.insert(np_data,2,[np.nan for x in range(0,5)],axis=0) 
# mask invalid data (NaNs) 
np_data = np.ma.masked_invalid(np_data) 

# get figure and ax objects from plot 
fig, ax = plt.subplots() 
# Draw an "X" on transparent values (masked values) 
ax.patch.set(hatch='x', edgecolor='blue') 

# get a predefined color scheme 
reds_cm = plt.get_cmap("Reds") 
# init colormap such that its members are available 
reds_cm._init() 
# set the first value to black 
reds_cm._lut[0,: ] = (0,0,0,1) 
# set the last value to lightgreen 
reds_cm._lut[-4:,: ] = np.array([149,238,58,255])/255. 

# Plot heatmap, add a colorbar and show it 
heatmap = ax.pcolor(np_data, cmap=reds_cm) 
cbar = fig.colorbar(heatmap) 
plt.show() 

production enter image description here