Hello everybody,

I'm building a small Tkinter GUI using matplotlib, in which I have to  
change/update plots quite often depending on user input (with different  
contents & sizes, in different places in the GUI, etc.; but always only  
one figure at a time).

As a first resort, I regenerated the figures with plt.figure(...) whenever  
necessary; unfortunately, the program happily accumulated memory with  
every new figure until the computer would no longer cooperate in a timely  
fashion. The following minimal script should demonstrate the tendency:

--- start of script ---

import math
 from Tkinter import Tk, Button
import Tkconstants
 from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
 from matplotlib.figure import Figure
 from matplotlib import pyplot as plt

def replot():
     global globalCanvas, globalFigure, plotShift

     # any variety of clean-up calls
     if globalFigure is not None:
         plt.close()
         globalCanvas.get_tk_widget().destroy()
         globalFigure.clf()

     globalFigure = Figure(dpi=120, figsize=(4, 4))

     globalCanvas = FigureCanvasTkAgg(globalFigure, master=root)
     globalCanvas.get_tk_widget().grid(row=0, column=1)

     xVals = xrange(100)
     ax = globalFigure.add_subplot(111)
     ax.plot(xVals, [math.sin(x + plotShift) for x in xVals])
     plotShift += 10

# MAIN
globalCanvas = None
globalFigure = None
plotShift = 0 # just to see the plot change

root = Tk()

draw_button = Button(root, text="Replot", command=replot)
draw_button.grid(row=0, column=0, sticky=Tkconstants.N)

root.mainloop()

--- end of script ---


I have tried various clean-up calls, but the effect (of memory piling up)  
is always the same. Using objgraph (http://mg.pov.lt/objgraph/), I took a  
look at object counts by adding the following snippet at the end of the  
"replot" call:

--- start of insertion ---

     import gc
     import objgraph
     gc.collect()
     print "---"
     for c in ('FigureCanvasTkAgg', 'Figure'):
         print "{}\t{}".format(len(objgraph.by_type(c)), c)

--- end of insertion ---

The output shows that the total number of both Figures and  
FigureCanvasTkAggs increases constantly (i.e., one each after the first  
call, then two each, etc.), whereas I had expected that old ones get  
released, and that the count remains at one each.

Now I am wondering if I am missing some detail, e.g., some other clean-up  
procedure? Or should this work & could be a memory leak in matplotlib or  
Tkinter? And/or is this approach (of generating a new figure every time)  
not recommended in the first place? I tried reusing the figure, but some  
aspects like changing the layout in the GUI and applying new size and dpi  
then proved tricky in their own ways.

Many thanks in advance,
Hans

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_sfd2d_oct
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Reply via email to