EDIT:
呸,终于找到了关于Runtime Error的讨论,虽然重点是使用PythonWin,而我当时还没有安装。安装 PythonWin 并设置 GTK 后(按照先前的问题 https://stackoverflow.com/questions/2604119/matplotlib-pyplot-pylab-not-updating-figure-while-isinteractive-using-ipython/3669748#3669748),我仍然遇到错误。讨论区的解决方案here http://www.mailinglistarchive.com/html/matplotlib-users@lists.sourceforge.net/2010-02/msg00164.html是在 for 循环之后附加 plt.close() 。这似乎有效。
However:
从命令行中,绘图时窗口仍然不可移动。退出时,PyEval_RestoreThread 不再遇到 NULL tstate。如果在绘图时允许窗口移动就好了。
原帖:
注意:所描述的所有问题都是从命令行运行时遇到的。从 IDLE Shell (-n) 运行时会遇到类似的问题,如“其他可能不相关的信息”部分所述。
我的代码正确绘制了一条线,绘制后我立即得到:
“致命的 Python 错误:PyEval_RestoreThread:NULL tstate
此应用程序已请求运行时以异常方式终止它。请联系应用程序的支持团队以获取更多信息。”
代码如下:
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()
注释掉 plt.ion() 时代码很好,但随后什么也没有显示。
虽然 plt.show() 在此示例中有效,但目标是通过以下方式使用交互式创建原始动画:
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()
每次迭代都会正确地绘制其各自的行,并且循环之后的任何代码都会在致命错误之前运行,这可以通过在 for 循环之后立即添加以下内容来证明:
raw_input("no error yet: ")
print "here it comes"
我意识到破坏图形然后创建新图形和新轴可能不是有效的,甚至不是好的做法。然而,问题似乎仍然出在 plt.ion() 上,因为将其注释掉不会产生错误。
如果该解决方案有详细记录,并且我在搜索中忽略了它,请随时愤怒地指出这一点,也许还提供一个链接。如果替代方案遇到新问题,这将是更可取的。
如果答案是比使用 pylab 更直接地管理绘图,我非常愿意探索这个选项。
其他可能不相关的信息:
- 当 for 循环后不使用 raw_input() 时,窗口在运行第二个代码时不可移动。
- 如果使用 raw_input(),则可以在绘图后移动窗口,而程序正在等待 raw_input()
- Issue is the same when running from IDLE Shell (-no subprocess):
- 绘图时窗口无法移动,但不会遇到致命错误。
- 即使不使用 raw_input(),也可以在绘图后移动窗口
- 从命令行或 IDLE Shell,每个图都能正确显示,而窗口不可移动
预先感谢您的任何建议/意见。