savefig Memory Leak

Could you try to use figure() instead of Figure()? That often creates a mess on my side.
Or should one use Figure() in the 'Artist's style? I am still importing pyplot as plt, and in that case, I have to use figure(), otherwise things don't work.

I also had the feeling of a leak and am currently doing this without much 'leaking': :slight_smile:

    fig = plt.figure()
    ax = fig.add_subplot(111)
    im = ax.imshow(nData)
    cb = plt.colorbar(im)
    ax.set_title(bname + ', ' + mode)
    fig.savefig(filename + '.equal.png')
    plt.close(fig)

I think, the plt.close(fig) was quite important in my case.
Give it a try!

Best regards,
Michael

路路路

On 2010-04-16 19:18:56 +0200, Keegan Callin said:

Hello,

I have written a small script that, I think, demonstrates a memory leak
in savefig. A search of the mailing list shows a thread started by Ralf
Gommers <ralf.gommers@...982...> about 2009-07-01 that seems to
cover a very similar issue. I have appended the demonstration script at
the end of this e-mail text.

[keegan@...3070... ~]$ python2.6
Python 2.6.4 (r264:75706, Jan 20 2010, 12:34:05)
[GCC 4.4.2 20091222 (Red Hat 4.4.2-20)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import matplotlib
>>> matplotlib.__version__
'0.99.1.1'
'''
# Import standard python modules
import sys
import os
from ConfigParser import SafeConfigParser as ConfigParser
from cStringIO import StringIO

# import numpy
import numpy
from numpy import zeros

# Import matplotlib
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas

def build_figure(a):
     '''Returns a new figure containing array a.'''

     # Create figure and setup graph
     fig = Figure()

Hello Michael,

I have not tried using plt.figure() and plt.close(fig) but you are right; I should investigate it as well for completeness. I had, actually, purposefully avoided doing this because I read that the pyplot API is stateful. It keeps references to figures in the same way that MatLab does and these figures need to be explicitly closed (via plt.close). By calling Figure(...) directly I am trying to use matplotlib's object-oriented API and avoid pyplot's statefullness.

Something interesting and perhaps enlightening is to switch backends from Agg to something else (say Cairo). In the demonstration script that I posted you would do so like this:

#from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.backends.backend_cairo import FigureCanvasCairo as FigureCanvas

When using the Cairo backend the memory leak disappears. In my mind, this indicates a memory leak when using the Agg backend that DOES NOT appear when using the Cairo backend.

Thanks for the advice; I will give pyplot a try and see if I get different behaviour.

Sincerely,
Keegan Callin

路路路

On 04/19/2010 11:28 AM, K.-Michael Aye wrote:

Could you try to use figure() instead of Figure()? That often creates a
mess on my side.
Or should one use Figure() in the 'Artist's style? I am still importing
pyplot as plt, and in that case, I have to use figure(), otherwise
things don't work.

I also had the feeling of a leak and am currently doing this without
much 'leaking': :slight_smile:

     fig = plt.figure()
     ax = fig.add_subplot(111)
     im = ax.imshow(nData)
     cb = plt.colorbar(im)
     ax.set_title(bname + ', ' + mode)
     fig.savefig(filename + '.equal.png')
     plt.close(fig)

I think, the plt.close(fig) was quite important in my case.
Give it a try!