FigureCanvasQTAgg clean up

Hi,

  I spend some time writing up the question below on Stackoverflow

which immediately was closed as a duplicate of other posts. To my
best knowledge, these posts did not answer my questions - so I’ll
try my luck here instead:

  I am using the qt backengine for setting up a QWidget that embeds

a matplotlib scene. When the widget is closed it appears that many
of the matplotlib objects that were part of the plot still are
alive in Python space.

  My question is basically the following: What actions should I take

to clean up the figure and axes objects etc. that were part of the
plot widget? The qt backend comes with a figure manager, but it
appears a little unclear how it should be used.

  I have attached a small unit test example that sets up a plot.

When the plot appears, just close it, and the test will garbage
collects the plot, and then display info of the matplotlib objects
that are still alive in Python space. Clearly both the path of the
plot, and several Bbox objects are still referenced.

  Our current unit test suite contains almost 10000 GUI tests and

its imperative that proper object space clean up is done after
each test. Any help is much appreciated.

  Best regards,

  Mads

plot.py (2.43 KB)

···
-- +-----------------------------------------------------+
| Mads Ipsen |
+----------------------+------------------------------+
| Gåsebæksvej 7, 4. tv | |
| DK-2500 Valby | phone: +45-29716388 |
| Denmark | email: |
+----------------------+------------------------------+

mads.ipsen@…287…

Would “fig.clf()” do what you need?

Ben Root

···

On Tue, Jan 29, 2013 at 5:12 PM, Mads Ipsen <mads.ipsen@…287…> wrote:


Hi,

  I spend some time writing up the question below on Stackoverflow

which immediately was closed as a duplicate of other posts. To my
best knowledge, these posts did not answer my questions - so I’ll
try my luck here instead:

  I am using the qt backengine for setting up a QWidget that embeds

a matplotlib scene. When the widget is closed it appears that many
of the matplotlib objects that were part of the plot still are
alive in Python space.

  My question is basically the following: What actions should I take

to clean up the figure and axes objects etc. that were part of the
plot widget? The qt backend comes with a figure manager, but it
appears a little unclear how it should be used.

  I have attached a small unit test example that sets up a plot.

When the plot appears, just close it, and the test will garbage
collects the plot, and then display info of the matplotlib objects
that are still alive in Python space. Clearly both the path of the
plot, and several Bbox objects are still referenced.

  Our current unit test suite contains almost 10000 GUI tests and

its imperative that proper object space clean up is done after
each test. Any help is much appreciated.

  Best regards,



  Mads

Thanks for the feedback.

The trick is to get this done automatically when the widget is closed. If you look in backend_qt4.py in the constructor of FigureCanvasQT you'll find

   QtCore.QObject.connect(self, QtCore.SIGNAL('destroyed()'), self.close_event)

which should perform the steps below when close_event is called

   event = CloseEvent(s, self, guiEvent=guiEvent)
   self.callbacks.process(s, event)

If I insert print statements, the signal is ignored with matplotlib 1.1.0, but called with 1.2.0 (which uses a lambda function in the above connection).But inspecting pythons objects after the close() method is called on the widget, it seems that - at least - the paths associated with plot actually still exist.

So I'm just a bit worried if there already is existing functionality in the FigureCanvasQTAgg object that can do these things for me. And if so, how to use them?

Best regards,

Mads

···

On 01/30/2013 05:03 PM, Benjamin Root wrote:

On Tue, Jan 29, 2013 at 5:12 PM, Mads Ipsen <mads.ipsen@…287… > <mailto:mads.ipsen@…287…>> wrote:

    Hi,

    I spend some time writing up the question below on Stackoverflow
    which immediately was closed as a duplicate of other posts. To my
    best knowledge, these posts did not answer my questions - so I'll
    try my luck here instead:

    I am using the qt backengine for setting up a QWidget that embeds
    a matplotlib scene. When the widget is closed it appears that many
    of the matplotlib objects that were part of the plot still are
    alive in Python space.

    My question is basically the following: What actions should I take
    to clean up the figure and axes objects etc. that were part of the
    plot widget? The qt backend comes with a figure manager, but it
    appears a little unclear how it should be used.

    I have attached a small unit test example that sets up a plot.
    When the plot appears, just close it, and the test will garbage
    collects the plot, and then display info of the matplotlib objects
    that are still alive in Python space. Clearly both the path of the
    plot, and several Bbox objects are still referenced.

    Our current unit test suite contains almost 10000 GUI tests and
    its imperative that proper object space clean up is done after
    each test. Any help is much appreciated.

    Best regards,

    Mads

Would "fig.clf()" do what you need?

Ben Root

--
+-----------------------------------------------------+

Mads Ipsen |

+----------------------+------------------------------+

G�seb�ksvej 7, 4. tv | |
DK-2500 Valby | phone: +45-29716388 |
Denmark | email: mads.ipsen@...287... |

+----------------------+------------------------------+

Actually, now I am starting to recall a bug fix that came shortly after the 1.2.0 release related to properly setting up the destruction signal of the QT figure object. Could you test your code-base with the maintenance branch (1.2.x)? or master?

Cheers!
Ben Root

···

On Wed, Jan 30, 2013 at 1:46 PM, Mads Ipsen <mads.ipsen@…287…> wrote:

  On 01/30/2013 05:03 PM, Benjamin Root > wrote:
    On Tue, Jan 29, 2013 at 5:12 PM, Mads > > Ipsen <mads.ipsen@...287...> > >         wrote:

Hi,

          I spend some time writing up the question below on

Stackoverflow which immediately was closed as a duplicate
of other posts. To my best knowledge, these posts did not
answer my questions - so I’ll try my luck here instead:

          I am using the qt backengine for setting up a QWidget that

embeds a matplotlib scene. When the widget is closed it
appears that many of the matplotlib objects that were part
of the plot still are alive in Python space.

          My question is basically the following: What actions

should I take to clean up the figure and axes objects etc.
that were part of the plot widget? The qt backend comes
with a figure manager, but it appears a little unclear how
it should be used.

          I have attached a small unit test example that sets up a

plot. When the plot appears, just close it, and the test
will garbage collects the plot, and then display info of
the matplotlib objects that are still alive in Python
space. Clearly both the path of the plot, and several Bbox
objects are still referenced.

          Our current unit test suite contains almost 10000 GUI

tests and its imperative that proper object space clean up
is done after each test. Any help is much appreciated.

          Best regards,



          Mads
      Would "fig.clf()" do what you need?



      Ben Root

Thanks for the feedback.

  The trick is to get this done automatically when the widget is

closed. If you look in backend_qt4.py in the constructor of
FigureCanvasQT you’ll find

    QtCore.QObject.connect(self, QtCore.SIGNAL('destroyed()'),

self.close_event)

  which should perform the steps below when close_event is called



    event = CloseEvent(s, self, guiEvent=guiEvent)

    self.callbacks.process(s, event)



  If I insert print statements, the signal is ignored with

matplotlib 1.1.0, but called with 1.2.0 (which uses a lambda
function in the above connection).
But inspecting pythons objects after the close() method is called
on the widget, it seems that - at least - the paths associated
with plot actually still exist.

  So I'm just a bit worried if there already is existing

functionality in the FigureCanvasQTAgg object that can do these
things for me. And if so, how to use them?

  Best regards,



  Mads

Hi,

I attach log files from running my setup 'plot.py' with 1.1.0, 1.2.0, and master. To my judgement - if an automated memory clean-up is handled by the FigureCanvasQTAgg class - I must be abusing the usage of the class, since all logs still show the presence of paths, labels, bbox's, etc.

Also notice that log-1.2.0 show the presence of a path with hundreds of data points, which are not present in the other logs.

Best regards,

Mads

log-1.1.0.gz (7.94 KB)

log-1.2.0.gz (13.2 KB)

log-master.gz (9 KB)

plot.py (2.43 KB)

···

On 01/30/2013 08:02 PM, Benjamin Root wrote:

On Wed, Jan 30, 2013 at 1:46 PM, Mads Ipsen <mads.ipsen@…287… > <mailto:mads.ipsen@…287…>> wrote:

    On 01/30/2013 05:03 PM, Benjamin Root wrote:

    On Tue, Jan 29, 2013 at 5:12 PM, Mads Ipsen <mads.ipsen@…287… >> <mailto:mads.ipsen@…287…>> wrote:

        Hi,

        I spend some time writing up the question below on
        Stackoverflow which immediately was closed as a duplicate of
        other posts. To my best knowledge, these posts did not answer
        my questions - so I'll try my luck here instead:

        I am using the qt backengine for setting up a QWidget that
        embeds a matplotlib scene. When the widget is closed it
        appears that many of the matplotlib objects that were part of
        the plot still are alive in Python space.

        My question is basically the following: What actions should I
        take to clean up the figure and axes objects etc. that were
        part of the plot widget? The qt backend comes with a figure
        manager, but it appears a little unclear how it should be used.

        I have attached a small unit test example that sets up a
        plot. When the plot appears, just close it, and the test will
        garbage collects the plot, and then display info of the
        matplotlib objects that are still alive in Python space.
        Clearly both the path of the plot, and several Bbox objects
        are still referenced.

        Our current unit test suite contains almost 10000 GUI tests
        and its imperative that proper object space clean up is done
        after each test. Any help is much appreciated.

        Best regards,

        Mads

    Would "fig.clf()" do what you need?

    Ben Root

    Thanks for the feedback.

    The trick is to get this done automatically when the widget is
    closed. If you look in backend_qt4.py in the constructor of
    FigureCanvasQT you'll find

      QtCore.QObject.connect(self, QtCore.SIGNAL('destroyed()'),
    self.close_event)

    which should perform the steps below when close_event is called

      event = CloseEvent(s, self, guiEvent=guiEvent)
      self.callbacks.process(s, event)

    If I insert print statements, the signal is ignored with
    matplotlib 1.1.0, but called with 1.2.0 (which uses a lambda
    function in the above connection).But inspecting pythons objects
    after the close() method is called on the widget, it seems that -
    at least - the paths associated with plot actually still exist.

    So I'm just a bit worried if there already is existing
    functionality in the FigureCanvasQTAgg object that can do these
    things for me. And if so, how to use them?

    Best regards,

    Mads

Actually, now I am starting to recall a bug fix that came shortly after the 1.2.0 release related to properly setting up the destruction signal of the QT figure object. Could you test your code-base with the maintenance branch (1.2.x)? or master?

Cheers!
Ben Root

--
+-----------------------------------------------------+

Mads Ipsen |

+----------------------+------------------------------+

G�seb�ksvej 7, 4. tv | |
DK-2500 Valby | phone: +45-29716388 |
Denmark | email: mads.ipsen@...287... |

+----------------------+------------------------------+