matplotlib.backends.backend_gtk3cairo memory leak

Hi, I seem to have a memory leak while generating a ‘live’ plot display. This wasn’t the case for GTK2, but the example below is consuming ~800k/second (Matplotlib 1.4.3, PyGI aio-3.14.0_rev18, Windows 7 x64, python 3.4.3). I have checked the garbage collector but it doesn’t show anything interesting (no massive incrementing count of uncollected items). Anyway, I would be very grateful if somebody could confirm and/or fix this (or tell me what I’m doing wrong).
Many thanks
David
Code below:


from gi.repository import Gtk, Gdk, GLib
from matplotlib.figure import Figure
# Tell matplotlib to use a GTK canvas for drawing
#from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas
from matplotlib.backends.backend_gtk3cairo import FigureCanvasGTK3Cairo as FigureCanvas
# Application Class
class pyMatPlotLibTest(object):
def update_gui(self):
y = [self.index] * 1024
self.index += 1
if self.index > 1024: self.index = 0
Gdk.threads_enter()
self.line.set_ydata(y)
self.axes.set_title("%d" % self.index)
self.canvas.draw()
Gdk.threads_leave()
return True
def __init__(self):
self.index = 0
self.x = range(1024)
# Initialise the threads system and allow threads to work with GTK
GLib.threads_init()
# Draw scope
self.figure = Figure(dpi=100)
self.canvas = FigureCanvas(self.figure) # a Gtk.DrawingArea
#self.widget.alignment_ScopeDisplay.add(self.canvas)
# Draw initial scope
self.axes = self.figure.add_subplot(111)
self.line, = self.axes.plot(self.x, [0]* 1024)
self.axes.set_title("None")
self.axes.set_xbound(0.0, 1024)
self.axes.set_ybound(-16, 1040)
self.window_main = Gtk.Window(title="pyMatPlotLibTest")
self.window_main.connect("destroy", lambda x: Gtk.main_quit())
self.window_main.add(self.canvas)
self.window_main.show_all()
# Ticker for the update of the input state monitoring
Gdk.threads_add_timeout(priority = GLib.PRIORITY_DEFAULT_IDLE,
interval = 10, # msec
function = self.update_gui)
Gtk.main()
if __name__ == "__main__":
gui = pyMatPlotLibTest()
···

View this message in context: matplotlib.backends.backend_gtk3cairo memory leak

Sent from the matplotlib - users mailing list archive at Nabble.com.

I take it that it doesn’t happen using the GTK3Agg backend? What about the threading portion? Does it happen if you take the threading out?

Ben Root

···

On Tue, May 26, 2015 at 8:23 AM, David <dhughes@…4672…> wrote:

Hi, I seem to have a memory leak while generating a ‘live’ plot display. This wasn’t the case for GTK2, but the example below is consuming ~800k/second (Matplotlib 1.4.3, PyGI aio-3.14.0_rev18, Windows 7 x64, python 3.4.3). I have checked the garbage collector but it doesn’t show anything interesting (no massive incrementing count of uncollected items). Anyway, I would be very grateful if somebody could confirm and/or fix this (or tell me what I’m doing wrong).
Many thanks
David
Code below:



from gi.repository import Gtk, Gdk, GLib
from matplotlib.figure import Figure
# Tell matplotlib to use a GTK canvas for drawing
#from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas
from matplotlib.backends.backend_gtk3cairo import FigureCanvasGTK3Cairo as FigureCanvas
# Application Class
class pyMatPlotLibTest(object):
def update_gui(self):
y = [self.index] * 1024
self.index += 1
if self.index > 1024: self.index = 0
Gdk.threads_enter()
self.line.set_ydata(y)
self.axes.set_title("%d" % self.index)
self.canvas.draw()
Gdk.threads_leave()
return True
def __init__(self):
self.index = 0
self.x = range(1024)
# Initialise the threads system and allow threads to work with GTK
GLib.threads_init()
# Draw scope
self.figure = Figure(dpi=100)
self.canvas = FigureCanvas(self.figure) # a Gtk.DrawingArea
#self.widget.alignment_ScopeDisplay.add(self.canvas)
# Draw initial scope
self.axes = self.figure.add_subplot(111)
self.line, = self.axes.plot(self.x, [0]* 1024)
self.axes.set_title("None")
self.axes.set_xbound(0.0, 1024)
self.axes.set_ybound(-16, 1040)
self.window_main = Gtk.Window(title="pyMatPlotLibTest")
self.window_main.connect("destroy", lambda x: Gtk.main_quit())
self.window_main.add(self.canvas)
self.window_main.show_all()
# Ticker for the update of the input state monitoring
Gdk.threads_add_timeout(priority = GLib.PRIORITY_DEFAULT_IDLE,
interval = 10, # msec
function = self.update_gui)
Gtk.main()
if __name__ == "__main__":
gui = pyMatPlotLibTest()

