Ipython freezes after plotting with sympy plot - python

Whenever i try to plot something and close the plot window after that, I do not return into my Ipython shell. The shell freezes. The only thing I can do is close the shell and start all over again.
from sympy import *
x = symbols('x')
expr = 2 * x
plot(expr)
Gives a nice plot.
But when I close the plot window, the Ipython shell keeps waiting, apparently in a loop.

After searching AGAIN for some time I did find a workaround for this problem with interactive mode:
from matplotlib import interactive
interactive(True)
Thanks to joaquin who explains it here:
https://stackoverflow.com/a/8575569/9154139

Related

Interactive Matplotlib window not updating

I have a programme which creates an interactive matplotlib (well, pylab) figure, then waits for a raw_input while letting the user manipulate the plot to manually find the best data.
import pylab as p
p.ion()
p.figure(1)
p.plot(x,y,'.')
cen=float(raw_input('Type centre:'))
dur=float(raw_input('Type duration:'))
depth=float(raw_input('Type depth:'))
If I run this on linux (matplotlib 1.4.3), it works as expected. Running this on my Mac (matplotlib 1.5.0) freezes the pylab window at it's first draw and doesn't let the interactive features work. After something is entered into the raw_input, however, it draws all the preceding interactive clicks. Any ideas?
ion() and raw_input() do not work well together. This is a known problem. In interactive mode pyplot.ion() is using an event handler to wait for keypresses. This breaks when raw_input takes over the input.
You can make it a bit better by adding draw() or show():
import pylab as p
p.ion()
p.figure(1)
p.plot(x,y,'.')
p.show()
cen=float(raw_input('Type centre:'))
dur=float(raw_input('Type duration:'))
depth=float(raw_input('Type depth:'))

matplotlib.pyplot.draw() and matplotlib.pyplot.show() have no effect

