1

I need to handle the pyplot objects, like figures and axes. Here is a simplified example of what I want:

In [1]: import matplotlib.pyplot as mp

In [2]: fig = mp.figure()             # create a figure

In [3]: mp.show()                     # and immediately show it. And close.

In [4]: ax = fig.add_subplot(111)     # Then I create a plot on that figure

In [5]: ax.plot([1, 2, 3]) 
Out[5]: [<matplotlib.lines.Line2D at 0x104e29a50>]

In [6]: mp.get_fignums()              # But I already released the figure, so it doesn't appear in the list of available figures
Out[6]: []

In [7]: fig.axes[0].lines[0].get_data()   # The data is there, on the plot
Out[7]: (array([ 0.,  1.,  2.]), array([1, 2, 3]))

In [8]: mp.show()                     # But mp.show() shows nothing.

The fig.show() doesn't work too. How to show a figure after releasing it?

UPD: There was a similar question: Matplotlib: re-open a closed figure?, but with no answer.

Community
  • 1
  • 1

3 Answers3

1

Which is the recommended way to plot: matplotlib or pylab? question is relevant to this question.

The pyplot interface is a convenience module that keeps track of a) open figures and b) the 'current figure' and 'current axes'. Underneath it is using the OO interface.

To have an open figure and a be able to enter new commands at the repl you need to be in 'interactive' mode which integrates the python repl loop with the GUI event loop.

From your question it looks like you are using IPython so use the %matplotlib magic:

16:31 $ ipython
Python 3.5.1 |Continuum Analytics, Inc.| (default, Dec  7 2015, 11:16:01) 
Type "copyright", "credits" or "license" for more information.

IPython 4.2.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: %matplotlib
Using matplotlib backend: Qt4Agg

In [2]: import matplotlib.pyplot as plt

In [3]: fig, ax = plt.subplots()  # prompt returns immediatly leaving open figure

In [4]: ln, = ax.plot(range(15), label='test')  # draws line and updates figure

In [5]: ln.set_linewidth(5)  # changes lw and updates screen

In [6]: 
tacaswell
  • 84,579
  • 22
  • 210
  • 199
0

Try this:

import matplotlib.pyplot as mp

fig = mp.figure()

plt.show() # empty figure appears, close it

fig = plt.gcf() # get current figure, this is the key piece.

ax = fig.add_subplot(111) # added axes object

ax.plot([1,2,3])

plt.show()

When I did this, I was able to get the plot to show with a diagonal line plotted.

AvlWx
  • 291
  • 3
  • 9
  • 1
    Unfortunately, it is wrong. When you do plt.gcf() you actually create a new figure and assign this new figure to the old variable fig. Thus you loose the old figure. You can check that the addresses of the fig is different before and after the call of plt.gcf() – user3631854 May 13 '16 at 18:57
-1

I found it! Let's create a mp.Figure()

import matplotlib.pyplot as mp
fig = mp.Figure()

Now it is not connected to pyplot, so we can't show it. It is equivalent to what happens when you close a figure. The fact that you can't show a figure which is not connected to pyplot is well documented. Just try

In []: fig.show?
Docstring:
If using a GUI backend with pyplot, display the figure window.
For non-GUI backends, this does nothing.

(I reduced the text of the help message.) But it is possible to trick the pyplot. Let's create a figure:

temp_fig = mp.figure()

Steal the figure manager from temp_fig and assign it to our fig:

m = mp.get_current_fig_manager()
fig.canvas.manager = m

Now we can show it:

mp.show() # Shows the fig figure.

Of course, it is a good practice to delete the temp_fig:

del temp_fig
  • This is making it way more complicated than it needs to be. If you want to create a `Figure` object, then you must also create a `Canvas` object for it. For the GUI backends the `Canvas` objects are sub-classes of the 'widgets' for the given frame work and must be embedded in a GUI, the figure managers take care of this for `pyplot`. – tacaswell May 14 '16 at 20:38
  • I am down voting this for those reasons. Please do not take it personally, I just want to indicate via a method stronger than a comment that this answer is not the recommended way of using mpl interactively. – tacaswell May 14 '16 at 20:40