python - 使用 Mayavi 以交互方式绘制 3d 图的简单方法?

标签 python matplotlib 3d mayavi

阅读 Mayavi 的文档“http://docs.enthought.com/mayavi/mayavi/building_applications.html”让我感到非常困惑。

我的问题是,如果我只是想要一个允许用户交互的 3d 绘图,例如,拖动 slider 并更改绘图的内容,我必须使用 Traits,对吧?根据文档,标准程序类似于:

class visual(HasTraits):
    scene = ...
    view = View(...)
    @on_trait_change(...)
    def do_something()
        ...

我不知道什么是特征。我什至不明白在构造函数之外定义的类中的属性是什么(这是一个“特征”?)。

回到最初的问题,如果我只是想要一个可以改变的3d plot,为什么我不直接做呢?一个工作示例如下:

import numpy as np
from mayavi import mlab
from matplotlib import pyplot as plt
from matplotlib.widgets import Slider


def slider_changed(val):
    s.mlab_source.scalars = np.asarray(x * (val + 1), 'd')

# mayavi 3d plot
x, y = np.mgrid[0:3:1,0:3:1]
s = mlab.surf(x, y, np.asarray(x*0.1, 'd'))

# a matplotlib slider
plt.figure()
ax = plt.subplot(1, 1, 1)
slider = Slider(ax, valmin=0., valmax=1., label='test')
slider.on_changed(slider_changed)

plt.show()
mlab.show()

在我看来,如果我不关心在应用程序中嵌入 3d 图,这是一种更简单的方法吗? 3d 图的很多属性都可以通过 mlab_source 的属性进行操作。我在这里使用 matplotlib slider 作为示例,但它似乎可以是 pyqt UI 或其他任何东西。

然而,文档说

All the different properties of the pipeline and pipeline objects are expressed as Traits, i.e. special attributes that can be visualized in dialogs and that fire callbacks when they are modified. In particular this means that when a visualization object is modified, the scene can update automatically.

这是否意味着如果我想要自动更新的东西,我必须按照上面描述的方式使用 Traits?

最佳答案

理解特征可能是一个好的开始 this article .我们在这里谈论的那些特征是developped by Enthough .值得注意的是,还有其他对象/概念称为特征,它们与使用 mayavi 的相关内容完全无关。


I don't have to use Traits, right?

调用 s.mlab_source.scalars = np.asarray(x * (val + 1), 'd') 时,您正在使用 Traits。 Mayavi 仅仅因为您更改了基础数据而更新绘图这一事实是使用了 Traits 的结果。

Mayavi 只是使用这些特征,而不是通常的对象。所以一旦你使用mayavi,你就不可避免地要用到traits。

Does it mean if I wanted something that's automatically updated, I have to use Traits in the way it was described above?

不是,你自己给了反例。您不必继承 HasTraits 来更新绘图。您可以使用您能想到的任何其他解决方案。然而,一旦您想要将 mayavi 场景嵌入到 GUI 中,按照文档说明的方式进行操作可能是个好主意。

此外,子类化 HasTraits 实际上是一种轻松获得交互式图形的非常巧妙的方法。所以问题中的例子可能看起来像

import numpy as np
from mayavi import mlab

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

x, y = np.mgrid[0:3:1,0:3:1]

class MyModel(HasTraits):
    slider    = Range(-5., 5., 0.5, )    
    scene = Instance(MlabSceneModel, ())

    def __init__(self):
        HasTraits.__init__(self)
        self.s = mlab.surf(x, y, np.asarray(x*1.5, 'd'), figure=self.scene.mayavi_scene)

    @on_trait_change('slider')
    def slider_changed(self):
        self.s.mlab_source.scalars = np.asarray(x * (self.slider + 1), 'd')

    view = View(Item('scene', editor=SceneEditor(scene_class=MayaviScene)),
                Group("slider"))

my_model = MyModel()
my_model.configure_traits()

enter image description here

这里值得注意的是,您实际上并没有定义显式回调(即没有 on_slider_change 或类似的)。

关于python - 使用 Mayavi 以交互方式绘制 3d 图的简单方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47063171/

相关文章:

如果客户端需要,python 启用 ssl

javascript - 三个js光线转换OBJ

python - 是否有可能用纯 Python 编写与魔兽世界一样大的 3D 游戏?

python - 如何以 pi 的倍数设置轴刻度(Python)(matplotlib)

3d - Three.js - 翻译与移动?

python - 当 ruamel.yaml 从字符串加载@dataclass 时,不会调用 __post_init__

python - 将列作为副本添加到 Pandas DataFrame

python - argparse 如何将可选参数的默认值设置为 null 或空?

python - 用 matplotlib pcolor 插值

python - 将曲线拟合到 Python 中的直方图