views:

700

answers:

3

There are a lot of questions about matplotlib, pylab, pyplot, ipython, so I'm sorry if you're sick of seeing this asked. I'll try to be as specific as I can, because I've been looking through people's questions and looking at documentation for pyplot and pylab, and I still am not sure what I'm doing wrong. On with the code:

Goal: plot a figure every .5 seconds, and update the figure as soon as the plot command is called.

My attempt at coding this follows (running on ipython -pylab):


import time
ion()
x=linspace(-1,1,51)
plot(sin(x))
for i in range(10):
    plot([sin(i+j) for j in x])
    #see **
    print i
    time.sleep(1)
print 'Done'

It correctly plots each line, but not until it has exited the for loop. I have tried forcing a redraw by putting draw() where ** is, but that doesn't seem to work either. Ideally, I'd like to have it simply add each line, instead of doing a full redraw. If redrawing is required however, that's fine.

Additional attempts at solving:
just after ion(), tried adding hold(True) to no avail.
for kicks tried show() for **
The closest answer I've found to what I'm trying to do was at http://stackoverflow.com/questions/2310851/plotting-lines-without-blocking-execution, but show() isn't doing anything.

I apologize if this is a straightforward request, and I'm looking past something so obvious. For what it's worth, this came up while I was trying to convert matlab code from class to some python for my own use. The original matlab (initializations removed) which I have been trying to convert follows:


for i=1:time
    plot(u)
    hold on
    pause(.01)
    for j=2:n-1
        v(j)=u(j)-2*u(j-1)
    end
    v(1)= pi
    u=v
end

Any help, even if it's just "look up this_method" would be excellent, so I can at least narrow my efforts to figuring out how to use that method. If there's any more information that would be useful, let me know.

A: 

The second answer to the question you linked provides the answer: call draw() after every plot() to make it appear immediately; for example:

import time
ion()
x = linspace(-1,1,51)
plot(sin(x))
for i in range(10):
    plot([sin(i+j) for j in x])
    # make it appear immediately
    draw()
    time.sleep(1)

If that doesn't work... try what they do on this page: http://www.scipy.org/Cookbook/Matplotlib/Animations

import time

ion()

tstart = time.time()               # for profiling
x = arange(0,2*pi,0.01)            # x-array
line, = plot(x,sin(x))
for i in arange(1,200):
    line.set_ydata(sin(x+i/10.0))  # update the data
    draw()                         # redraw the canvas

print 'FPS:' , 200/(time.time()-tstart)

The page mentions that the line.set_ydata() function is the key part.

Daniel G
For some reason this is not working for me. I have no doubt it's right, I'm just not sure why it's not working for me. As soon as the first one prints, I see a blank window for 10 seconds; after which all of the graphs appear. But draw() doesn't seem to be forcing an update until it's out of the for loop. I've just started (trying) to use matplotlib- could this be related to the "backend" I've heard about? (I have no idea what that is =/)
NumberOverZero
@NumberOverZero - what platform are you using? (Windows/Mac/Linux...)
Daniel G
Vista Ult 64, Python 2.6.2
NumberOverZero
Weird... it works for me on 7. Okay, I'll update the answer with something else to try.
Daniel G
Looked promising, but no such luck. Getting around 77fps. I threw a pause in the main loop afterward to see if it was doing each piece at a time, using "trashvar=raw_input(":")" to pause each time for input. Same thing, still a blank screen until the loop finishes.
NumberOverZero
:( I'm sorry - both methods work for me, I don't have any idea what's going on.
Daniel G
No problem, I'll keep looking and if nothing comes up, go for a fresh install when I can get my hands on another computer. Thank you for the help, I'm sure it will work for (most) someone(s).
NumberOverZero
A: 

Hi - I have exactly the same problem - interactive mode doesn't work for me. I think it depends on the system - I've tried the same pyhon/matplotlib configuration on Vista and XP and draw() works for XP only.

In my case even an animation example (matplotlib.sourceforge.net/examples/animation/animate_decay_tk_blit.html ) hangs up figure window.

Rght now I'm thinking about adjusting this example http://matplotlib.sourceforge.net/examples/event_handling/zoom_window.html so there is some event generated every second that can update the plot (I don't know it this makes sense).

If you have any ideas that would be great.

karol
A: 

Please see the answer I posted here to a similar question. I could generate your animation without problems using only the GTKAgg backend. To do this, you need to add this line to your script (I think before importing pylab):

matplotlib.use('GTkAgg')

and also install PyGTK.

Carlos Cordoba