循环更新 mayavi 图

Update mayavi plot in loop

我想做的是循环更新mayavi plot。我希望在我指定的时间更新情节(与动画装饰器不同)。

所以我想获得 运行ning 的一段代码示例是:

import time
import numpy as np
from mayavi import mlab

V = np.random.randn(20, 20, 20)
s = mlab.contour3d(V, contours=[0])

for i in range(5):

    time.sleep(1) # Here I'll be computing a new V

    V = np.random.randn(20, 20, 20)

    # Update the plot with the new information
    s.mlab_source.set(scalars=V)

但是,这不显示数字。如果我在循环中包含 mlab.show(),那么这会窃取焦点并且不允许代码继续。

我觉得我应该使用 特征 数字(例如 this)。我可以按照示例特征应用程序 运行 一个在我更新滑块时实时更新的图形。但是,当我的代码要求它更新时,我无法让它更新; visualization.configure_traits().

现在的焦点是 'stolen'

任何指向适当文档的指针或 link,我们将不胜感激。


编辑

David Winchester 的回答离解决方案又近了一步。

但是,正如我在评论中指出的那样,我无法在 time.sleep() 步骤中使用鼠标操作图形。正是在这一步,在整个程序中,计算机将忙于计算 V 的新值。在此期间,我希望能够操纵图形,用鼠标旋转它等。

我认为 Mayavi 使用 generators 来制作数据动画。这对我有用:

import time
import numpy as np
from mayavi import mlab

f = mlab.figure()
V = np.random.randn(20, 20, 20)
s = mlab.contour3d(V, contours=[0])

@mlab.animate(delay=10)
def anim():
    i = 0
    while i < 5:
        time.sleep(1)
        s.mlab_source.set(scalars=np.random.randn(20, 20, 20))
        i += 1
        yield

anim()

我用这个 post 作为参考 ( Animating a mayavi points3d plot )

如果您使用 wx 后端,如果您想在某些 long-运行 函数期间与您的数据进行交互,则可以定期调用 wx.Yield()。在以下示例中,wx.Yield() 会在某些 "long running" 函数 animate_sleep 的每次迭代中调用。在这种情况下,您可以使用 $ ipython --gui=wx <program_name.py>

启动程序
import time
import numpy as np
from mayavi import mlab
import wx

V = np.random.randn(20, 20, 20)
f = mlab.figure()
s = mlab.contour3d(V, contours=[0])

def animate_sleep(x):
    n_steps = int(x / 0.01)
    for i in range(n_steps):
        time.sleep(0.01)
        wx.Yield()

for i in range(5):

    animate_sleep(1)

    V = np.random.randn(20, 20, 20)

    # Update the plot with the new information
    s.mlab_source.set(scalars=V)