FigureCanvasTkAgg 的声明导致内存泄漏
Declaration of FigureCanvasTkAgg causes memory leak
我很难弄清楚为什么 FigureCanvasTkAgg 的声明会导致内存泄漏,我的 class __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 仍然在我的进程中 window 并且会阻塞我的计算机。然而,注释掉这三行将允许我的应用程序退出并且进程将正确终止。这些行对我的应用程序做了什么,阻止了应用程序完成后进程结束?谢谢
编辑
内存泄漏似乎仅由行 self.__fig = plt.figure(figsize=(16, 11))
引起。我需要在退出前用 plt 做一些解构吗?
我猜这是由于 Tkinter window 关闭时 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()
我遇到了内存泄漏问题,我想我找到了解决方案。在我的 __init__ 方法中,我创建了一个框架,然后将其传递给绘图函数以完成实际工作。在那个函数中,我会创建一个新的 matplotlib.figure.Figure 实例,由于某种原因,当函数超出范围时,它没有被销毁。
为了解决这个问题,我这样做了:在 __init__ 方法中,我不仅创建了框架,还创建了图形(带有轴)和 canvas:
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()
就这样,泄漏消失了!
我很难弄清楚为什么 FigureCanvasTkAgg 的声明会导致内存泄漏,我的 class __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 仍然在我的进程中 window 并且会阻塞我的计算机。然而,注释掉这三行将允许我的应用程序退出并且进程将正确终止。这些行对我的应用程序做了什么,阻止了应用程序完成后进程结束?谢谢
编辑
内存泄漏似乎仅由行 self.__fig = plt.figure(figsize=(16, 11))
引起。我需要在退出前用 plt 做一些解构吗?
我猜这是由于 Tkinter window 关闭时 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()
我遇到了内存泄漏问题,我想我找到了解决方案。在我的 __init__ 方法中,我创建了一个框架,然后将其传递给绘图函数以完成实际工作。在那个函数中,我会创建一个新的 matplotlib.figure.Figure 实例,由于某种原因,当函数超出范围时,它没有被销毁。
为了解决这个问题,我这样做了:在 __init__ 方法中,我不仅创建了框架,还创建了图形(带有轴)和 canvas:
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()
就这样,泄漏消失了!