Matplotlib - Tcl_AsyncDelete: async handler delete

2020-02-08 16:29发布

I'm asking this question because I can't solve one problem in Python/Django (actually in pure Python it's ok) which leads to RuntimeError: tcl_asyncdelete async handler deleted by the wrong thread. This is somehow related to the way how I render matplotlib plots in Django. The way I do it is:

...
import matplotlib.pyplot as plt
...
fig = plt.figure()
...
plt.close()

I extremely minimized my code. But the catch is - even if I have just one line of code:

fig = plt.figure()

I see this RuntimeError happening. I hope I could solve the problem, If I knew the correct way of closing/cleaning/destroying plots in Python/Django.

2条回答
Deceive 欺骗
2楼-- · 2020-02-08 16:50

By default matplotlib uses TK gui toolkit, when you're rendering an image without using the toolkit (i.e. into a file or a string), matplotlib still instantiates a window that doesn't get displayed, causing all kinds of problems. In order to avoid that, you should use an Agg backend. It can be activated like so --

import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot

For more information please refer to matplotlib documentation -- http://matplotlib.org/faq/howto_faq.html#matplotlib-in-a-web-application-server

查看更多
放荡不羁爱自由
3楼-- · 2020-02-08 16:56

The above (accepted) answer is a solution in a terminal environment. If you debug in an IDE, you still might wanna use 'TkAgg' for displaying data. In order to prevent this issue, apply these two simple rules:

  1. everytime you display your data, initiate a new fig = plt.figure()
  2. don't close old figures manually (e.g. when using a debug mode)

Example code:

import matplotlib
matplotlib.use('TkAgg')
from matplotlib import pyplot as plt

fig = plt.figure()
plt.plot(data[:,:,:3])
plt.show()

This proves to be the a good intermediate solution under MacOS and PyCharm IDE.

查看更多
登录 后发表回答