Mayavi中points3d的不同大小和颜色

16

在mayavi中,是否可以单独指定每个点的大小和颜色?

那个API对我来说很笨重。

points3d(x, y, z...)
points3d(x, y, z, s, ...)
points3d(x, y, z, f, ...)

x, y and z are numpy arrays, or lists, all of the same shape, giving the positions of the points.
If only 3 arrays x, y, z are given, all the points are drawn with the same size and color.
In addition, you can pass a fourth array s of the same shape as x, y, and z giving an associated scalar value for each point, or a function f(x, y, z) returning the scalar value. This scalar value can be used to modulate the color and the size of the points.

所以在这种情况下,标量控制大小和颜色,无法将它们分开。我希望有一种方法可以单独指定大小为(N,1)数组,颜色为另一个(N,1)数组。

看起来很复杂?

4个回答

14
每个VTK源都有一个用于标量和向量的数据集。我在我的程序中使用的技巧是绕过Mayavi来源并直接在VTK来源中使用标量作为颜色,矢量作为大小(可能也可以反过来)。
nodes = points3d(x,y,z)
nodes.glyph.scale_mode = 'scale_by_vector'

#this sets the vectors to be a 3x5000 vector showing some random scalars
nodes.mlab_source.dataset.point_data.vectors = np.tile( np.random.random((5000,)), (3,1))

nodes.mlab_source.dataset.point_data.scalars = np.random.random((5000,))

您可能需要转置5000x3向量数据或以某种方式移动矩阵维度。

enter image description here


这幅图是Crossley等人的共同激活矩阵吗?这正是我试图用Mayavi可视化的相同图像。无意中,我正在使用你的bctpy工具箱,并发现它非常有用。我只想说谢谢,我将在github上fork它。 - linello
什么是共同激活矩阵?这张图片是我可视化程序CVU中的一个脑网络,自动生成了网络统计数据的大小和颜色(使用bctpy计算,这也是我创建bctpy的原因)。我很高兴看到人们在使用bctpy。 - aestrivex

10

我同意Mayavi提供的API很不友好。 Mayavi文档建议使用以下hack(我稍作改述)来独立调整点的大小和颜色。

pts = mayavi.mlab.quiver3d(x, y, z, sx, sy, sz, scalars=c, mode="sphere", scale_factor=f)
pts.glyph.color_mode = "color_by_scalar"
pts.glyph.glyph_source.glyph_source.center = [0,0,0]

这将展示x,y,z点作为球体,尽管您调用的是mayavi.mlab.quiver3d。Mayavi将使用sx,sy,sz向量的范数来确定点的大小,并使用c中的标量值来索引到一个颜色映射中。你可以选择提供一个常数大小缩放因子,它将应用于所有点。
这肯定不是您编写过的最自描述的代码,但它有效。

7

我也认为API很丑陋。我只是用@aestrivex的想法做了一个简单而完整的示例:

from mayavi.mlab import *
import numpy as np

K = 10
xx = np.arange(0, K, 1)
yy = np.arange(0, K, 1)

x, y = np.meshgrid(xx, yy)
x, y = x.flatten(), y.flatten()
z = np.zeros(K*K)

colors = 1.0 * (x + y)/(max(x)+max(y))

nodes = points3d(x, y, z, scale_factor=0.5)
nodes.glyph.scale_mode = 'scale_by_vector'

nodes.mlab_source.dataset.point_data.scalars = colors

show()

产生以下结果:

enter image description here


0
如果像我一样,有人试图在单击操作或按键事件时更新单个点的比例或颜色,则可能需要添加以下行以确保即使在图形已经显示后也会更新标量(我添加了修改点大小的完整示例函数,因为它可能对某些人有帮助):
def picker(picker):
    if picker.actor in glyphs.actor.actors:
        point_id = picker.point_id//glyph_points.shape[0]
        # If the no points have been selected, we have '-1'
        if point_id != -1:
            glyphs.mlab_source.dataset.point_data.scalars[point_id] = 10
            # following line is necessary for the live update
            glyphs.mlab_source.dataset.modified()

# you would typically use this function the following way in your main :

figure = mlab.gcf()
mlab.clf()

# define your points
pts = ...

# define scalars or they will be defined to None by default
s = len(pts)*[1]
glyphs = mlab.points3d(pts[:,0], pts[:,1], pts[:,2], s, scale_factor=1, mode='cube')

glyph_points = glyphs.glyph.glyph_source.glyph_source.output.points.to_array()

picker = figure.on_mouse_pick(picker, button='Left')
picker.tolerance = 0.01

mlab.show()

灵感来自这个示例:https://docs.enthought.com/mayavi/mayavi/auto/example_select_red_balls.html


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