matplotlib 颜色图:set_bad 对集合没有影响

lth*_*ner 5 python plot matplotlib colormap

我想使用 matplotlib 颜色图的 set_bad 参数为 nan 值分配特定颜色。我创建了一个颜色图:

from matplotlib.colors import ListedColormap, BoundaryNorm

cmap = ListedColormap(['green', 'yellow', 'red'])
norm = BoundaryNorm([0, 20, 70, 100], cmap.N)
Run Code Online (Sandbox Code Playgroud)

然后我将坏颜色设置为黑色:

cmap.set_bad(color="k")
Run Code Online (Sandbox Code Playgroud)

为了验证一切按预期工作,我绘制了一个数组作为测试,并且它有效(左下象限是黑色):

import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
im = ax.imshow(np.array([[10, 50], [np.nan, 70]]), cmap=cmap, norm=norm)
fig.colorbar(im, ax=ax)
Run Code Online (Sandbox Code Playgroud)

但是,如果我在集合上使用相同的颜色图,则它不起作用:

from matplotlib.collections import LineCollection
lc = LineCollection(([(0.1, 0.1), (0.1, 0.2)], [(0.2, .2), (0.2, .3)], [(0.3, .3), (0.3, .4)]))

lc.set_cmap(cmap)
lc.set_norm(norm)
lc.set_array(np.array([10, np.nan, 80]))

fig, ax = plt.subplots()
ax.add_collection(lc)
plt.draw()
Run Code Online (Sandbox Code Playgroud)

中间的线有一个 nan z 值并且应该是黑色的,但它显示为绿色。在这种情况下 nan 似乎被解释为 0。

这是一个错误还是有意为之?有谁知道是否可以以不同的方式将 set_bad 与颜色图一起使用?

PS:我用matplotlib 2.2和3.0测试了这个,结果是一样的

Imp*_*est 4

如本期所示和 @EdSmith 的评论,nans 实际上并不是颜色图的有效输入。

相反,nan在将范数和颜色图应用于 a 之前,s 会被屏蔽ScalarMappable。对于 s,此屏蔽需要手动完成Collection

.set_array(np.ma.masked_invalid([10., np.nan, 80.]))
Run Code Online (Sandbox Code Playgroud)

完整示例:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap, BoundaryNorm
from matplotlib.collections import LineCollection

cmap = ListedColormap(['green', 'yellow', 'red'])
cmap.set_bad(color="k")
norm = BoundaryNorm([0, 20, 70, 100], cmap.N)

lc = LineCollection(([(0.1, 0.1), (0.1, 0.2)], [(0.2, .2), (0.2, .3)], [(0.3, .3), (0.3, .4)]))

lc.set_cmap(cmap)
lc.set_norm(norm)
lc.set_array(np.ma.masked_invalid([10., np.nan, 80.]))

fig, ax = plt.subplots()
ax.add_collection(lc)
plt.show()
Run Code Online (Sandbox Code Playgroud)

图像