Matplotlib - Tcl_AsyncDelete:错误的线程删除了异步处理程序?

时间:2014-11-26 10:56:22

标签: python django matplotlib

我问这个问题是因为我无法解决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中关闭/清理/破坏绘图的正确方法。

5 个答案:

答案 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'来显示数据。为了防止出现此问题,请应用以下两个简单规则:

  1. 每次显示数据时,都要启动一个新的fig = plt.figure()
  2. 请勿手动关闭旧图形(例如,在使用调试模式时)

示例代码:

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

找到这个简单的解决方案来修复这个“异步处理程序错误”是非常痛苦的,我希望这能帮助其他人:)