相关文章推荐
粗眉毛的松鼠  ·  Axure RP 8 ...·  1 年前    · 
纯真的领结  ·  GitHub - ...·  2 年前    · 

Python Matplotlib: 解决 Tcl_AsyncDelete: async handler deleted by the wrong thread

问题:
在同时使用 PyQt5 中的 QThread matplotlib.pyplot 时,虽然一开始所有的图形都能顺利生成,但是在关闭窗口的时候,就会生成以下的错误:

Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "C:\Users\XXX\Miniconda3\lib\site-packages\matplotlib\_pylab_helpers.py", line 73, in destroy_all
    manager.destroy()
  File "C:\Users\XXX\Miniconda3\lib\site-packages\matplotlib\backends\_backend_tk.py", line 561, in destroy
    self.window.destroy()
  File "C:\Users\XXX\Miniconda3\lib\tkinter\__init__.py", line 2061, in destroy
    for c in list(self.children.values()): c.destroy()
  File "C:\Users\XXX\Miniconda3\lib\tkinter\__init__.py", line 2305, in destroy
    self.tk.call('destroy', self._w)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x0000022484EF57B8>>
Traceback (most recent call last):
  File "C:\Users\XXX\Miniconda3\lib\tkinter\__init__.py", line 3507, in __del__
    self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x000002248A604940>>
Traceback (most recent call last):
  File "C:\Users\XXX\Miniconda3\lib\tkinter\__init__.py", line 3507, in __del__
    self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x000002248A68D208>>
Traceback (most recent call last):
  File "C:\Users\XXX\Miniconda3\lib\tkinter\__init__.py", line 3507, in __del__
    self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x000002248A89C080>>
Traceback (most recent call last):
  File "C:\Users\XXX\Miniconda3\lib\tkinter\__init__.py", line 3507, in __del__
    self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x000002248A8EF828>>
Traceback (most recent call last):
  File "C:\Users\XXX\Miniconda3\lib\tkinter\__init__.py", line 3507, in __del__
    self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x000002248A90BA90>>
Traceback (most recent call last):
  File "C:\Users\XXX\Miniconda3\lib\tkinter\__init__.py", line 3507, in __del__
    self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x000002248A8EFF60>>
Traceback (most recent call last):
  File "C:\Users\XXX\Miniconda3\lib\tkinter\__init__.py", line 3507, in __del__
    self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Tcl_AsyncDelete: async handler deleted by the wrong thread

原因:
一开始我以为是多线程的问题,后来才发现是matplotlib.pyplot造成的问题。matplotlib.pyplot在运行的时候,是需要在主线程(Main Thread)上运行的,然而,我在使用多线程的时候,将使用matplotlib.pyplot的函数用在了子线程里面。之后也在matplotlib的官方FAQ找到了相应的原因,如下图:
在这里插入图片描述

解决方法:
将原本的import matplotlib.pyplot as plt修改成以下:

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

参考链接:
StackOverflow: Tcl_AsyncDelete: async handler deleted by the wrong thread
Matplotlib的官方FAQ

