【问题标题】:Simple way to do a 3d plot interactively using Mayavi?使用 Mayavi 以交互方式进行 3d 绘图的简单方法?
【发布时间】:2017-11-01 20:30:13
【问题描述】:

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

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

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

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

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

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 滑块作为示例,但它似乎可以是 pyqt UI 或其他任何东西。

但是,文档说

管道和管道对象的所有不同属性都表示为特征,即可以在对话框中可视化并在修改时触发回调的特殊属性。特别是这意味着当一个可视化对象被修改时,场景可以自动更新。

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

【问题讨论】:

  • 我不确定这个问题的目的是什么。如果您对实施更新的方式感到满意,您可以使用它。
  • 我很困惑,不知道该问什么。刚刚编辑。我认为问题是我必须使用特征吗?在文档中,将 mayavi 嵌入到 QT 应用程序中的方法是首先将其嵌入到 HasTraits,然后将其嵌入到 QT 中。为什么不直接在 qt(或 matplotlib 或任何其他 UI)中?

标签: python matplotlib 3d mayavi


【解决方案1】:

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


我不必使用 Traits,对吧?

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

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

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

不,你自己举了反例。您不必继承 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()

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

【讨论】:

    猜你喜欢
    • 2012-05-12
    • 2014-04-05
    • 2016-06-13
    • 2019-06-03
    • 1970-01-01
    • 2020-07-02
    • 1970-01-01
    • 2013-05-01
    • 1970-01-01
    相关资源
    最近更新 更多