imshow memory leak in pylab mode?

Dear all,

I'm not sure if this is by design or a problem:

It's by design and is not a leak. matplotlib supports multiple images
on the same axes, and can composite multiple images that overlap the
same space using transparency, so each call to imshow is adding
additional data to the axes.

Understood, and of course quite useful. But see below.

You can inspect the ax.images list to
see the list of images is growing.

If you have an Image object and want to remove it from the Axes, call

  im.remove()

This worked.

or you can manipulate the list of ax.images directly, eg

  del ax.images[0]

I tried this and got this error message:

In [10]: del ax.images.remove[0]

···

On 2010-07-14 01:46:49 +0200, John Hunter said:

On Mon, Jul 12, 2010 at 5:06 PM, K.-Michael Aye > <kmichael.aye@...287...> wrote:

On 2010-07-12 23:17:19 +0200, John Hunter said:

On Mon, Jul 12, 2010 at 4:06 PM, K.-Michael Aye >>> <kmichael.aye@...287...> wrote:

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)

/Users/aye/Documents/workspace/pyrise_saver_clone/src/<ipython console> in <module>()

TypeError: 'builtin_function_or_method' object does not support item deletion

Here my history of that session:

1 : from fan_finder import get_data
2 : data = get_data(2)
3 : fig = figure()
4 : ax = fig.add_subplot(111)
5 : im = imshow(data)
6 : ax.images
7 : im = imshow(data)
8 : ax.images
9 : ax.images.remove[0]
10: del ax.images.remove[0]
11: hist%
12: _ip.magic("hist ")

data is a np.array

I found another funny thing:

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.

or if you have a single image and want to update the data in it, you can do

  im = ax.imshow(something)
  im.set_array(newdata)

I am using this way in a GUI I programmed and works very well there.

BR,
Michael

to update the array in the existing image.

JDH

------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first

Dear all,

I'm not sure if this is by design or a problem:

It's by design and is not a leak. matplotlib supports multiple images
on the same axes, and can composite multiple images that overlap the
same space using transparency, so each call to imshow is adding
additional data to the axes.

Understood, and of course quite useful. But see below.

You can inspect the ax.images list to
see the list of images is growing.

If you have an Image object and want to remove it from the Axes, call

im.remove()

This worked.

or you can manipulate the list of ax.images directly, eg

del ax.images[0]

I tried this and got this error message:

In [10]: del ax.images.remove[0]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)

/Users/aye/Documents/workspace/pyrise_saver_clone/src/<ipython console>
in <module>()

TypeError: 'builtin_function_or_method' object does not support item deletion

Here my history of that session:

1 : from fan_finder import get_data
2 : data = get_data(2)
3 : fig = figure()
4 : ax = fig.add_subplot(111)
5 : im = imshow(data)
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]

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)

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.

In [220]: import matplotlib.cbook as cbook

In [221]: cbook.report_memory
Out[221]: <function report_memory at 0x87fd5a4>

In [222]: cbook.report_memory()
Out[222]: 81733

In [223]: hold(False)

In [224]: ax = gca()

In [225]: len(ax.images)
Out[225]: 1

In [226]: imshow(data)
Out[226]: <matplotlib.image.AxesImage object at 0xc7455ec>

In [227]: len(ax.images)
Out[227]: 1

In [228]: cbook.report_memory()
Out[228]: 81733

In [229]: imshow(data)
Out[229]: <matplotlib.image.AxesImage object at 0xd4752ac>

In [230]: len(ax.images)
Out[230]: 1

In [231]: imshow(data)
Out[231]: <matplotlib.image.AxesImage object at 0xe4ee72c>

In [232]: len(ax.images)
Out[232]: 1

In [233]: cbook.report_memory()
Out[233]: 81733

JDH

···

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

On 2010-07-14 01:46:49 +0200, John Hunter said:

On Mon, Jul 12, 2010 at 5:06 PM, K.-Michael Aye >> <kmichael.aye@...287...> wrote:

On 2010-07-12 23:17:19 +0200, John Hunter said:

On Mon, Jul 12, 2010 at 4:06 PM, K.-Michael Aye >>>> <kmichael.aye@...287...> wrote: