我问这个问题是因为我无法解决Python/Django
中的一个问题(实际上在纯Python中它没问题)导致RuntimeError: tcl_asyncdelete async handler deleted by the wrong thread
。这与我在Django中呈现matplotlib
图的方式有某种关系。我这样做的方式是:
...
import matplotlib.pyplot as plt
...
fig = plt.figure()
...
plt.close()
我极度最小化了我的代码。但问题是 - 即使我只有一行代码:
fig = plt.figure()
我发现这个RuntimeError正在发生。我希望我能解决这个问题,如果我知道在Python / Django中关闭/清理/破坏绘图的正确方法。
答案 0 :(得分:27)
默认情况下,matplotlib使用TK gui工具包,当你在不使用工具包的情况下渲染图像时(即进入文件或字符串),matplotlib仍会实例化一个不显示的窗口,从而导致各种问题。为了避免这种情况,您应该使用Agg后端。它可以像这样激活 -
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot
有关详细信息,请参阅matplotlib文档 - http://matplotlib.org/faq/howto_faq.html#matplotlib-in-a-web-application-server
答案 1 :(得分:1)
以上(可接受的)答案是终端环境中的解决方案。如果在IDE中进行调试,您可能仍想使用'TkAgg
'来显示数据。为了防止出现此问题,请应用以下两个简单规则:
fig = plt.figure()
示例代码:
import matplotlib
matplotlib.use('TkAgg')
from matplotlib import pyplot as plt
fig = plt.figure()
plt.plot(data[:,:,:3])
plt.show()
在MacOS和PyCharm IDE下,这被证明是一个很好的中间解决方案。
答案 2 :(得分:0)
如果您不需要在调试时显示图,则可以使用以下方法:
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot as plt
但是,如果要在调试时绘图,则需要执行3个步骤:
1。将后端保持为“ TKAgg”,如下所示:
import matplotlib
matplotlib.use('TKAgg')
from matplot.lib import pyplot as plt
或者简单地
import matplotlib.pyplot as plt
2。正如Fábio所述,您需要为每个图#i添加fig(编号#i)= plt.figure(编号#i)。作为#1地块的以下示例,添加:
fig1 = plt.figure(1)
plt.plot(yourX,yourY)
plt.show()
3。添加断点。您需要至少添加两个断点,一个在代码开头的某个位置(在第一个绘图之前),另一个断点在您希望绘制所有绘图(在第二个断点之前)的位置。所有图形均已绘制,您甚至无需手动关闭任何图形。
答案 3 :(得分:0)
对我来说,这是因为在 Tensorboard 的服务器连续运行一周后,Matplotlib 和 Tensorboard 并行访问数据。
重新安装 tensorboard tensorboard --logdir . --samples_per_plugin images=100
为我解决了这个问题。
答案 4 :(得分:0)
我在 tkinter 应用程序中使用 matplotlib 实时绘制图形时遇到了这个问题。
我找到的最简单的解决方案是始终删除子图。我发现你不需要实例化一个新的图形,你只需要删除旧的子图(使用 del subplot),然后重新制作它。
在绘制新图形之前,请确保删除旧的子图。 示例:
f = Figure(figsize=(5,5), dpi=100)
a = f.add_subplot(111)
(For Loop code that updates graph every 5 seconds):
del a #delete subplot
a = f.add_subplot(111) #redefine subplot
找到这个简单的解决方案来修复这个“异步处理程序错误”是非常痛苦的,我希望这能帮助其他人:)