阅读 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()
这里值得注意的是,您实际上并没有定义显式回调(即没有 on_slider_change
或类似的)。
关于python - 使用 Mayavi 以交互方式绘制 3d 图的简单方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47063171/