Matplotlib, Pylab using TKAgg: encountering PyEval

2019-05-26 02:50发布

问题:

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.