Python 如何在Mayavi中更改直线图的管半径?

Python 如何在Mayavi中更改直线图的管半径?,python,enthought,mayavi,Python,Enthought,Mayavi,我试图在Mayavi2中动态修改三维线图的管半径。比如说 from traits.api import HasTraits, Float, Instance, on_trait_change from traitsui.api import View, Item, Group from mayavi.core.api import PipelineBase from mayavi.core.ui.api import MayaviScene, SceneEditor, MlabSceneMode

我试图在Mayavi2中动态修改三维线图的管半径。比如说

from traits.api import HasTraits, Float, Instance, on_trait_change
from traitsui.api import View, Item, Group
from mayavi.core.api import PipelineBase
from mayavi.core.ui.api import MayaviScene, SceneEditor, MlabSceneModel
import numpy

def curve():
    n_mer, n_long = 6, 11
    pi = numpy.pi
    dphi = pi / 1000.0
    phi = numpy.arange(0.0, 2 * pi + 0.5 * dphi, dphi)
    mu = phi * n_mer
    x = numpy.cos(mu) * (1 + numpy.cos(n_long * mu / n_mer) * 0.5)
    y = numpy.sin(mu) * (1 + numpy.cos(n_long * mu / n_mer) * 0.5)
    z = numpy.sin(n_long * mu / n_mer) * 0.5
    t = numpy.sin(mu)

    return x, y, z, t

class MyModel(HasTraits):
    radius = Float(0.025)
    scene = Instance(MlabSceneModel, ())
    plot = Instance(PipelineBase)

    @on_trait_change('radius,scene.activated')
    def update_plot(self):
        x, y, z, t = curve()
        if self.plot is None:
            self.plot = self.scene.mlab.plot3d(x, y, z, t,
                                tube_radius=self.radius, colormap='Spectral')
        else:
            print self.radius
            self.plot.mlab_source.set(tube_radius=self.radius)
            self.scene.mlab.draw()

    view = View(Item('scene', editor=SceneEditor(scene_class=MayaviScene),
                     height=250, width=300, show_label=False),
                Group(
                        'radius',
                     ),
                resizable=True,
                )

my_model = MyModel()
my_model.configure_traits()
这使得:


但是,当我更改半径时,视觉线图不会发生任何变化。

不要使用
trait.set
trait.reset
来设置mayavi或vtk属性。实际上,您正在使用的
MLineSource
没有这样的属性,但即使有,它也可能不起作用

手动查找控制此功能的mayavi属性通常很有用,可以查看指定给它的mayavi对象。在这种情况下,通过mayavi管道GUI显示它位于管道过滤器上

mlab.plot3d
是一个帮助函数,它尝试为您做任何事情,而不维护 引用所使用的过滤器。但一般来说,如果您自己构建管道,最好保留对mayavi管道中每个步骤的引用。这样,您就可以轻松访问控制此操作的mayavi对象

如果您不自己构造管道,您可以通过手动导航父对象和子对象的树,始终在管道中找到它。在这种情况下,您可以这样访问它:

@on_trait_change('radius,scene.activated')
    def update_plot(self):
        x, y, z, t = curve()
        if self.plot is None:
            self.plot = self.scene.mlab.plot3d(x, y, z, t,
                                tube_radius=self.radius, colormap='Spectral')
        else:
            self.plot.parent.parent.filter.radius = self.radius