2016-11-21 2 views
0

Angenommen, ich möchte die NaNs in einer Matplotlib Colormap unterscheiden. Dann:Maskieren Sie zwei Gruppen von Werten in Matlotlib Colormap mit graduellem Farbschema

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() 

Plots: heatmap

Jetzt NaNs sind leicht erkennbar in der Handlung.

Nun sagen, ich möchte in der Lage sein, leicht unterscheiden zwischen NaNs, 0s und den Rest der Werte.

Wenn ich jetzt die 0s maskiere, kann ich die NaNs und die 0s nicht unterscheiden.

Wie kann ich zwei Gruppen von Werten in einer Colormap unterscheiden? In diesem Fall NaNs einerseits und Nullen andererseits.

+0

Relevante Fragen hier Herstellung sind http://stackoverflow.com/questions/35905393/python-leave-numpy-nan-values-from-matplotlib-heatmap-and-its-legend/35905483 # 35905483 und http://stackoverflow.com/questions/16120481/matplotlib-grayscale-heatmap-with-visual-distinct-na-squares-fields – ImportanceOfBeingErnest

Antwort

0

Ich fand this answer von @unutbu in einer nicht verwandten Frage. Ich habe seine Antwort auf mein Problem angepasst und auch das Problem behoben, dass die neuen Luken auch in den NaN-Zellen enthalten sind. Um dies zu vermeiden, rufen Sie die Zellen mit dem Wert 0 ab, bevor Sie das Array numpy maskieren (ich würde seine Antwort kommentieren, um dies im Zusammenhang zu zeigen, aber ich habe nicht die erforderliche Reputation). Ich schließe nur Code ein, der von meiner Frage geändert wurde.

# (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() 

New Heatmap: enter image description here

+0

Ich denke, der Fragesteller will eine Lösung mit 'pcolor'. Das Hinzufügen vieler Rechtecke ist möglicherweise nicht immer eine gute Lösung. – ImportanceOfBeingErnest

2

Falls Sie den ersten oder letzten Wert Ihrer colormap die folgende Lösung sagen, appart ist ein guter Weg zu gehen. Sie können die Colormap so ändern, dass diese Werte ganz einfach eine andere Farbe annehmen.

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. 

Hier ist eine vollständige Lösung.

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() 

enter image description here