60

I have a simple python script which plots some graphs in the same figure. All graphs are created by the draw() and in the end I call the show() function to block.

The script used to work with Python 2.6.6, Matplotlib 0.99.3, and Ubuntu 11.04. Tried to run it under Python 2.7.2, Matplotlib 1.0.1, and Ubuntu 11.10 but the show() function returns immediately without waiting to kill the figure.

Is this a bug? Or a new feature and we'll have to change our scripts? Any ideas?

EDIT: It does keep the plot open under interactive mode, i.e., python -i ..., but it used to work without that, and tried to have plt.ion() in the script and run it in normal mode but no luck.

gpierris
  • 776
  • 1
  • 6
  • 10
  • 5
    code is the main subject of SO. Give us some – joaquin Feb 14 '12 at 16:10
  • You are correct. I tried to reproduce it with a simpler example but couldn't. I'll try to trim down the code and highlight you the source of the problem. – gpierris Feb 14 '12 at 17:27
  • a workaround could be using a raw_input() in the last line in the script – joaquin Feb 14 '12 at 17:33
  • I thought of it and did a time.sleep instead, but the figure handlers weren't working and it was frozen, thus I quit the idea, but you are correct. With the raw_input I don't have that problem! – gpierris Feb 14 '12 at 17:41
  • great, still, it should work without using raw_input. you have a problem somewhere. Try putting together a piece of code that reproduces the effect. Or the reverse, find the problem in the code you removed to prepare the piece of code that now works! :-) – joaquin Feb 14 '12 at 18:12

5 Answers5

72

I had this same problem, and it was caused by calling show() on the Figure object instead of the pyplot object.

Incorrect code. Causes the graph to flash on screen for a brief instant:

    import matplotlib.pyplot as plt

    x = [1,2,3]
    y = [5,6,7]

    fig = plt.figure()
    plt.plot(x, y)

    fig.show()

Last line should be as follows to show the graph until it is dismissed:

    plt.show()
Jason Sundram
  • 12,225
  • 19
  • 71
  • 86
CraigTeegarden
  • 8,173
  • 8
  • 38
  • 43
  • This was my problem too, but only in standalone Python. Everything works fine in Anaconda. So.... Is this a Bug or a Feature? – Franz Forstmayr Mar 20 '18 at 17:43
  • I have problem in anaconda too. figure window opens, nothing is drawn and window gets automatically closed. any help? I tried both fig.show() and plt.show() from exact simple example given above. I have matplotlib version 3.4.3 – Kartik Podugu Nov 03 '21 at 18:27
60

I think that using show(block=True) should fix your problem.

Jason Sundram
  • 12,225
  • 19
  • 71
  • 86
Guy Adini
  • 5,188
  • 5
  • 32
  • 34
  • 2
    Thanks for the answer, but no. Probably that was an older version. It just tells me block was an unexpected arguments. – gpierris Feb 14 '12 at 17:23
  • 1
    @gpierris `block` argument to `show` exists at least in matplotlib 1.1.0. However, default is to block so if you did not changed the mode previously in the code, setting it to True is not relevant – joaquin Feb 14 '12 at 17:28
  • Worked in matplotlib 2.2.3 – vindarmagnus Nov 14 '18 at 19:21
  • 1
    You're the man!!! I dunno if `pandas` or `vscode` is causing it, but explicitly doing `plt.show(block=True)` is **NEEDED** when I'm debugging running in `vscode` – daparic Aug 09 '21 at 08:59
  • 1
    Side note, [`block=True` is only by default if `isinteractive=False`](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.show.html). So the "proper" fix might be `plt.ioff()`, as mentioned in the [answer below](https://stackoverflow.com/a/28028339/5267751). – user202729 Jun 28 '22 at 02:57
9

Had the inverse problem, and it seems that matplotlib will work in interactive or non-interaxctive mode based on a number of things that I could not trace (One way in IDLE, another in system console, one way in normal spyder console, another in a dedicated one ...)

This worked for me:

import matplotlib
matplotlib.interactive(False)

(Actually, I wanted interactive mode, but in your case the inverse should help.) ion() and ioff() should do the same but the above is on matplotlib's level, not just pyplot or pylab. This works for me although I'm (later) importing pyplot separately and never call matplotlib as such again. I'm thinking that plt.ion() only has an effect on pyplot, not other components of matplotlib that may or may not be involved when using pyplot.

This method works for me on Windows 7, using both Python 2.65 with matplotlib 0.99 and Python 2.75 with matplotlib 1.3.1, across all available python consoles and IDEs on both systems (64-bit, both of them). It did, however, not work on Linux (SuSe 11.3, 64 bit), so there is definitely some platform dependency at play here

Zak
  • 3,063
  • 3
  • 23
  • 30
5

To replicate the matplotlib.show() behaviour with the tkagg backend when calling show() on the Figure object:

import Tkinter as Tk
import matplotlib.pyplot as plt
fig = plt.figure()
... your plot commands...
fig.show()
Tk.mainloop()
bio_james
  • 161
  • 2
  • 2
  • 1
    Tkinter is not a package. it's tkinter. – thang Apr 01 '17 at 14:54
  • 2
    His example is correct for python2, it's tkinter in python 3. https://stackoverflow.com/questions/25905540/importerror-no-module-named-tkinter Also confirmed, his solution works for our specific use case. Thank you! – Bryan Cote-Chang Sep 12 '17 at 18:08
1

I had the same problem with this code below.

import matplotlib.pyplot as plt

plt.ion()
fig,ax0 = plt.subplots(figsize=(5.3,4))

plt.show()

I removed plt.ion(), and the plot stays without closing automatically.

  • Actually this answer is already covered in https://stackoverflow.com/a/28028339/5267751 which suggests disabling interactive mode – user202729 Jun 28 '22 at 02:57