matplotlib 声明FigureCanvasTkAgg导致内存泄漏

pgccezyw  于 2023-10-24  发布在  其他
关注(0)|答案(3)|浏览(184)

我很难弄清楚为什么FigureCanvasTkAgg的声明会导致内存泄漏,我在我的类__init__方法中有以下几行:

# pndwinBottom is a paned window of the main screen
   self.__drawplotFrame = Frame(pndwinBottom, width=WIDTH, height=HEIGHT)                                 # the frame on which we will add our canvas for drawing etc.

   self.__fig = plt.figure(figsize=(16,11))
   self.__drawplotCanvas = FigureCanvasTkAgg(self.__fig, master=self.__drawplotFrame)

问题是,在运行我的应用程序,并退出,python32.exe仍然在我的进程窗口,并会堵塞我的计算机.注解出这三行,但将允许我的应用程序退出,该进程将正确终止.这些行可以做什么,我的应用程序,防止该进程结束后,应用程序完成?谢谢

  • 编辑 *

内存泄漏似乎是由self.__fig = plt.figure(figsize=(16, 11))这行代码引起的。在退出之前,我需要用plt做一些解构吗?

plicqrtu

plicqrtu1#

我遇到了内存泄漏的问题,我想我找到了一个解决方案。在我的__init__方法中,我创建了一个框架,然后将其传递给绘图函数来完成实际工作。在该函数中,我将创建一个新的matplotlib.figure.Figure示例,由于某种原因,当函数超出范围时,该示例没有被销毁。
为了解决这个问题,我这样做了:在__init__方法中,我不仅创建了框架,还创建了图形(包括轴)和画布:

results = tk.Frame(self)
    f = Figure()
    ax0 = f.add_subplot(211)
    ax1 = f.add_subplot(212)
    self.canvas = FigureCanvasTkAgg(f, results)
    self.canvas.get_tk_widget().pack(expand=True, fill='both')

然后,在绘图方法中,

ax0, ax1 = self.canvas.figure.get_axes()
    ax0.clear()
    ax0.plot(x, y)

    ax1.clear()
    ax1.plot(x, z)

    self.canvas.draw()

就这样,漏洞消失了!

hs1ihplo

hs1ihplo2#

我猜这是因为当Tkinter窗口关闭时pyplot图形没有被破坏。
就像在embedding in tk example中一样,尝试使用Figure

from matplotlib.figure import Figure

self.__fig = Figure(figsize=(16,11))

示例用途:

import Tkinter as tk
import matplotlib
matplotlib.use('TkAgg')

from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

class App():
    def __init__(self, parent):

        self.__drawplotFrame = tk.Frame(parent, width=500, height=500)
        self.__drawplotFrame.pack()

        self.__fig = Figure(figsize=(16,11))
        self.__p = self.__fig.add_subplot(1,1,1)
        self.__p.plot(range(10), range(10))

        self.__drawplotCanvas = FigureCanvasTkAgg(self.__fig, master=self.__drawplotFrame)
        self.__drawplotCanvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)

root = tk.Tk()
App(root)
root.mainloop()
kcugc4gi

kcugc4gi3#

为用户提供的侧标,对于这些用户,所提供的解决方案不起作用:
在第二代gc.collect(2)的垃圾收集器的帮助下,对丢失对象的引用被删除。
这为我解决了FigureCanvasTkAgg()的几个问题。
垃圾收集器可以通过以下方式导入和使用:

import gc
gc.enable()

相关问题