开发者

in matplotlib, is there a way to pop up a figure asynchronously?

In matplotlib, is there a simple way of plotting a figure without interrupting the control flow of the script?

Using pseudocode for clarity, here's 开发者_StackOverflow社区what I'm trying to achieve:

fig1 = figure()
fig1.plot_a_figure(datasets)

for dataset in datasets:
   results = analyze(dataset)    # this takes several minutes
   update(fig1)
   pop_up_another_figure(results) # would like to have a look at this one
                                  # while the next dataset is being processed

Of course, I can just savefig() these intermediate figures, but I only need a quick glance at a them and it would be the best to have them just pop up on the screen in real time.

EDIT: A runnable example:

#!/usr/bin/python
import pylab as plb
import matplotlib.pyplot as plt

fig1=plt.figure(1)
ax = fig1.add_subplot(1,1,1)

ax.plot([1,2,3],[4,5,6],'ro-')

#fig1.show()  # this does not show a figure if uncommented
plt.show()    # until the plot window is closed, the next line is not executed

print "doing something else now"

Am I missing something very very basic?


First things first, don't forget a simple alternative is to just make new figure windows with plt.figure(2), plt.figure(3) etc. If you really want to update the existing figure window, you had better keep a handle on your lines object with

h = ax.plot([1,2,3],[4,5,6],'ro-')

And then later you would be doing something like:

h[0].set_data(some_new_results)
ax.figure.canvas.draw()

As for the real meat of the question, if you're still battling with this read on..


You need to enable interactive mode if you want plt.show() to be non-blocking. To modify your runnable example so that "doing something else now" would print immediately, as opposed to waiting for the figure window to be closed, the following would do:

#!/usr/bin/python
import pylab as plb
import matplotlib.pyplot as plt

fig1=plt.figure(1)
ax = fig1.add_subplot(1,1,1)

ax.plot([1,2,3],[4,5,6],'ro-')

#fig1.show()  # this does not show a figure if uncommented
plt.ion()     # turns on interactive mode
plt.show()    # now this should be non-blocking

print "doing something else now"
raw_input('Press Enter to continue...')

However, this is just scratching the surface of things - there are many complications once you start wanting to do background work while interacting with the plots. This is a natural consequence of painting with what's essentially a state machine, it doesn't rub well with threading and programming in an object-oriented environment.

  • Expensive calculations will have to go into worker threads (or alternatively into subprocesses) to avoid freezing the GUI.
  • Queue should be used to pass input data and get results out of the worker functions in a thread-safe way.
  • In my experience, it is not safe to call draw() in the worker thread so you also need to set up a way to schedule a repaint.
  • Different backends may start to do strange things and TkAgg seems to be the only one which works 100% (see here).

The easiest and best solution is not to use the vanilla python interpreter, but to use ipython -pylab (as ianalis has rightly suggested), because they have already figured out most of the tricks needed to get interactive stuff working smoothly. It can be done without ipython/pylab but it's a significant amount of extra work.

Note: I still often like to farm off worker threads whilst using ipython and pyplot GUI windows, and to get threading working smoothly I also need to use another commandline argument ipython -pylab -wthread. I'm on python 2.7.1+ with matplotlib v1.1.0, your mileage may vary. Hope this helps!

Note for Ubuntu users: The repositories are still back on v0.99 for quite some time now, it is worth upgrading your matplotlib because there were many improvements coming up to the v1.0 release including a Bugfix marathon, and major changes to the behaviour of show().


Probably the easiest solution is to use IPython as your python shell. Run it with the -pylab option.

ipython -pylab
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