57

I would like to:

pylab.figure()
pylab.plot(x)
pylab.figure()
pylab.plot(y)
# ...
for i, figure in enumerate(pylab.MagicFunctionReturnsListOfAllFigures()):
  figure.savefig('figure%d.png' % i)

What is the magic function that returns a list of current figures in pylab?

Websearch didn't help...

Evgeny
  • 3,064
  • 2
  • 18
  • 19

6 Answers6

113

Pyplot has get_fignums method that returns a list of figure numbers. This should do what you want:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(100)
y = -x

plt.figure()
plt.plot(x)
plt.figure()
plt.plot(y)

for i in plt.get_fignums():
    plt.figure(i)
    plt.savefig('figure%d.png' % i)
Matti Pastell
  • 9,135
  • 3
  • 37
  • 44
  • 2
    There is also now a `plt.get_figlabels` method that can be used in the same way, I used that to include the figure label in the filename on saving it. – Heath Jan 22 '19 at 21:03
28

The following one-liner retrieves the list of existing figures:

import matplotlib.pyplot as plt
figs = list(map(plt.figure, plt.get_fignums()))
krollspell
  • 381
  • 3
  • 5
17

Edit: As Matti Pastell's solution shows, there is a much better way: use plt.get_fignums().


import numpy as np
import pylab
import matplotlib._pylab_helpers

x=np.random.random((10,10))
y=np.random.random((10,10))
pylab.figure()
pylab.plot(x)
pylab.figure()
pylab.plot(y)

figures=[manager.canvas.figure
         for manager in matplotlib._pylab_helpers.Gcf.get_all_fig_managers()]
print(figures)

# [<matplotlib.figure.Figure object at 0xb788ac6c>, <matplotlib.figure.Figure object at 0xa143d0c>]

for i, figure in enumerate(figures):
    figure.savefig('figure%d.png' % i)
Community
  • 1
  • 1
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • 6
    Sure it works, but the underscore in the beginning of _pylab_helpers is a signal that this is not a supported interface and may go away at any time. If there is no published interface and you have a use case for one, please file a feature request. – Jouni K. Seppänen Oct 02 '10 at 07:15
  • @Jouni I've run into the same problem and would like to do just that. Unfortunately the whole host of matplotlib/pyplot/pylab websites isn't all that clear to me. Could you indicate where I could file a feature request? Github? – Michael Clerx May 01 '12 at 12:34
  • Yes, Github (https://github.com/matplotlib/matplotlib/issues) or possibly on the mailing list (http://dir.gmane.org/gmane.comp.python.matplotlib.general). – Jouni K. Seppänen May 01 '12 at 16:34
  • If you're going to use `_pylab_helpers` you can do `_pylab_helpers.Gcf.figs.values()` which is easier. But yeah, uses internal variables etc, so use Matti's way if you don't mind non-OO interface. – Mark Jan 22 '17 at 21:58
3

This should help you (from the pylab.figure doc):

call signature::

figure(num=None, figsize=(8, 6), dpi=80, facecolor='w', edgecolor='k')

Create a new figure and return a :class:matplotlib.figure.Figure instance. If num = None, the figure number will be incremented and a new figure will be created.** The returned figure objects have a number attribute holding this number.

If you want to recall your figures in a loop then a good aproach would be to store your figure instances in a list and to call them in the loop.

>> f = pylab.figure()
>> mylist.append(f)
etc...
>> for fig in mylist:
>>     fig.savefig()
joaquin
  • 82,968
  • 29
  • 138
  • 152
  • "The returned figure objects have a _number_ attribute holding this number." Thanks. That's what I was looking for and missed it in the documentation. – Chris Redford Aug 14 '11 at 23:20
2

I tend to name my figures using strings rather than using the default (and non-descriptive) integer. Here is a way to retrieve that name and save your figures with a descriptive filename:

import matplotlib.pyplot as plt
figures = []
figures.append(plt.figure(num='map'))
# Make a bunch of figures ...
assert figures[0].get_label() == 'map'

for figure in figures:
    figure.savefig('{0}.png'.format(figure.get_label()))
Wesley Baugh
  • 3,720
  • 4
  • 24
  • 42
2

Assuming you haven't manually specified num in any of your figure constructors (so all of your figure numbers are consecutive) and all of the figures that you would like to save actually have things plotted on them...

import matplotlib.pyplot as plt
plot_some_stuff()
# find all figures
figures = []
for i in range(maximum_number_of_possible_figures):
    fig = plt.figure(i)
    if fig.axes:
        figures.append(fig)
    else:
        break

Has the side effect of creating a new blank figure, but better if you don't want to rely on an unsupported interface

mcstrother
  • 6,867
  • 5
  • 22
  • 18