In the past I was able to do simple animations with matplotlib with a for loop, but this hasn't worked for some time now.
The standard answer is that you have to turn interactive mode on and/or force a redraw with matplotlib.pyplot.draw(). Here is my minimal working example:
import numpy as np
import matplotlib
matplotlib.use('Qt4Agg')
import matplotlib.pyplot as mplot
mplot.ion()
fig = mplot.figure(1)
ax = fig.add_subplot(111)
for ii in np.arange(0,10):
x = 200*np.random.rand(30)
ax.plot(x)
mplot.draw()
filename = ("img_%d.png" % ii)
mplot.savefig(filename)
When I run this in Interactive Python Editor, I get one figure at the very end with all the plots in it (this also happens with mplot.show())
When I run this in IPython 3.1 (with Python 3.3.5) from the command line, I get nothing at all.
The mplot.savefig(filename) line does seem to work, as the images are generated.
(It's possible this is a bug in the Qt4 backend.)
Try deleting the line matplotlib.use('Qt4Agg'). Works for me. Also works with matplotlib.use('TkAgg'). So it is a backend problem. There is another way to do animations.

How to prevent ipython shutting down interactive mode while running a script

This page talks about the usage of ipython for interactive plotting: http://matplotlib.org/users/shell.html
According to that page, by default the %run command that is used to run scripts in ipython shuts down interactive mode. Is there an option to run the script in interactive mode as well?
I want the plotting commands in a script to take effect in the plotting figure as soon as they are run as if they are entered from the console interactively.
For example, consider the very simple script below:
# try.py:
# run in ipython that is started with
# ipython --pylab
# using
# %run -i try.py
from numpy import *
from time import sleep
ion()
x = randn(10000)
hist(x,100)
show()
sleep(5)
xlabel('labalu')
When run from ipython as indicated in the comment, this script waits 5 seconds, than shows everything. What I want is this: When run from ipython as indicated in the comment, the script should show the histogram immediately, wait 5 seconds, than update the figure to show the x label.
Moving ion() so it is after show() does what I think you want. Why it doesn't in the higher position, I do not know offhand.
If wx is used as the backend, following works:
#run in ipython that is started with ipython --pylab=wx
from numpy import *
import matplotlib
matplotlib.use('WX')
import wx
from time import sleep
import numpy as np
import matplotlib.pyplot as plt
plt.ion()
x = np.random.uniform(0,1,100)
plt.plot(x)
plt.show()
wx.Yield()
for i in reversed(range(5)):
print(i)
sleep(1)
plt.xlabel('labl')
wx.Yield()
So, wx.Yield() lets interaction with the figure window. This also works when the script is run with normal python, but the figure is closed at the end of the script automatically.
Any cross-backends solutions (or solutions for qt/tk ) are still well come.
And below is a solution that works with both the wx and qt backends. gcf().canvas.flush_events() does the trick.
# try.py:
# run in ipython that is started with
# ipython --pylab
# using
# %run -i try.py
from numpy import *
import matplotlib
from time import sleep
x = randn(10000)
hist(x,100)
show()
ion()
gcf().canvas.flush_events()
sleep(5)
xlabel('labalu')
show()

matplotlib on mac doesn't display

There are a lot of questions about installing matplotlib on mac, but as far as I can tell I've installed it correctly using pip and it's just not working. When I try and run a script with matplotlib.pyplot.plot(x, y) nothing happens. No error, no nothing.
import matplotlib.pyplot
x = [1,2,3,4]
y = [4,3,2,1]
matplotlib.pyplot.plot(x, y)
When I run this in the terminal in a file called pyplot.py I get this:
pgcudahy$ python pyplot.py
pgcudahy$
No errors, but no plot either. In an interactive python shell I get this:
>>> import matplotlib
>>> print matplotlib.__version__
1.1.1
>>> print matplotlib.__file__
/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/__init__.pyc
Which leads me to believe it's installed correctly.
Any ideas?
You need to call the show function.
import matplotlib.pyplot as plt
x = [1,2,3,4]
y = [4,3,2,1]
plt.plot(x, y)
plt.show()
It's likely that the plot is hidden behind the editor window or the spyder window on the screen. Instead of changing matplotlib settings, just learn the trackpack gestures of the mac, "app exposé" is the one you need to make your plots visible (see system preferences, trackpack). Then click on the figure to raise it to the front.

Matplotlib, Pylab using TKAgg: encountering PyEval_RestoreThread: NULL tstate when using plt.ion() on win32

EDIT:
Bah, finally found a discussion on the Runtime Error, although it focuses on using PythonWin, which I did not have installed at the time. After installing PythonWin and setting up GTK (as per an earlier question), I was still encountering the error. The solution from the discussion board here was to append plt.close() after the for loop. This seems to work.
However:
From the command line, window is still unmovable while plotting. When exiting, PyEval_RestoreThread no longer runs into NULL tstate. It would be nice to allow the window to move while plotting.
Original Post:
Note: All problems described are encountered when running from command line. Similar quirks are encountered when running from IDLE Shell (-n), as noted in the "Additional, possibly irrelevant information" section.
My code plots a line correctly, and immediately after plotting I get:
"Fatal Python error: PyEval_RestoreThread: NULL tstate
This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information."
The code follows:
import matplotlib as mpl
mpl.use("TKAgg")
import pylab as plt
import numpy as np
Line = mpl.lines.Line2D
x = np.linspace(-1,1,50)
y=np.sin(x*np.pi)
plt.ion()
fig = plt.gcf()
ax = fig.gca()
ax.add_line(Line([x],[y]))
plt.draw()
The code is fine when commenting out plt.ion(), but then nothing is shown.
While plt.show() would work in this example, the goal is to use interactive to create a crude animation through the following:
import matplotlib as mpl
mpl.use("TKAgg")
import pylab as plt
import numpy as np
plt.ion()
Line = mpl.lines.Line2D
x = np.linspace(-1,1,50)
for i in xrange(10):
y = (1.0+i/9.0) * np.sin(x*np.pi)
plt.clf()
fig = plt.gcf()
ax = fig.gca()
ax.add_line(Line([x],[y]))
plt.draw()
Each iteration correctly plots its respective line, and any code after the loop runs before the fatal error, as can be demonstrated by adding the following immediately following the for loop:
raw_input("no error yet: ")
print "here it comes"
I realize that destroying the figure and then creating a new figure and new axes may not be efficient or even good practice. However, the problem still seems to be on plt.ion(), as commenting it out produces no errors.
If the solution is well-documented and I've passed it by in my searches, please feel free to angrily point this out and perhaps provide a link to such. This would be much preferred, if the alternative is having run into a new problem.
If the answer is to manage plotting more directly than using pylab, I am more than willing to explore this option.
Additional, possibly irrelevant information:
When not using raw_input() after for loop, window is unmovable while running second code.
If using raw_input(), window can be moved after plotting, while program is waiting for raw_input()
Issue is the same when running from IDLE Shell (-no subprocess):
Window cannot be moved while plotting, but does not encounter fatal error.
Window can be moved after plotting, even without using raw_input()
From either command line or IDLE Shell, each plot is correctly displayed while window is unmovable
Thanks in advance for any suggestions/advice.

Categories

Resources