views:

833

answers:

3

Say that I have two figures in matplotlib, with one plot per figure:

import matplotlib.pyplot as plt

f1 = plt.figure()
plt.plot(range(0,10))
f2 = plt.figure()
plt.plot(range(10,20))

Then I show both in one shot

plt.show()

Is there a way to show them separately, i.e. to show just f1?

Or better: how can I manage the figures separately like in the following 'wishful' code (that doesn't work):

f1 = plt.figure()
f1.plot(range(0,10))
f1.show()
+4  A: 

Sure. Add an Axes using add_subplot. (Edited import.) (Edited show.)

import matplotlib.pyplot as plt
f1 = plt.figure()
f2 = plt.figure()
ax1 = f1.add_subplot(111)
ax1.plot(range(0,10))
ax2 = f2.add_subplot(111)
ax2.plot(range(10,20))
plt.show()

Alternatively, use add_axes.

ax1 = f1.add_axes([0.1,0.1,0.8,0.8])
ax1.plot(range(0,10))
ax2 = f2.add_axes([0.1,0.1,0.8,0.8])
ax2.plot(range(10,20))
Steve
This is exactly what I'm trying to do, but matplotlib.figure seems a module, not a class. Am I missing something?
Federico Ramponi
My fault. See edit. In fact, I use `from pylab import figure` more often. For some reason, that `pylab.figure` returns a figure with the `show` method, but `matplotlib.figure.Figure` does not. Hmm.
Steve
Uff.. :) Here I'm using python 2.5.2 with matplotlib 0.98.1. f1.show() does nothing, whereas the second show() gets stuck. Probably something is misconfigured. However, on another machine I use python 2.5.5 and matplotlib 0.99.1.1 and everything works fine, so... +1 and accepted, thank you very much.
Federico Ramponi
One really shouldn't use `pylab` any more, `matplotlib.pyplot` is much better and was also used by the questioner.
nikow
Here is the offical link why `matplotlib.pyplot` is prefered: http://matplotlib.sourceforge.net/faq/usage_faq.html
nikow
WARNING: calling show multiple times is officially incorrect: http://matplotlib.sourceforge.net/faq/howto_faq.html#use-show. A working solution is to use `draw()` and `raw_input()` (see my answer).
EOL
@nikow: As far as I know, Pylab is not deprecated. The link you quote says is that examples in the Matplotlib documentation should not imply "from pylab import *" but instead rely on explicit module attribute access. What is deprectaed is the "from pylab import *" in their examples.
EOL
Edited with single `show`. Still works for me.
Steve
@EOL: Of course it is not deprecated, but that doesn't mean that it is good practice.
nikow
@nikow: I was referring to your "One really shouldn't use pylab anymore". Pylab can actually still be used ("is not deprecated"), as far as I understand (Matplotlib's examples should not use "from pylab import *", that's all).
EOL
A: 

Perhaps you need to read about interactive usage of Matplotlib. However, if you are going to build an app, you should be using the API and embedding the figures in the windows of your chosen GUI toolkit (see examples/embedding_in_tk.py, etc).

Jouni K. Seppänen
+2  A: 

Edit: the currently accepted answer has now taken the following remark into account:

show() should only be called once per program, even if it seems to work within certain environments (some backends, on some platforms, etc.).

The relevant drawing function is actually draw():

import matplotlib.pyplot as plt

plt.plot(range(10))  # Creates the plot.  No need to save the current figure.
plt.draw()  # Draws, but does not block
raw_input()  # This shows the first figure "separately" (by waiting for "enter").

plt.figure()  # New window, if needed.  No need to save it, as pyplot uses the concept of current figure
plt.plot(range(10, 20))
plt.draw()
# raw_input()  # If you need to wait here too...

# (...)

# Only at the end of your program:
plt.show()  # blocks

It is important to recognize that show() is an infinite loop, designed to handle events in the various figures (resize, etc.). Note that in principle, the calls to draw() are optional if you call matplotlib.ion() at the beginning of your script (I have seen this fail on some platforms and backends, though).

I don't think that Matplotlib offers a mechanism for creating a figure and optionally displaying it; this means that all figures created with figure() will be displayed. If you only need to sequentially display separate figures (either in the same window or not), you can do like in the above code.

Now, the above solution might be sufficient in simple cases, and for some Matplotlib backends. Some backends are nice enough to let you interact with the first figure even though you have not called show(). But, as far as I understand, they do not have to be nice. The most robust approach would be to launch each figure drawing in a separate thread, with a final show() in each thread. I believe that this is essentially what IPython does.

The above code should be sufficient most of the time.

EOL
Edited my answer to use single `show`. I still prefer the manual way of saving individual axis and figure handles, because I find that I frequently need them later on. Furthermore, that is what the initial question asked.
Steve
You really do not need to name the figures in order to display them sequentially… Whether to save the result of figure() or not really depends on one's specific needs; I almost never save it.
EOL
Okay, fair enough. Thank you for the added information.
Steve