30

I have problem with interactive feature of Matplotlib. I ran the following program and received a freezing empty graph window.

import matplotlib.pyplot as plt
import numpy as np

plt.ion()
x = np.arange(0, 4*np.pi, 0.1)
y = [np.sin(i) for i in x]
plt.plot(x, y, 'g-', linewidth=1.5, markersize=4)
plt.show()

If I removed 'plt.ion()' statement, then it worked just fine. I use IDLE and the Matplotlib version 1.2.x package is installed in Python 3.2.2.

I expect it to be interactive, but instead I got an unfriendly non-interactive window. Can someone shed some light of what I am missing? Thank you in advance.

kaosad
  • 1,233
  • 1
  • 11
  • 15
  • So, it works as you expect if you leave out `plt.ion()`? – tacaswell Oct 01 '12 at 17:04
  • Just don't use plt.ion(), unless you are in a python console, the interactive part is that the console does not freeze. Its always either show or ion not both. – seberg Oct 01 '12 at 17:18
  • What I meant was if I input each statement through IDLE console, then I got that nasty result. @seberg: I want it to be interactive so that I can see the result as I type in plotting statements. – kaosad Oct 02 '12 at 07:01

2 Answers2

56

I bumped into this link found here, which answers my problem.

It seems that after turning on interactive mode through plt.ion(), pyplot needs to be paused temporarily for it to update/redraw itself through plt.pause(0.0001). Here is what I did and it works!

>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> plt.ion()
>>> x = np.arange(0, 4*np.pi, 0.1)
>>> y = [np.sin(i) for i in x]
>>> plt.plot(x, y, 'g-', linewidth=1.5, markersize=4)
>>> plt.pause(0.0001)         
>>> plt.plot(x, [i**2 for i in y], 'g-', linewidth=1.5, markersize=4)
>>> plt.pause(0.0001)
>>> plt.plot(x, [i**2*i+0.25 for i in y], 'r-', linewidth=1.5, markersize=4) 
>>> plt.pause(0.0001)

If you tried that in your IDLE console, notice that up to this point everything got displayed except that the graph window freezes and cannot exit. To unfreeze it type the following last statement

>>> plt.show(block=True)

Now the window can be closed.

Community
  • 1
  • 1
kaosad
  • 1,233
  • 1
  • 11
  • 15
  • Thank you - I have been having this precise problem. Adding a millisecond pause has prevented the plot window from freezing. – tyleha Nov 05 '13 at 01:12
  • 1
    What the `pause` is really doing is calling `draw()`. You could have just called `draw()`. – Neil Traft Apr 10 '14 at 01:15
  • 1
    Actually Neil is on to something. Looks like pause() does in fact call draw(), which means if you're using pause() Don't Call draw() as there's no need to call it twice. My plot performance went way up now that I've taken out draw() and just call a short pause(0.0001)!!!! Thanks!!!! – Logic1 Dec 30 '15 at 06:55
  • Hello @kaosad, could you please have look this question of mine, I am really struggling to get the solution. http://stackoverflow.com/questions/36207525/how-to-generate-multiple-plots-by-clicking-a-single-plot-for-more-infomation-usi – Sandy Mar 25 '16 at 18:35
  • 3
    I've found this is necessary when I'm running python inside of Eclipse (/liclipse), but not when I run it in the terminal. @NeilTraft, In my case, just calling "draw()" is not sufficient. – BenB Nov 20 '16 at 22:42
  • I'm using plots on ubuntu on windows wsl through xming and the pause (not draw) was absolutely necessary. Otherwise it was just "gray" when using ion – AwokeKnowing Jun 02 '17 at 06:20
  • @Neil Traft if you're using IDLE `draw()` doesn't work – user32882 Jul 22 '17 at 08:36
  • 1
    I'm writing 6 years after the answer: According to the current docs on interactive mode, it *does not work with IDLE*; see [Usage Guide — Matplotlib 2.2.3 documentation](https://matplotlib.org/2.2.3/tutorials/introductory/usage.html#what-is-interactive-mode). This may be a change from when the answer was posted. – Tom Loredo Oct 05 '18 at 05:09
6

I am having the exact same problem. In ipython there is the magic %matplotlib, which solved the problem for me. At least now I can type plt.figure() (assuming that import matplotlib.pyplot as plt has been called) and get a fully interactive responsive figure.

However, I would still be interested to know what this magic imports exactly to be able to understand the problem.

Chris
  • 899
  • 2
  • 17
  • 25
  • 2
    This suddenly started happening to me after years of stable `plt.ion()` usage the other day—2016 felt like 2006—but the `%matplotlib` magic in IPython fixed it for me too. Kudos. – Ahmed Fasih Jul 29 '16 at 20:16