Scott
Scott

Reputation: 2676

Visualizing data with matplotlib

In Matlab, you can use drawnow to view a calculation's result while it's in progress. I have tried a similar syntax in Python, both with matplotlib and mayavi.

I know it's possible to animate in one dimension with ion and set_data. However, animating in two dimensions (via imshow) is useful and I couldn't find an easy way to do that.

I know it's possible to animate using a function call but that's not as useful for algorithm development (since you can't use IPython's %run and query your program).

In matplotlib, I can use

N = 16
first_image = arange(N*N).reshape(N,N)
myobj = imshow(first_image)
for i in arange(N*N):
    first_image.flat[i] = 0
    myobj.set_data(first_image)
    draw()

to animate an image but this script doesn't respond to <Cntrl-C> -- it hangs and disables future animations (on this machine). Despite this SO answer, different ways of invoking this animation process does not work. How do I view 2D data as it's being calculated?

Upvotes: 2

Views: 395

Answers (1)

Scott
Scott

Reputation: 2676

EDIT: I have since made a package called python-drawnow to implement the following answer.

You just want to visualize the data from some complicated computation and not smoothly animate an image, correct? Then you can just define some simple functions:

def drawnow(draw_fig, wait_secs=1):
    """
        draw_fig: (callable, no args by use of python's global scope) your
        function to draw the figure. it should include the figure() call --
        just like you'd normally do it.  However, you must leave out the
        show().

        wait_secs : optional, how many seconds to wait. note that if this is 0
        and your computation is fast, you don't really see the plot update.

        does not work in ipy-qt. only works in the ipython shell.
    """
    close()
    draw_fig()
    draw()
    time.sleep(wait_secs)

def drawnow_init():
    ion()

An example of this:

def draw_fig():
    figure()
    imshow(z, interpolation='nearest')
    #show()

N = 16
x = linspace(-1, 1, num=N)
x, y = meshgrid(x, x)
z = x**2 + y**2


drawnow_init()
for i in arange(2*N):
    z.flat[i] = 0
    drawnow(draw_fig)

Notice this requires that the variables you're plotting be global. This shouldn't be a problem since it seems that the variables you want to visualize are global.

This method responds fine to cntrl-c and is visible even during fast computations (through wait_secs.

Upvotes: 1

Related Questions