54

When writing scripts that use matplotlib, I temporally get an interactive graphing window when I run the script, which immediately goes away before I can view the plot. If I execute the same code interactively inside iPython, the graphing window stays open. How can I get matplotlib to keep a plot open once it is produces a graph when I run a script?

For example, I can save this plot, but I cannot display it with show():

from matplotlib import pyplot as plt
import scipy as sp

x =  sp.arange(10)
y =  sp.arange(10)

plt.plot(x,y)
plt.show()
turtle
  • 7,533
  • 18
  • 68
  • 97
  • 2
    When I run a script including the `show()` method of matplotlib, the window stays open until I close it and the script does not return until I close the window. Can you provide a minimal examples showing your problem? – Dr. Jan-Philip Gehrcke Sep 10 '12 at 19:39
  • Are you sure that you do something beyond just displaying your plot? If that is last thing you do, than Python will just exit your script! Add info about it to your question. – przemo_li Sep 10 '12 at 19:39
  • 1
    I can save plots just fine. For whatever reason, I cannot display them. I briefly get a window, which them immediates goes away. Updated with example. – turtle Sep 10 '12 at 20:14
  • I'm using OS X Mountain Lion. – turtle Sep 11 '12 at 16:42

3 Answers3

49

According to the documentation, there's an experimental block parameter you can pass to plt.show(). Of course, if your version of matplotlib isn't new enough, it won't have this.

If you have this feature, you should be able to replace plt.show() with plt.show(block=True) to get your desired behavior.

Sam Mussmann
  • 5,883
  • 2
  • 29
  • 43
  • I still don't get under which circumstances you need to set this to `True`. As I said, when I invoke a Python script using the system's Python interpreter (like `$ python plot_a_plot.py` with `plot_a_plot.py` containing `pylab.show()`), this Python process does not return until I close all the plot windows. This is in agreement with the documentation: "In non-interactive mode, display all figures and block until the figures have been closed" – Dr. Jan-Philip Gehrcke Sep 11 '12 at 12:40
  • @jan-philip-gehrcke I get the same behavior as "turtle". I'm using Debian 7.0, Python 2.7.3 and matplotlib 1.1.1rc2 – glarrain Jul 01 '13 at 00:49
  • @glarrain Yep, same here. I guess I'm the only windows/py3.3 guy here, but my plot window only works if I use `block=True` – Navin Sep 15 '13 at 18:18
  • @Navin It's good to know how this package work in the latest Python version (3.3), although I'm afraid Windows isn't very representative when it comes to Python software using C/C++ libraries. – glarrain Sep 15 '13 at 20:45
  • 2
    @Jan-PhilipGehrcke at least in my case, `fig.show()` is non blocking, while `plt.show()` is blocking normally. – Rui Pimentel Feb 12 '17 at 17:49
15

Old question, but more canonical answer (perhaps), since it uses only documented and not experimental features.

Before your script exits, enter non-interactive mode and show your figures. This can be done using plt.show() or plt.gcf().show(). Both will block:

plt.ioff()
plt.show()

OR

plt.ioff()
plt.gcf().show()

In both cases, the show function will not return until the figure is closed. The first case is to block on all figures, the second case is to block only until the one figure is closed.

You can even use the matplotlib.rc_context context manager to temporarily modify the interactive state in the middle of your program without changing anything else:

import matplotlib as mpl
with mpl.rc_context(rc={'interactive': False}):
    plt.show()

OR

with mpl.rc_context(rc={'interactive': False}):
    plt.gcf().show()
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
  • Thanks for this, super useful. I edit in Vim and this way, I can map a keyboard shortcut to execute the current file and have figure windows pop up. Allows me to avoid using an IPython session. – Luke Davis Feb 17 '17 at 23:07
0

For anyone this applies to, I had the problem where my new windows were being automatically closed regardless of the interactive backend. The error for me was accidentally running the script inside a terminal-initiated version of Python rather than calling my system version. To solve I just needed to quit() my terminal Python session and rerun the program--simple but frustrating to debug!