I'm plotting a surface using matplotlib 1.1.0.
我正在用matplotlib 1.1.0绘制一个表面。
The plot Z axis is masked like so:
图Z轴是这样的:
Zm = ma.masked_where((abs(z_grid) < 1.09) & (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) < 1.09) & (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):
这就是我想要的(从matlab):
What am I missing?
我缺少什么?
2 个解决方案
#1
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.
cmap函数在0和1之间有一个nubmer,所以我们只需要在调用cmap函数之前对值进行规范化。
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 < numpy.sqrt(X[i,j]**2 + Y[i,j]**2) < 1.09:
colours[i,j] = "red"
else:
colours[i,j] = plt.get_cmap("jet")((z_surface[i,j]-min_z) / (max_z - min_z))
surf = ax.plot_surface(X, Y, z_surface, rstride=2, cstride=2, facecolors=colours, linewidth=0, antialiased=False)
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.
我还应该指出,matplotlib将您的z数组转换为real——尽管我不知道您是否有意利用它。
#2
12
Fraxel mentioned that surface_plot doesn't support masking. In order to get around the issue, this is what I did:
Fraxel提到,surface_plot不支持屏蔽。为了避开这个问题,我做了如下的事:
I basically manually masked the z axis data by setting every masked value to numpy.nan like so:
我基本上是通过将每个掩蔽值设置为numpy来手动屏蔽z轴数据。南一样:
Zm = ma.masked_where((abs(z_grid) < 1.02) & (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.
不是100%我想要的,但这是一个很好的妥协。
#1
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.
cmap函数在0和1之间有一个nubmer,所以我们只需要在调用cmap函数之前对值进行规范化。
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 < numpy.sqrt(X[i,j]**2 + Y[i,j]**2) < 1.09:
colours[i,j] = "red"
else:
colours[i,j] = plt.get_cmap("jet")((z_surface[i,j]-min_z) / (max_z - min_z))
surf = ax.plot_surface(X, Y, z_surface, rstride=2, cstride=2, facecolors=colours, linewidth=0, antialiased=False)
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.
我还应该指出,matplotlib将您的z数组转换为real——尽管我不知道您是否有意利用它。
#2
12
Fraxel mentioned that surface_plot doesn't support masking. In order to get around the issue, this is what I did:
Fraxel提到,surface_plot不支持屏蔽。为了避开这个问题,我做了如下的事:
I basically manually masked the z axis data by setting every masked value to numpy.nan like so:
我基本上是通过将每个掩蔽值设置为numpy来手动屏蔽z轴数据。南一样:
Zm = ma.masked_where((abs(z_grid) < 1.02) & (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.
不是100%我想要的,但这是一个很好的妥协。