问题
What I want to do is to update a mayavi plot in a loop. I want the updating of the plot to be done at a time specified by me (unlike, e.g., the animation decorator).
So an example piece of code I would like to get running is:
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)
However, this doesn't display a figure. If I include mlab.show()
in the loop, then this steals the focus and doesn't allow the code to continue.
I feel what I should be using is a traits figure (e.g. this). I can follow the example traits application to run a figure which live-updates as I update the sliders. However, I can't get it to update when my code asks it to update; the focus now is 'stolen' by visualization.configure_traits()
.
Any pointers, or a link to appropriate documentation, would be appreciated.
EDIT
David Winchester's answer gets a step closer to the solution.
However, as I point out in the comments, I am not able to manipulate the figure with the mouse during the time.sleep()
step. It is during this step that, in the full program, the computer will be busy computing the new value of V. During this time I would like to be able to manipulate the figure, rotating it with the mouse etc.
回答1:
If you use the wx
backend, you can call wx.Yield()
periodically if you want to interact with your data during some long-running function. In the following example, wx.Yield()
is called for every iteration of some "long running" function, animate_sleep
. In this case, you could start the program with $ 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)
回答2:
I thin Mayavi uses generators
to animate data. This is working for me:
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()
I used this post as reference ( Animating a mayavi points3d plot )
来源:https://stackoverflow.com/questions/39840638/update-mayavi-plot-in-loop