解决 matplotlib 和 PySimpleGUI 结合使用中的内存泄露问题
记录使用matplotlib绘图遇到的内存泄露问题
最近我在用matplotlib进行数据可视化时,遇到了一道令人头疼的难题:内存泄漏。 虽然单独运行matplotlib多次生成绘制图没问题,但一旦与pysimplegui结合使用,内存占用就会快速上升,最终导致程序崩溃。经过一番折腾和查阅资料,终于找到了解决方案!
’’' Traceback (most recent call last): File “C:\Python311\Lib\site-packages\matplotlib_pylab_helpers.py”, line 81, in destroy_all manager.destroy() File “C:\Python311\Lib\site-packages\matplotlib\backends_backend_tk.py”, line 562, in destroy self.canvas._tkcanvas.after_cancel(self.canvas.idle_draw_id) File “C:\Python311\Lib\tkinter_init.py”, line 893, in after_cancel data = self.tk.call(‘after’, ‘info’, id)
’’’
Matplotlib和tkinter的关系
首先,我们需要了解matplotlib和tkinter之间的关系。 matplotlib是一个用于创建静态、动画和交互式可视化的绘图库,而 tkinter则是Python标准的GUI工具包,用于创建桌面应用程序的窗口、按钮等界面元素。
在一些情况下,matplotlib会使用tkinter作为其后端来实现交互式图形功能。例如,当我们想要在一个 GUI 应用中嵌入 matplotlib 图表时,就会用到 tk 后端。
内存泄露的原因
我的问题源于这个 tk 后端的依赖关系。 使用 tk 后端时,matplotlib 会与 PySimpleGUI 中使用的 tkinter 进行冲突,导致资源管理混乱,最终引发内存泄漏。 这种冲突可能发生在以下方面:
- 后端冲突: PySimpleGUI 默认使用 tkinter, 当 matplotlib 也使用 tk 后端时,可能会导致两个库之间的资源管理冲突。
- 事件循环干扰: PySimpleGUI 和 matplotlib(使用 tk 后端时)可能都试图控制 tkinter 的事件循环,导致资源无法正确释放。
解决方案
最终,我通过切换 matplotlib 的后端解决了问题。 将matplotlib的backend从tk改成Agg
后端就能够避免内存泄漏。 ‘Agg’ 是一种非交互式后端,专门用于创建图像文件,它与 GUI 完全无关。
步骤如下:
- 在导入 matplotlib 之前,使用
matplotlib.use('Agg')
设置后端。 - 使用
plt.savefig('output.png')
保存图形到文件。
import matplotlib matplotlib.use(‘Agg’)
总结
这段经历让我深刻体会到软件开发中的复杂性。即使是看似独立的库之间也可能存在难以察觉的相互影响。
此外,以下几点也值得我们牢记:
- 谨慎选择后端: 在使用 matplotlib 时,要根据实际需求选择合适的 backend,避免不必要的依赖关系。
- 仔细管理资源: 使用matplotlib时,一定要及时释放资源,例如使用
plt.close()
关闭图形窗口。
希望我的经验能帮助其他开发者避免类似的困扰!
- 原文作者:iamdev
- 原文链接:https://blog.iamdev.cn/post/2024/%E8%A7%A3%E5%86%B3_matplotlib_%E5%92%8C_PySimpleGUI_%E7%BB%93%E5%90%88%E4%BD%BF%E7%94%A8%E4%B8%AD%E7%9A%84%E5%86%85%E5%AD%98%E6%B3%84%E9%9C%B2%E9%97%AE%E9%A2%98__/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止转载 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。