2016-11-21 45 views
0

说我想区分matplotlib颜色地图中的NaN。然后:在matlotlib颜色地图中使用渐变颜色遮罩两组值颜色编号

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

图: heatmap

现在NaN是在情节容易辨认。

现在,我想能够轻松地区分NaNs,0s和其他值。

如果我现在掩盖了0,我将无法分辨NaN和0。

如何区分颜色映射中的2组值?在这种情况下,一方面是NaN,另一方面是0。

+0

有关问题http://stackoverflow.com/questions/35905393/python-leave-numpy-nan-values-from-matplotlib-heatmap-and-its-legend/35905483#35905483和http://stackoverflow.com/questions/16120481/matplotlib-grayscale-heatmap-with-visually-distinct-na-squares-fields – ImportanceOfBeingErnest

回答

0

我发现this answer来自@unutbu在一个无关的问题。我将他的答案改编成我的问题,并解决了新的舱口也包含在NaN电池中的问题。为了避免这种情况,在屏蔽numpy数组之前,先获取值为0的单元格(我会评论他的回答,以便在上下文中指出这一点,但我没有所需的声望)。我只包括从我的问题更改的代码。

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

新热图: enter image description here

+0

我认为提问者想要一个使用'pcolor'的解决方案。添加很多矩形可能并不总是一个好的解决方案。 – ImportanceOfBeingErnest

2

如果你想告诉你的APPART颜色表的第一个或最后一个值下面的解决方案是一个很好的路要走。您可以修改颜色映射图,使这些值相当容易变成不同的颜色

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. 

这是一个完整的解决方案。

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