View this message in context: matplotlib.backends.backend_gtk3cairo memory leak

Sent from the matplotlib - users mailing list archive at Nabble.com.


One dashboard for servers and applications across Physical-Virtual-Cloud

Widest out-of-the-box monitoring support with 50+ applications

Performance metrics, stats and reports that give you Actionable Insights

Deep dive visibility with transaction tracing using APM Insight.

http://ad.doubleclick.net/ddm/clk/290420510;117567292;y


Matplotlib-users mailing list

Matplotlib-users@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Thanks, however GTK3Agg is unimplemented in at the GTK3-end:

File “c:\Python34\lib\site-packages\matplotlib\backends\backend_gtk3agg.py”, line 69, in on_draw_event

buf, cairo.FORMAT_ARGB32, width, height)

NotImplementedError: Surface.create_for_data: Not Implemented yet.

Regards

David

On Behalf Of Benjamin Root

···

I take it that it doesn’t happen using the GTK3Agg backend? What about the threading portion? Does it happen if you take the threading out?

Ben Root

On Tue, May 26, 2015 at 8:23 AM, David <dhughes@…4672…> wrote:

Hi, I seem to have a memory leak while generating a ‘live’ plot display. This wasn’t the case for GTK2, but the example below is consuming ~800k/second (Matplotlib 1.4.3, PyGI aio-3.14.0_rev18, Windows 7 x64, python 3.4.3). I have checked
the garbage collector but it doesn’t show anything interesting (no massive incrementing count of uncollected items). Anyway, I would be very grateful if somebody could confirm and/or fix this (or tell me what I’m doing wrong). Many thanks David Code below:

from gi.repository import Gtk, Gdk, GLib


from matplotlib.figure import Figure

# Tell matplotlib to use a GTK canvas for drawing

#from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas

from matplotlib.backends.backend_gtk3cairo import FigureCanvasGTK3Cairo as FigureCanvas


Application Class

class pyMatPlotLibTest(object):

def update_gui(self):

y = [self.index] * 1024


self.index += 1

if self.index > 1024: self.index = 0

Gdk.threads_enter()

self.line.set_ydata(y)

self.axes.set_title("%d" % self.index)

self.canvas.draw()

Gdk.threads_leave()

return True

def __init__(self):

self.index = 0

self.x     = range(1024)

# Initialise the threads system and allow threads to work with GTK

GLib.threads_init()


Draw scope

self.figure = Figure(dpi=100)

self.canvas = FigureCanvas(self.figure) # a Gtk.DrawingArea

#self.widget.alignment_ScopeDisplay.add(self.canvas)

# Draw initial scope

self.axes = self.figure.add_subplot(111)

self.line, = self.axes.plot(self.x, [0]* 1024)

self.axes.set_title(“None”)

self.axes.set_xbound(0.0, 1024)

self.axes.set_ybound(-16, 1040)


self.window_main = Gtk.Window(title=“pyMatPlotLibTest”)

self.window_main.connect("destroy", lambda x: Gtk.main_quit())

self.window_main.add(self.canvas)

self.window_main.show_all()

# Ticker for the update of the input state monitoring

Gdk.threads_add_timeout(priority = GLib.PRIORITY_DEFAULT_IDLE,

interval = 10, # msec

function = self.update_gui)

Gtk.main()


if name == “main”:

gui = pyMatPlotLibTest()

---

