如何在Mayavi的网格图中使用掩码?

4
我正在使用Python和Mayavi2进行3D绘图。我正在使用mesh命令绘制一个球体,现在我想将球体的某些面板涂成不同的颜色。似乎mask选项就是为此而设的,但我无法使其正常工作(整个球体都被重新涂色)。
参考网页:http://docs.enthought.com/mayavi/mayavi/auto/mlab_helper_functions.html#mayavi.mlab.mesh “mask:用于抑制一些数据点的布尔掩码数组”
我的代码如下:
mesh(X,Y,Z, color = (1,1,1), opacity=0.5)

将整个球体涂成白色,然后

mesh(X,Y,Z, color = (1,0,1), mask = active_region, opacity=0.5) 

把一些部分涂成紫色,其中包括:
active_region = [[False False False False False False  True]
                 [False False False False False False  True]
                 [False False False False False  True  True]
                 [False False False  True  True  True  True]
                 [False False  True  True  True  True  True]
                 [False False False  True  True  True  True]
                 [False False False False False False  True]]

但是这会导致完全紫色的球体。X、Y和Z都是形状为(7,7)的数组,就像active_region一样。我做错了什么?


嗯,应该可以了。如果所有的值都是True或False会发生什么? - M4rtini
1个回答

3
掩码基于标量而不是设置了纯色时运作。请尝试使用以下方法代替:

import numpy as np
m = mesh(X,Y,Z, mask=active_region, opacity=0.5)
m.mlab_source = ones_like(X)

掩蔽功能通过在掩蔽的位置设置标量为NaN来实现。绘制的几何形状相同,但如果标量为NaN,则不会显示掩蔽区域。

无论如何,这里是一个完整的工作示例供您参考:

import numpy as np
phi, theta = np.mgrid[0:np.pi:100j, 0:2 * np.pi:100j]
x = np.sin(phi) * np.cos(theta)
y = np.sin(phi) * np.sin(theta)
z = np.cos(phi)
mask = np.zeros_like(x).astype(bool)
mask[::5] = True
mask[:,::5] = True

from mayavi import mlab
mlab.mesh(x, y, z, scalars=z, mask=mask)

请注意,您不需要提供标量值,只是如果提供了显式颜色,就不会进行掩码操作。此处的标量值仅设置为z,您可以使用任何兼容的数组,甚至是通过ones_like(X)设置的常量值。
事实证明,如果您有一个恒定的标量值,VTK 5.6似乎无法正确地屏蔽您的点;如果您有VTK 5.10,则可以执行以下操作:
m = mlab.mesh(x, y, z, scalars=scalars, mask=mask)
m.module_manager.scalar_lut_manager.lut.nan_color = 0, 0, 0, 0

否则,请使用scalar=z并设置一个恒定颜色查找表。您可以通过在管道编辑器上单击“颜色和图例”,然后单击“启动lut编辑器”来创建自己的颜色映射表。要使用此自定义颜色映射,请执行以下操作:
scalars = np.ones_like(x)
m = mlab.mesh(x, y, z, scalars=scalars, mask=mask)
m.module_manager.scalar_lut_manager.lut_mode = 'file'
m.module_manager.scalar_lut_manager.file_name = '/path/to/your.lut'

如果你不想与LUT编辑器及其它繁琐的东西打交道,这里有一个纯粹的Numpy版本,您可以直接从Python中使用。

m = mlab.mesh(x, y, z, scalars=z, mask=mask)
# Lets make some colors:
#    this is an array of (R, G, B, A) values (each in range 0-255), there should
#    be at least 2 colors in the array.
colors = np.zeros((2, 4), dtype='uint8')
# Set the green value to constant.
colors[:,1] = 255
# the alpha value to fully opaque.
colors[:,3] = 255
# Now use this colormap.
m.module_manager.scalar_lut_manager.lut.table = colors

请注意,颜色数组应该至少有2个颜色,可以有任意多个。对于一个固定的颜色,两个就足够了。
希望这有帮助。

感谢一直以来的帮助,但我仍然遇到问题。我尝试了更新后的示例,但仍然没有看到任何掩模效果。你能否附上你得到的输出图片?我的版本信息:Mayavi版本4.0.0 - VTK版本5.6.0 Python 2.7.2 | EPD 7.1-2 wxPython 2.8.10.1我也不理解什么是标量,你能解释一下或给我一个参考吗? - capybaralet
我升级到版本 4.3.0 - VTK 版本 5.6.0 Python 2.7.3 | 64 位 | Qt 1.1.2,现在它可以正常工作了!谢谢! - capybaralet
我仍然非常想知道“scalars”参数是如何工作的。当我尝试使用ones_like(X)时,遮罩似乎被关闭了,整个球体仍然变成蓝色。 - capybaralet
是的,我无法使用掩码来使其工作,除非使用标量=z,就像你所做的那样,或者标量=x或y。因此,到目前为止,我的假设是它必须是前三个变量之一,这对于我尝试做的事情真的不起作用。我需要一种自己设置颜色的方法。 - capybaralet
你说得对,在这方面似乎存在一个VTK错误,因此常量标量似乎无法正常工作。如果您有可用的VTK-5.10,则可以解决此问题,但似乎您没有那个版本。 "scalars"是与数据中每个点相关联的标量属性,并且通过查找表将数据显示为颜色。掩蔽通过将所有“Nan”值转换为透明颜色来实现,但某种方式使用恒定颜色时,VTK似乎无法使其透明。您的一个选择是创建一个lut文件并使用其中的恒定颜色。 - Prabhu Ramachandran
顺便提一下,我已经在mlab中添加了一个test_mesh_mask_custom_colors示例,它说明了上述内容,并希望在下一个mayavi版本中可用。 - Prabhu Ramachandran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接