imshow memory leak in pylab mode?

6 : ax.images
7 : im = imshow(data)
8 : ax.images
9 : ax.images.remove[0]
10: del ax.images.remove[0]

Both of these lines are wrong. You either need to do

  ax.images.remove(0) # note the parens, not square brackets

or

del ax.images[0]

*doh*, of course, me stupid. Sorry, it's very very hot here. :slight_smile:

Also, you are mixing API calls, eg

  ax = fig.add_subplot(111)

with pyplot call, eg

  im = imshow(data)

While this isn't a bug in this case, it is not good form. The pyplot
calls manage stateful information like current image and current axes,
and you are safer using all pyplot or all api. So for pure pyplot:

  subplot(111)
  imshow(data)

or pure API:

  ax = fig.add_subplot(111)
  ax.imshow(data)

Yeah, sorry, i thought it wouldn't matter, as i did not need an image object for this demo.

Even so i set hold(False), and the ax.images array does not increase,
the memory consumption increases.

I used these commands:

3 : fig = figure()
4 : ax = fig.add_subplot(111)
5 : imshow(data)
6 : ax.images
7 : hold(False)
8 : imshow(data)
9 : ax.images

At step 6 I had 1 image in the ax.images array, at step 9 still only 1,
but RealMem went up the approx same amount between 7 and 8 then it did
between 4 and 5.

I don't see this -- try using gc.collect() if you think you see a leak
and use cbook.report_memory to get a measure of consumed memory. If
you still think you have a leak, try and build a complete
free-standing script that replicates it.

I only can reproduce it inside a pylab session, as you see here:

IPython 0.10 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object'. ?object also works, ?? prints more.

  Welcome to pylab, a matplotlib-based Python environment.
  For more information, type 'help(pylab)'.

In [1]: import gc

In [2]: gc.collect?
Type: builtin_function_or_method
Base Class: <type 'builtin_function_or_method'>
String Form: <built-in function collect>
Namespace: Interactive
Docstring:
    collect([generation]) -> n

    With no arguments, run a full collection. The optional argument
    may be an integer specifying which generation to collect. A ValueError
    is raised if the generation number is invalid.

    The number of unreachable objects is returned.

In [3]: import matplotlib.cbook as cbook

In [4]: data = ones((1500,1500,3))

In [5]: imshow(data)

Out[5]: <matplotlib.image.AxesImage object at 0x1c57610>

In [6]: ax =gca()

In [7]: cbook.report_memory()

Out[7]: 175384

In [8]: hold(False)

In [9]: len(ax.images)

Out[9]: 1

In [10]: imshow(data)

Out[10]: <matplotlib.image.AxesImage object at 0x1416430>

In [11]: cbook.report_memory()

Out[11]: 254624

In [12]: len(ax.images)

Out[12]: 1

In [13]: gc.collect()

Out[13]: 12

Don't know what to do with the 12 though?

If I do the same with a script like this:
from matplotlib.pylab import *
import matplotlib.cbook as cbook

data = ones((1500,1500,3))
imshow(data)
ax = gca()
print cbook.report_memory()
print len(ax.images)
hold(False)
imshow(data)
print cbook.report_memory()
print len(ax.images)
imshow(data)
print cbook.report_memory()
print len(ax.images)
imshow(data)
print cbook.report_memory()
print len(ax.images)
imshow(data)
print cbook.report_memory()
print len(ax.images)

This is what happens:
81920
1
82028
1
82128
1
82128
1
82132
1
So it's fine here.
So what's wrong with my ipython/pylab? :frowning:

BR,
Michael

still not seeing a leak in your data -- you need to report_memory
after calling gc collect. Turn off hold, add an image, call collect,
report memory, the repeat several times, each time calling collect and
report memory, and report the results.

JDH

···

On Wed, Jul 14, 2010 at 11:38 AM, K.-Michael Aye <kmichael.aye@...287...> wrote:

Out[12]: 1

In [13]: gc.collect()

Out[13]: 12