a memory + CPU problem when using mpl_connect?

Questions and problems: 1/ when I load the image the first

    > time (first imshow command in the script), I see that,
    > although the amount of data is very small,
    > ipython/matplotlib already uses more than 40 Mb of memory!
    > Is that normal?

It seems high, but looks inline with the size of the mpl extension
code (though some of which is redunant numpy/numeric/numarray extensions
that shouldn't all be loaded)

peds-pc311:~/mpl/build> du -h
20M ./lib.linux-i686-2.4/matplotlib/backends
8.0K ./lib.linux-i686-2.4/matplotlib/toolkits
8.0K ./lib.linux-i686-2.4/matplotlib/numerix/mlab
8.0K ./lib.linux-i686-2.4/matplotlib/numerix/ma
8.0K ./lib.linux-i686-2.4/matplotlib/numerix/linear_algebra
8.0K ./lib.linux-i686-2.4/matplotlib/numerix/random_array
8.0K ./lib.linux-i686-2.4/matplotlib/numerix/fft
64K ./lib.linux-i686-2.4/matplotlib/numerix
40K ./lib.linux-i686-2.4/matplotlib/enthought/traits/ui/null
252K ./lib.linux-i686-2.4/matplotlib/enthought/traits/ui
632K ./lib.linux-i686-2.4/matplotlib/enthought/traits
28K ./lib.linux-i686-2.4/matplotlib/enthought/resource
12K ./lib.linux-i686-2.4/matplotlib/enthought/util
676K ./lib.linux-i686-2.4/matplotlib/enthought
40M ./lib.linux-i686-2.4/matplotlib
40M ./lib.linux-i686-2.4
40M

    > 2/ When I now use the mouse_move event, it can go up to 150
    > Mb of memory usage!! Again: is that normal?

In your example code below, I notice you are drawing on every mouse
motion. I believe there is a Tkinter specific leak in TkAgg if memory
serves, but it's outside of mpl. What backend are you using? Does
the problem go away with a different backend?

If there is a leak under our control we will certainly find it an fix
it to the best of our abilities. Our canonical memory leak checking
script (which does an imshow and more) is running rock solid on the
Agg backend so if there is a leak it is probably backend specific.

I noticed in your example script that you are only modifiying a text
entry on mouse motion. Your performance will dramatically improve if
you use the blitting techniques described in the animation tutorial.
The basic idea is to capture the background as a pixel buffer,
identify the rectangle region you want to draw the text into, draw the
background, update the text, redraw only the text rectangle etc....
See

  http://www.scipy.org/Cookbook/Matplotlib/Animations

After you've read through this if you get stuck let me know and I'll
put together a small demo for you.

JDH

Hi,

thanks for this useful and quick answer. I am (always) using GTKAgg
(hope it is a good choice). I understand the 40 Mb part then, but not
the 150-200 Mb... (this happens when I move the cursor within the figure
window only and things get worse when I reload the data with a new imshow).

Two things from what you say:

* first : should I do something before redoing another imshow? (when I
cycle many times through the 3 commands, connect, disconnect, imshow,
the mouse event updating gets really slow, and in fact it seems only the
"imshow" really makes things worse..). Maybe I need to "flush" the old
data/image/imshow ?

* second: I tried to understand what you mentioned in your email about
the blit thing. I understand the "principle", reading the wiki, and
going into mpl examples, but I didn"t manage to implement it in practice
(see my pathetic attempt below). I guess the main reason is that I am
not sure what should be the "background" in the case of a figtext...
(not ax.bbox I guess but then what?)

Any help is welcome (or a hint, since doing it myself is I guess the
best way to learn ...)

thanks again
Eric

···

#===================================================
# This script is not working... something I didn't understand in
blitting....
#===================================================
import numpy as num
import matplotlib as mpl
import matplotlib.pylab as plab

data = num.random.rand(200,200)
xy = [num.arange(0.,20,.1), num.arange(0.,20,.1)]

fig = plab.figure()
canvas = fig.canvas
im = plab.imshow(data, extent=[0.,20.,0.,20.])
ftext = plab.figtext(0.9,0.9,"", animated=True)
ax = plab.gca()
background = canvas.copy_from_bbox(ax.bbox)

def whichpix_inframe(coord) :
   indw = num.zeros(2, num.int32)
   if len(coord) == 2 :
      indw[0] = num.sort(xy[0]).searchsorted(coord[0])
      indw[1] = num.sort(xy[1]).searchsorted(coord[1])
   return indw

def mouse_move(event) :
   if event.inaxes :
     canvas.restore_region(background)
     ftext.set_text(str(data[tuple(whichpix_inframe([event.xdata,
event.ydata]))]))
     ax.draw_artist(ftext)
     canvas.blit(ax.bbox)
# canvas.draw()

id = canvas.mpl_connect('motion_notify_event', mouse_move)

canvas.mpl_disconnect(id)

John Hunter wrote:

    > 2/ When I now use the mouse_move event, it can go up to 150
    > Mb of memory usage!! Again: is that normal?

In your example code below, I notice you are drawing on every mouse
motion. I believe there is a Tkinter specific leak in TkAgg if memory
serves, but it's outside of mpl. What backend are you using? Does
the problem go away with a different backend?

...

The basic idea is to capture the background as a pixel buffer,
identify the rectangle region you want to draw the text into, draw the
background, update the text, redraw only the text rectangle etc....
See

  http://www.scipy.org/Cookbook/Matplotlib/Animation

Hi again,
thinking about the module I am writing which will include a "move mouse
event" to get the intensity of the pixel in an imshow provided in the
figure I am wondering:

- would it make any sense to DIRECTLY include such a facility (intensity
of pixel provided for an imshow, figimage…) NEXT to the coordinates x
& Y which are already there (in the lower right) in mpl figures ???

To me (at least) it would make a LOT of sense, since x,y are already
provided for any plot, or imshow-like commands. The third axis
(intensity) would then only appear when there is a third dimension is
available of course (imshow, etc). I can imagine that such a facility
could be turned on or off (I guess...).

no?

Eric