如何使用imshow将NaN值绘制为特定颜色?

108 投票
2 回答
89791 浏览
提问于 2025-04-15 21:15

我想用matplotlib里的imshow函数把数据画成热图,但有些值是NaN(也就是“不是一个数字”的意思)。我希望这些NaN能用一种在颜色图中找不到的特殊颜色来显示。

举个例子:

import numpy as np
import matplotlib.pyplot as plt
f = plt.figure()
ax = f.add_subplot(111)
a = np.arange(25).reshape((5,5)).astype(float)
a[3,:] = np.nan
ax.imshow(a, interpolation='nearest')
f.canvas.draw()

结果图像意外地全是蓝色(在jet颜色图中是最低的颜色)。不过,如果我这样画:

ax.imshow(a, interpolation='nearest', vmin=0, vmax=24)

--那么结果会好一些,但NaN值的颜色和最小值是一样的……有没有什么好的方法可以把NaN用一种特殊颜色(比如灰色或透明)来显示呢?

2 个回答

98

嗯,看起来我可以用一个“掩码数组”来做到这一点:

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

这样应该就够用了,不过我还是欢迎其他建议。 :)

80

在新版本的Matplotlib中,不再需要使用掩码数组了。

比如,我们可以生成一个数组,让每第7个值都是NaN(也就是“不是一个数字”):

arr = np.arange(100, dtype=float).reshape(10, 10)
arr[~(arr % 7).astype(bool)] = np.nan

.cm.get_cmap()这个方法在matplotlib v3.7.0中被替换成了.colormaps.get_cmap('viridis')

你可以用.set_bad来设置颜色。

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

arr = np.arange(100, dtype=float).reshape(10, 10)
arr[~(arr % 7).astype(bool)] = np.nan

cmap = mpl.colormaps.get_cmap('viridis')  # viridis is the default colormap for imshow
cmap.set_bad(color='red')

plt.imshow(arr, cmap=cmap)

plot result


.cm.get_cmap()这个方法已经不推荐使用了

我们可以用下面的代码来修改当前的颜色映射,并绘制这个数组:

current_cmap = mpl.cm.get_cmap()
current_cmap.set_bad(color='red')
plt.imshow(arr)

撰写回答