使用 matplotlib.collections.PolyCollection 制作等高线图时如何不为 nan 值着色

how to not color nan values when making a contour plot with matplotlib.collections.PolyCollection

我正在尝试绘制一个 tri/quad 网格以及该网格上的结果。我正在绘制 CFD 模拟的结果。

我正在使用 matplotlib.collections.PolyCollection 绘图,因为它处理非三元素,而其他方法只支持三元素。

我当前的代码工作正常,但是当我尝试绘制某些单元格没有水的结果时(现在将它们设置为 np.nan),绘图崩溃并且轮廓颜色都搞砸了。

我当前的代码是:

ax = plt.subplot(111)
cmap = matplotlib.cm.jet
polys = element_coords #list of Nx2 np.arrays containing the coordinates of each element polygon)
facecolors = element_values #np array of values at each element, same length as polys
pc = matplotlib.collections.PolyCollection(polys, cmap=cmap)
pc.set_array(facecolors)
ax.add_collection(pc)
ax.plot()

当 element_values 不包含任何 nan 值时,它工作正常并且看起来像这样:

但是,当 element_values 确实包含 nan 值时,它会崩溃并且出现此错误:

C:\Users\deden\AppData\Local\Continuum\anaconda3\envs\test\lib\site-packages\matplotlib\colors.py:527: RuntimeWarning: invalid value encountered in less
  xa[xa < 0] = -1

我试过 element_values 并且可以确认只有当存在 nan 值时才会发生这种情况。

我最初试图忽略 nan 值,这样做只是为了让它们更清楚:

pc.cmap.set_bad(color='white',alpha=0)

但我仍然得到同样的错误。

所以...我尝试将所有 nan 值设置为 -999 然后尝试像这样切断颜色图:

vmin = np.nanmin(facecolors)
vmax = np.nanmax(facecolors)
facecolors[np.isnan(facecolors)] = -999
pc.cmap.set_under(color='white',alpha=0)

然后尝试根据我见过的其他堆栈问题设置颜色图的限制..比如:

pc.cmap.set_clim(vmin,vmax)

但后来我得到:

AttributeError: 'ListedColormap' object has no attribute 'set_clim'

我在这里没有想法...任何人都可以帮助我吗?我只想不为值为 nan 的任何元素着色。

要重现我的错误..您可以尝试使用此虚拟数据:

polys = [np.array([[ 223769.2075899 , 1445713.24572239],
                   [ 223769.48419606, 1445717.09102757],
                   [ 223764.48282055, 1445714.84782264]]),
         np.array([[ 223757.9584215 , 1445716.57576502],
                   [ 223764.48282055, 1445714.84782264],
                   [ 223762.05868674, 1445720.48031478]])]
facecolors = np.array([np.nan, 1]) #will work if you replace np.nan with a number

旁注 - 如果有人知道我如何在没有多集合的情况下绘制这个网格+数据,那就太好了。它包括 3 和 4 面网格元素

Matplotlib 的颜色映射机制来自 numpy.nan 不存在的时代。相反,它适用于屏蔽数组。

facecolors = np.ma.array(facecolors, mask=np.isnan(facecolors))

关于您遇到的其他错误,请注意 .set_clim 是颜色 bar 的属性,而不是颜色map.


最后,如果您的网格仅包含 3 面元素,您可以使用 tripcolor,但这不适用于 4 面网格。