views:

2146

answers:

4

Dear all,

After these instructions in the Python interpreter one gets a window with a plot

from matplotlib.pyplot import *
plot([1,2,3])
show()
# other code

Unfortunately, I don't know how to continue to interactively explore the figure created by show() while the program does further calculations.

Is it possible at all? Sometimes calculations are long and it would help if they would proceed during examination of intermediate results.

Any help appreciated,

meteore.

+4  A: 

It is better to always check with the library you are using if it supports usage in a non-blocking way.

But if you want a more generic solution, or if there is no other way, you can run anything that blocks in a separated process by using the multprocessing module included in python. Computation will continue:

from multiprocessing import Process
from matplotlib import plot, show

def plot_graph(*args):
    for data in args:
        plot(data)
    show()

p = Process(target=plot_graph, args=([1, 2, 3],))
p.start()

print 'yay'
print 'computation continues...'
print 'that rocks.'

print 'Now lets wait for the graph be closed to continue...:'
p.join()

That has the overhead of launching a new process, and is sometimes harder to debug on complex scenarios, so I'd prefer the other solution (using matplotlib's nonblocking API calls)

nosklo
Thanks! Since I don't have Python 2.6 yet on my system, I used threading.Thread as a substitute for Process. I observed that subsequent print statements become unbearably slow (third print, I issued KeyboardInterrupt after 1 min wait). Is this an effect of using threading instead of multiprocessing?
meteore
@meteore: Yes, threading sucks. You can always get multiprocessing for python <2.6 from here: http://pyprocessing.berlios.de/
nosklo
This is absolutely excellent. Do you have an idea why the print statements are not executed when in Emacs (python mode) until the plot window is closed?
meteore
In Ubuntu 8.10 (Intrepid) the package (for python <2.6) is called python-processing and you import it with 'import processing'
meteore
+9  A: 

Use matplotlib's calls that won't block:

Using draw():

from matplotlib import plot, draw, show
plot([1,2,3])
draw()
print 'continue computation'

# at the end call show to ensure window won't close.
show()

Using interactive mode:

from matplotlib import plot, ion, show
ion() # enables interactive mode
plot([1,2,3]) # result shows immediatelly (implicit draw())

print 'continue computation'

# at the end call show to ensure window won't close.
show()
nosklo
With matplotlib 0.98.3 the right import is from matplotlib.pyplot import plot, draw, show
meteore
Thanks! but in the noninteractive mode what is the advantage of calling draw() somewhere in the code before the final show()?
meteore
@meteore: it makes the screen update, if you're in a script. (In interactive python prompt interactive mode is enabled by default)
nosklo
I didn't realize this before due to the fact that Emacs python mode does not print until you close the plot window... :(
meteore
+2  A: 

You may want to read this document in matplotlib's documentation, titled:

Using matplotlib in a python shell

nosklo
+1  A: 

In my case, I wanted to have several windows pop up as they are being computed. For reference, this is the way:

from matplotlib.pyplot import draw, figure, show
f1, f2 = figure(), figure()
af1 = f1.add_subplot(111)
af2 = f2.add_subplot(111)
af1.plot([1,2,3])
af2.plot([6,5,4])
draw() 
print 'continuing computation'
show()

PS. A quite useful guide to matplotlib's OO interface.

meteore