View this message in context: [
matplotlib.backends.backend_gtk3cairo memory leak](http://matplotlib.1069221.n5.nabble.com/matplotlib-backends-backend-gtk3cairo-memory-leak-tp45614.html)
Sent from the [
matplotlib - users mailing list archive](http://matplotlib.1069221.n5.nabble.com/matplotlib-users-f3.html) at Nabble.com.

------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
[http://ad.doubleclick.net/ddm/clk/290420510;117567292;y](http://ad.doubleclick.net/ddm/clk/290420510;117567292;y)
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
[https://lists.sourceforge.net/lists/listinfo/matplotlib-users](https://lists.sourceforge.net/lists/listinfo/matplotlib-users)

</details>

I removed all calls to threads and swapped Gdk.threads_add_timeout to Glib.timeout_add (See attached. However if I comment the call to self.canvas.draw(), the
python memory utilisation sits at 30.8Mb.

from gi.repository import Gtk, Gdk, GLib

from matplotlib.figure import Figure

Tell matplotlib to use a GTK canvas for drawing

#from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas

from matplotlib.backends.backend_gtk3cairo import FigureCanvasGTK3Cairo as FigureCanvas

Application Class

class pyMatPlotLibTest(object):

def update_gui(self):

y = [self.index] * 1024

self.index += 1

if self.index > 1024: self.index = 0

#Gdk.threads_enter()

self.line.set_ydata(y)

self.axes.set_title("%d" % self.index)

self.canvas.draw()

#Gdk.threads_leave()

return True

def init(self):

self.index = 0

self.x = range(1024)

Initialise the threads system and allow threads to work with GTK

#GLib.threads_init()

Draw scope

self.figure = Figure(dpi=100)

self.canvas = FigureCanvas(self.figure) # a Gtk.DrawingArea

#self.widget.alignment_ScopeDisplay.add(self.canvas)

Draw initial scope

self.axes = self.figure.add_subplot(111)

self.line, = self.axes.plot(self.x, [0]* 1024)

self.axes.set_title(“None”)

self.axes.set_xbound(0.0, 1024)

self.axes.set_ybound(-16, 1040)

self.window_main = Gtk.Window(title=“pyMatPlotLibTest”)

self.window_main.connect(“destroy”, lambda x: Gtk.main_quit())

self.window_main.add(self.canvas)

self.window_main.show_all()

Ticker for the update of the input state monitoring

GLib.timeout_add(10, self.update_gui)

#Gdk.threads_add_timeout(priority = GLib.PRIORITY_DEFAULT_IDLE,

interval = 10, # msec

function = self.update_gui)

Gtk.main()

if name == “main”:

gui = pyMatPlotLibTest()

On Behalf Of Benjamin Root

···

I take it that it doesn’t happen using the GTK3Agg backend? What about the threading portion? Does it happen if you take the threading out?

Ben Root

On Tue, May 26, 2015 at 8:23 AM, David <dhughes@…4672…> wrote:

Hi, I seem to have a memory leak while generating a ‘live’ plot display. This wasn’t the case for GTK2, but the example below is consuming ~800k/second (Matplotlib 1.4.3, PyGI aio-3.14.0_rev18, Windows 7 x64, python 3.4.3). I have checked
the garbage collector but it doesn’t show anything interesting (no massive incrementing count of uncollected items). Anyway, I would be very grateful if somebody could confirm and/or fix this (or tell me what I’m doing wrong). Many thanks David Code below:

from gi.repository import Gtk, Gdk, GLib


from matplotlib.figure import Figure

# Tell matplotlib to use a GTK canvas for drawing

#from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas

from matplotlib.backends.backend_gtk3cairo import FigureCanvasGTK3Cairo as FigureCanvas


Application Class

class pyMatPlotLibTest(object):

def update_gui(self):

y = [self.index] * 1024


self.index += 1

if self.index > 1024: self.index = 0

Gdk.threads_enter()

self.line.set_ydata(y)

self.axes.set_title("%d" % self.index)

self.canvas.draw()

Gdk.threads_leave()

return True

def __init__(self):

self.index = 0

self.x     = range(1024)

# Initialise the threads system and allow threads to work with GTK

GLib.threads_init()


Draw scope

self.figure = Figure(dpi=100)

self.canvas = FigureCanvas(self.figure) # a Gtk.DrawingArea

#self.widget.alignment_ScopeDisplay.add(self.canvas)

# Draw initial scope

self.axes = self.figure.add_subplot(111)

self.line, = self.axes.plot(self.x, [0]* 1024)

self.axes.set_title(“None”)

self.axes.set_xbound(0.0, 1024)

self.axes.set_ybound(-16, 1040)


self.window_main = Gtk.Window(title=“pyMatPlotLibTest”)

self.window_main.connect("destroy", lambda x: Gtk.main_quit())

self.window_main.add(self.canvas)

self.window_main.show_all()

# Ticker for the update of the input state monitoring

Gdk.threads_add_timeout(priority = GLib.PRIORITY_DEFAULT_IDLE,

interval = 10, # msec

function = self.update_gui)

Gtk.main()


if name == “main”:

gui = pyMatPlotLibTest()

---

View this message in context: [
matplotlib.backends.backend_gtk3cairo memory leak](http://matplotlib.1069221.n5.nabble.com/matplotlib-backends-backend-gtk3cairo-memory-leak-tp45614.html)
Sent from the [
matplotlib - users mailing list archive](http://matplotlib.1069221.n5.nabble.com/matplotlib-users-f3.html) at Nabble.com.

------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
[http://ad.doubleclick.net/ddm/clk/290420510;117567292;y](http://ad.doubleclick.net/ddm/clk/290420510;117567292;y)
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
[https://lists.sourceforge.net/lists/listinfo/matplotlib-users](https://lists.sourceforge.net/lists/listinfo/matplotlib-users)

</details>

I take it that it doesn't happen using the GTK3Agg backend?

GTK3Agg is unimplemented at the GTK3-end:

  File
"c:\Python34\lib\site-packages\matplotlib\backends\backend_gtk3agg.py", line
69, in on_draw_event
    buf, cairo.FORMAT_ARGB32, width, height)
NotImplementedError: Surface.create_for_data: Not Implemented yet.

What about the threading portion? Does it happen if you take the threading
out?

I removed all calls to threads and swapped Gdk.threads_add_timeout to
Glib.timeout_add. This made little difference.

However if I comment the call to self.canvas.draw(), the python memory
utilisation sits at 30.8Mb (but the graph does not update of course).

Thanks

David

···

--
View this message in context: http://matplotlib.1069221.n5.nabble.com/matplotlib-backends-backend-gtk3cairo-memory-leak-tp45614p45616.html
Sent from the matplotlib - users mailing list archive at Nabble.com.

IGtk3Agg should work in you use cairocffi instead of py(2/3)cairo. AFAIK py(2/3)cairo is more or less unmaintained these days and that function has never been implemented in a released version.

Best

Jens

tir. 26. maj 2015 kl. 16.27 skrev David <dhughes@…4672…>:

···

I take it that it doesn’t happen using the GTK3Agg backend?

GTK3Agg is unimplemented at the GTK3-end:

File

“c:\Python34\lib\site-packages\matplotlib\backends\backend_gtk3agg.py”, line

69, in on_draw_event

buf, cairo.FORMAT_ARGB32, width, height)

NotImplementedError: Surface.create_for_data: Not Implemented yet.

What about the threading portion? Does it happen if you take the threading

out?

I removed all calls to threads and swapped Gdk.threads_add_timeout to

Glib.timeout_add. This made little difference.

However if I comment the call to self.canvas.draw(), the python memory

utilisation sits at 30.8Mb (but the graph does not update of course).

Thanks

David

View this message in context: http://matplotlib.1069221.n5.nabble.com/matplotlib-backends-backend-gtk3cairo-memory-leak-tp45614p45616.html

Sent from the matplotlib - users mailing list archive at Nabble.com.


One dashboard for servers and applications across Physical-Virtual-Cloud

Widest out-of-the-box monitoring support with 50+ applications

Performance metrics, stats and reports that give you Actionable Insights

Deep dive visibility with transaction tracing using APM Insight.

http://ad.doubleclick.net/ddm/clk/290420510;117567292;y


Matplotlib-users mailing list

Matplotlib-users@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-users

IGtk3Agg should work in you use cairocffi instead of py(2/3)cairo. AFAIK

py(2/3)cairo is more or less

unmaintained these days and that function has never been implemented in a
released version.

Yes you're right. This does work. However you need to do the following
steps:

Run: pip install cairocffi
Copy: C:\Python34\Lib\site-packages\gnome\libcairo-gobject-2.dll to
C:\Python34
Rename: libcairo-gobject-2.dll to libcairo-2.dll

Then in the python code, change the back-ends line to:
from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as
FigureCanvas

Incidentally, if you're trying the script, modify the line from the first
script example I sent -- the second has a horrible threads issue (due to the
missing call to threads_init).

Regards

David

···

--
View this message in context: http://matplotlib.1069221.n5.nabble.com/matplotlib-backends-backend-gtk3cairo-memory-leak-tp45614p45628.html
Sent from the matplotlib - users mailing list archive at Nabble.com.

To clarify, this fixes the memory leak issue.

···

--
View this message in context: http://matplotlib.1069221.n5.nabble.com/matplotlib-backends-backend-gtk3cairo-memory-leak-tp45614p45629.html
Sent from the matplotlib - users mailing list archive at Nabble.com.