I am trying to plot a tri/quad mesh along with results on that mesh. I am plotting results of a CFD simulation.
I am using matplotlib.collections.PolyCollection to plot because it handles non-tri elements, where other methods only support tri elements.
my current code works fine, but when I try to plot results where some cells have no water (have them set to np.nan right now), the plotting crashes and the contour colors get all screwed up.
My current code is:
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()
When element_values does not contain any nan values, it works fine and looks something like this:

However, when element_values does contain nan values, it crashes and I get this error:
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
I played around with element_values and can confirm this only happens when nan values are present.
I initially tried to ignore the nan values by doing this just to make them clear:
pc.cmap.set_bad(color='white',alpha=0)
But I still get the same error.
So... I tried setting all the nan values to -999 then trying to cut off the colormap like this:
vmin = np.nanmin(facecolors)
vmax = np.nanmax(facecolors)
facecolors[np.isnan(facecolors)] = -999
pc.cmap.set_under(color='white',alpha=0)
then tried to set the limits of the colormap based on other stack questions I've seen..like:
pc.cmap.set_clim(vmin,vmax)
but then I get:
AttributeError: 'ListedColormap' object has no attribute 'set_clim'
I'm out of ideas here...can anyone help me? I just want to NOT COLOR any element where the value is nan.
To reproduce my error..you can try using this dummy data:
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
SIDE NOTE - if anyone knows how I can plot this mesh+data without polycollections that'd be great..it includes 3 and 4 sided mesh elements
Matplotlib's colormapping mechanics come from a time when numpy.nan wasn't around. Instead it works with masked arrays.
facecolors = np.ma.array(facecolors, mask=np.isnan(facecolors))
Concerning the other error you get, note that .set_clim is an attribute of the colorbar, not the colormap.
Finally, if your mesh contained only 3-sided elements, you could use tripcolor, but that won't work with 4-sided meshes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With