Plotting a masked surface plot using python, numpy and matplotlib

匿名 (未验证) 提交于 2019-12-03 00:46:02

问题:

I'm plotting a surface using matplotlib 1.1.0.

The plot Z axis is masked like so:

Zm = ma.masked_where((abs(z_grid)  0.91), (z_surface)) surf = ax.plot_surface(X, Y,Zm, rstride=2, cstride=2, cmap=colors,linewidth=0, antialiased=False) 

But I'm not seeing the mask applied on the plot. I plotted the mask itself as a subplot

surf = ax.plot_surface(X, Y,ma.getmask(Zm), rstride=2, cstride=2, cmap=colors,linewidth=0, antialiased=False) 

Which worked, so I know my mask does actually contain True values.

Full code:

from pylab import * import matplotlib.pyplot as plt from matplotlib.widgets import Button import numpy from mpl_toolkits.mplot3d.axes3d import Axes3D from  matplotlib import patches from matplotlib.figure import Figure from matplotlib import rcParams   fig = plt.figure(figsize=plt.figaspect(0.5)) ax = fig.add_subplot(1, 2, 1,projection='3d')  pole_positions_orig = [-0.6+0.73j]; zero_positions_orig = [0.29-0.41j];  surface_limit = 1.7; min_val = -surface_limit; max_val = surface_limit;  surface_resolution = 0.0333;  X = numpy.arange(min_val,max_val,surface_resolution) Y = numpy.arange(min_val,max_val,surface_resolution) X, Y = numpy.meshgrid(X, Y)  z_grid = X + Y*1j; z_surface = z_grid*0;  pole_positions = numpy.round(pole_positions_orig,1) + surface_resolution/2+(surface_resolution/2)*1j; zero_positions = numpy.round(zero_positions_orig,1) + surface_resolution/2 +(surface_resolution/2)*1j;  for k in range(0, len(zero_positions)):     z_surface = z_surface + 20*log10((z_grid - zero_positions[k].real - zero_positions[k].imag*1j));     z_surface = z_surface + 20*log10((z_grid - zero_positions[k].real + zero_positions[k].imag*1j));  for k in range(0, len(pole_positions)):     z_surface = z_surface - 20*log10((z_grid - pole_positions[k].real - pole_positions[k].imag*1j));     z_surface = z_surface - 20*log10((z_grid - pole_positions[k].real + pole_positions[k].imag*1j));       colors = cm.jet; colors.set_bad('k');   Zm = ma.masked_where((abs(z_grid)  0.91), (z_surface))  z_surface = Zm;  surf = ax.plot_surface(X, Y,z_surface, rstride=2, cstride=2, cmap=colors,linewidth=0, antialiased=False)   ticks = [-1, 1];  z_ticks = [-30,-20,-10,0,10,20,30];  ax.set_xticks(ticks); ax.set_yticks(ticks);    ax.set_zticks(z_ticks);  ax.set_xlabel('Re') ax.set_ylabel('Im') ax.set_zlabel('Mag(db)',ha='left') plt.setp(ax.get_zticklabels(), fontsize=7) plt.setp(ax.get_xticklabels(), fontsize=7)   plt.setp(ax.get_yticklabels(), fontsize=7)  ax = fig.add_subplot(1, 2, 2,projection='3d') surf = ax.plot_surface(X, Y,ma.getmask(z_surface), rstride=2, cstride=2, cmap=colors,linewidth=0, antialiased=False)  ax.grid(b=None); show(); 

This is what I have:

This is what I want (from matlab):

What am I missing?

回答1:

You can do it, but you need to do it by manually colouring the surface faces yourself;

the cmap function takes a nubmer between 0 and 1, so we just need to normalise the values before calling the cmap function on them.

z_surface = numpy.real(z_surface) min_z, max_z = z_surface.min(), z_surface.max() colours = numpy.zeros_like(z_surface, dtype=object)  for i in range(len(z_surface)):   for j in range(len(z_surface[0])):     if 0.91 

I should also point out that matplotlib is casting your z array to real - whether or not you are taking advantage of this on purpose though i don't know.



回答2:

Fraxel mentioned that surface_plot doesn't support masking. In order to get around the issue, this is what I did:

I basically manually masked the z axis data by setting every masked value to numpy.nan like so:

Zm = ma.masked_where((abs(z_grid)  0.98), (z_surface)) z_surface[where(ma.getmask(Zm)==True)] = numpy.nan 

However, it messed up my colormap scaling. To fix that, I did this:

cmap = cm.jet lev = numpy.arange(-30,30,1); norml = colors.BoundaryNorm(lev, 256)  surf = ax.plot_surface(X, Y, z_surface,...,norm = norml) 

Not 100% what I wanted, but a good compromise nonetheless.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!