Python Matplotlib: 解决 Tcl_AsyncDelete: async handler deleted by the wrong thread问题:在同时使用PyQt5中的QThread和matplotlib.pyplot时,虽然一开始所有的图形都能顺利生成,但是在关闭窗口的时候,就会生成以下的错误:Error in atexit._run_exitfuncs:Trace... 消耗网络服务 .Net 框架使使用多线程 Web 应用程序变得更加容易。 应用程序使用 async 和 await 关键字来启用异步编程,并且编译器会自动应用必要的转换以使用回调以避免阻塞线程。 它通过在后台运行非阻塞线程来提高性能。 为了制作一个异步方法(或ASP.net MVC世界中的动作),我们需要用async关键字标记方法并创建一个返回的Task。我们还需要使用await关键字来进行web服务调用. 公共异步任务 IndexAsAsync() { var assets = await _client.GetAsync(); 返回视图(资产)} 访问以获取有关 ASP.net MVC/Web API 中异步编程的更多信息。
asyncqt - asyncio + PyQt5/PySide2 重要提示:此项目未维护。 使用其他替代方案,例如 asyncqt是带有Qt的PEP 3156事件循环的实现。 这个包是quamash一个分支,专注于现代 Python 版本,带有一些额外的实用程序、示例和简化的 CI。 asyncqt需要 Python >= 3.5 和 PyQt5 或 PySide2。 可以使用QT_API环境变量显式设置 Qt API。 pip install asyncqt 您可以在examples文件夹中找到使用示例。
报错如下: Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x000001B31B4E6470>> Traceback (most recent call last): File "C:\Python\Python36\...
python3 async 实践 async/await 是python3的新特性,可以进行协程运行。个人将他理解成多线程。实现代码如下 #!/usr/bin/python3 # -*- coding: utf-8 -*- import time import asyncio async def SleepTime(ts): if ts == 3: await asyncio.sleep(10) #当ts等于3的时候,让挂起的时间为10s,其他的按正常挂起,验证协程时间。
deprecationwarning: `set_matplotlib_formats` is deprecated since ipython 7.23, directly use `matplotlib_inline.backend_inline.set_matplotlib_formats()` display.set_matplotlib_formats('svg')
### 回答1: 警告:`set_matplotlib_formats`自ipython 7.23版本起已被弃用,请直接使用`matplotlib_inline.backend_inline.set_matplotlib_formats()`,并使用`display.set_matplotlib_formats('svg')`来设置SVG格式。 ### 回答2: 首先,对于Python程序员来说,我们常常会使用matplotlib这个图像库来进行数据可视化。但是,在使用过程中,可能会遇到如下的问题: deprecationwarning: `set_matplotlib_formats` is deprecated since ipython 7.23, directly use `matplotlib_inline.backend_inline.set_matplotlib_formats()` display.set_matplotlib_formats('svg')。 这个问题的意思是提示我们使用set_matplotlib_formats()这个函数时会出现警告,因为ipython的版本已经更新到了7.23,而set_matplotlib_formats()这个函数已经被弃用了。 知道了这个问题,我们怎么去解决呢? 其实,在新版本的ipython中,我们可以直接使用matplotlib_inline.backend_inline.set_matplotlib_formats()这个函数来代替set_matplotlib_formats(),并且实现的效果是一样的。 除此之外,还可以使用display.set_matplotlib_formats('svg')来设置输出格式,这个函数也能够输出图片,只不过它只支持SVG格式的输出。 这些函数的使用方式比较简单,我们只需要在代码中进行相应的修改,即可顺利运行我们的程序。当然,这个问题的解决也提示我们要随时关注我们所使用的库的版本,以确保我们的程序能够正常运行。 ### 回答3: 简单来说,这个DeprecationWarning是Python在告诉我们现在的设置方法已经过时了,应该使用新的方法来设置。具体来说,这个警告是针对在使用IPython 7.23及以上版本时调用set_matplotlib_formats()函数的用户发出的。 set_matplotlib_formats()函数是一种设置图形格式的方法,旧的IPython版本中经常用到它来为matplotlib生成的图形设置格式,比如说png或者svg格式。但在新的IPython版本中,这个函数被认为是过时的了,因此旧版本中使用的代码需要进行修改。 替代set_matplotlib_formats()函数的新方法是调用matplotlib_inline.backend_inline.set_matplotlib_formats()和display.set_matplotlib_formats('svg')。这些新方法提供了更好的API,并且更符合Python代码风格的规范。 总的来说,如果你正在使用较新版本的IPython,想修改matplotlib图形的格式,那么建议使用新的设置方法。这不仅能避免警告产生,而且能够更好地提高您Python代码编写的效率。
Python pd.DataFrame: 解决 ‘ValueError: Shape of passed values is (6, 1), indices imply (6, 6)‘ 28486 Python Matplotlib: 解决 Tcl_AsyncDelete: async handler deleted by the wrong thread chaichaicai: YOLO v5出现这个问题,应该改哪里的代码呢?