Update mayavi plot in loop
<p>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).</p>

<p>So an example piece of code I would like to get running is:</p>

<pre><code>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)
</code></pre>

<p>However, this doesn't display a figure. If I include <code>mlab.show()</code> in the loop, then this steals the focus and doesn't allow the code to continue.</p>

<p>I feel what I should be using is a <em>traits</em> figure (e.g. <a href="http://docs.enthought.com/mayavi/mayavi/building_applications.html" rel="nofollow">this</a>). 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 <code>visualization.configure_traits()</code>.</p>

<p>Any pointers, or a link to appropriate documentation, would be appreciated.</p>

<hr>

<p><strong>EDIT</strong></p>

<p>David Winchester's answer gets a step closer to the solution. </p>

<p>However, as I point out in the comments, I am not able to manipulate the figure with the mouse during the <code>time.sleep()</code> 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.</p>

<p>If you use the <code>wx</code> backend, you can call <code>wx.Yield()</code> periodically if you want to interact with your data during some long-running function. In the following example, <code>wx.Yield()</code> is called for every iteration of some "long running" function, <code>animate_sleep</code>. In this case, you could start the program with <code>$ ipython --gui=wx &lt;program_name.py&gt;</code></p>

<pre><code>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)
</code></pre>

python interactive mayavi