Search code examples
pythonpython-2.7matplotlibmemory-leakstkinter

Declaration of FigureCanvasTkAgg causes memory leak


I'm having difficulty figuring out just why the declaration of FigureCanvasTkAgg causes a memory leak, I have the following lines in my class __init__ method:

   # 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)

the problem is that upon running my application , and exiting, python32.exe remains in my process window and will clog up my computer. Commenting out these three lines however will allow my application to exit and the process will correctly terminate. What could these lines be doing to my application that prevents the process from ending after the application is finished? Thanks

edit


The memory leak seems to be caused by only the line self.__fig = plt.figure(figsize=(16, 11)) . Do I need to do some sort of deconstruction with plt before exiting?


Solution

  • I'm gonna guess this is caused by the pyplot figure not being destroyed when the Tkinter window is closed.
    Like in the embedding in tk example try using Figure:

    from matplotlib.figure import Figure
    
    self.__fig = Figure(figsize=(16,11))
    

    example use:

    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()