Making an interactive plot faster

Hi everyone,

The following shows an example of a simple data viewer which includes
a slider, a bitmap, and a scatter plot:

"""
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.widgets import Slider

fig = plt.figure()

ax1 = fig.add_axes([0.1, 0.1, 0.4, 0.7])
image = ax1.imshow(np.random.random((512, 512)), vmin=0., vmax=1.)

ax2 = fig.add_axes([0.1, 0.9, 0.85, 0.05])
ax2.set_xticklabels("")
ax2.set_yticklabels("")
slider = Slider(ax2, "", 0., 1.)

def update_vmax(value):
    image.set_clim(0., value)
    fig.canvas.draw()

slider.on_changed(update_vmax)

ax3 = fig.add_axes([0.55, 0.1, 0.4, 0.7])
x = np.random.random(10000)
y = np.random.random(10000)
ax3.scatter(x, y)

plt.show()
"""

When moving the slider, the vmax of the image changes, but I get very
slow frame rates (~2/sec) on my computer with the MacOS X backend. I
was wondering whether people here have any tips on speeding things up?

As far as I can figure out, this is slow because both the slider and
the callback function call ``fig.canvas.draw``. Slider calls it before
the callback function, so I definitely need to draw things in that
function, but I can get a factor of 2x speedup by doing

slider.drawon = False

which prevents ``canvas.draw()`` being called twice. However, this is
still much too slow, so I started to look into using ``draw_artist``
to only update elements that need updating, but this requires
partially re-implementing the Slider class.

As a side note, using ``draw_artist`` also does not work on the MacOS X backend:

https://github.com/matplotlib/matplotlib/issues/166

but I'm willing to have a solution that wouldn't work on this backend
if it was the only way.

Does anyone have a clean solution to increasing the frame rate of this example?

Thanks!
Tom

Have you tried using "draw_idle"? That will schedule the draw for the next time the event loop is idle.

Mike

···

On 06/24/2013 07:39 AM, Thomas Robitaille wrote:

Hi everyone,

The following shows an example of a simple data viewer which includes
a slider, a bitmap, and a scatter plot:

"""
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.widgets import Slider

fig = plt.figure()

ax1 = fig.add_axes([0.1, 0.1, 0.4, 0.7])
image = ax1.imshow(np.random.random((512, 512)), vmin=0., vmax=1.)

ax2 = fig.add_axes([0.1, 0.9, 0.85, 0.05])
ax2.set_xticklabels("")
ax2.set_yticklabels("")
slider = Slider(ax2, "", 0., 1.)

def update_vmax(value):
     image.set_clim(0., value)
     fig.canvas.draw()

slider.on_changed(update_vmax)

ax3 = fig.add_axes([0.55, 0.1, 0.4, 0.7])
x = np.random.random(10000)
y = np.random.random(10000)
ax3.scatter(x, y)

plt.show()
"""

When moving the slider, the vmax of the image changes, but I get very
slow frame rates (~2/sec) on my computer with the MacOS X backend. I
was wondering whether people here have any tips on speeding things up?

As far as I can figure out, this is slow because both the slider and
the callback function call ``fig.canvas.draw``. Slider calls it before
the callback function, so I definitely need to draw things in that
function, but I can get a factor of 2x speedup by doing

slider.drawon = False

which prevents ``canvas.draw()`` being called twice. However, this is
still much too slow, so I started to look into using ``draw_artist``
to only update elements that need updating, but this requires
partially re-implementing the Slider class.

As a side note, using ``draw_artist`` also does not work on the MacOS X backend:

RuntimeError: CGContextRef is NULL with draw_artist · Issue #166 · matplotlib/matplotlib · GitHub

but I'm willing to have a solution that wouldn't work on this backend
if it was the only way.

Does anyone have a clean solution to increasing the frame rate of this example?

Thanks!
Tom

------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

Hi Mike,

Thanks for the suggestion - however, this doesn't change the FPS. From
my experiments so far, it seems using draw_artist would be the best
bet, but any ideas why it doesn't work with the MacOS X backend?

Cheers,
Tom

···

On 24 June 2013 16:13, Michael Droettboom <mdroe@...86...> wrote:

Have you tried using "draw_idle"? That will schedule the draw for the
next time the event loop is idle.

Mike

On 06/24/2013 07:39 AM, Thomas Robitaille wrote:

Hi everyone,

The following shows an example of a simple data viewer which includes
a slider, a bitmap, and a scatter plot:

"""
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.widgets import Slider

fig = plt.figure()

ax1 = fig.add_axes([0.1, 0.1, 0.4, 0.7])
image = ax1.imshow(np.random.random((512, 512)), vmin=0., vmax=1.)

ax2 = fig.add_axes([0.1, 0.9, 0.85, 0.05])
ax2.set_xticklabels("")
ax2.set_yticklabels("")
slider = Slider(ax2, "", 0., 1.)

def update_vmax(value):
     image.set_clim(0., value)
     fig.canvas.draw()

slider.on_changed(update_vmax)

ax3 = fig.add_axes([0.55, 0.1, 0.4, 0.7])
x = np.random.random(10000)
y = np.random.random(10000)
ax3.scatter(x, y)

plt.show()
"""

When moving the slider, the vmax of the image changes, but I get very
slow frame rates (~2/sec) on my computer with the MacOS X backend. I
was wondering whether people here have any tips on speeding things up?

As far as I can figure out, this is slow because both the slider and
the callback function call ``fig.canvas.draw``. Slider calls it before
the callback function, so I definitely need to draw things in that
function, but I can get a factor of 2x speedup by doing

slider.drawon = False

which prevents ``canvas.draw()`` being called twice. However, this is
still much too slow, so I started to look into using ``draw_artist``
to only update elements that need updating, but this requires
partially re-implementing the Slider class.

As a side note, using ``draw_artist`` also does not work on the MacOS X backend:

RuntimeError: CGContextRef is NULL with draw_artist · Issue #166 · matplotlib/matplotlib · GitHub

but I'm willing to have a solution that wouldn't work on this backend
if it was the only way.

Does anyone have a clean solution to increasing the frame rate of this example?

Thanks!
Tom

------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

Hi Thomas,

As explained in this issue:
https://github.com/matplotlib/matplotlib/issues/166
draw_artist does not work because it is being called from outside the event loop (or, to be exact, because draw_artist will only work if it is called from inside the drawing callback function that is called by the event loop). On some backends, you may get away with calling draw_artist from outside the event loop. However, this suggests a problem in the code design (for comparison, see this issue

on the animation code).
As far as I know, the matplotlib documentation does not advertise the use of draw_artist, and there is no guarantee that it will work on all backends. If you can redesign
your code such that draw_artist is called from inside the event loop, it should work OK on all backends. (though my first bet would also be to look at draw_idle).

Best,
-Michiel.

···

From: Thomas Robitaille <thomas.robitaille@…287…>
To: Michael Droettboom <mdroe@…120…86…>
Cc: matplotlib-users@lists.sourceforge.net
Sent: Tuesday, June 25, 2013 9:45 PM
Subject: Re: [Matplotlib-users] Making an interactive plot
faster

Hi Mike,

Thanks for the suggestion - however, this doesn’t change the FPS. From
my experiments so far, it seems using draw_artist would be the best
bet, but any ideas why it doesn’t work with the MacOS X backend?

https://github.com/matplotlib/matplotlib/issues/166

Cheers,
Tom

On 24 June 2013 16:13, Michael Droettboom <mdroe@…120…86…> wrote:

Have you tried using “draw_idle”? That will schedule the draw for the
next time the event loop is idle.

Mike

On 06/24/2013 07:39 AM, Thomas Robitaille wrote:

Hi everyone,

The following shows an example of a simple data viewer which includes
a slider, a bitmap, and a scatter plot:

“”"

import numpy as np

from matplotlib import pyplot as plt
from matplotlib.widgets import Slider

fig = plt.figure()

ax1 = fig.add_axes([0.1, 0.1, 0.4, 0.7])
image = ax1.imshow(np.random.random((512, 512)), vmin=0., vmax=1.)

ax2 = fig.add_axes([0.1, 0.9, 0.85, 0.05])
ax2.set_xticklabels(“”)
ax2.set_yticklabels(“”)
slider = Slider(ax2, “”, 0., 1.)

def update_vmax(value):
image.set_clim(0., value)
fig.canvas.draw()

slider.on_changed(update_vmax)

ax3 = fig.add_axes([0.55, 0.1, 0.4, 0.7])
x = np.random.random(10000)
y = np.random.random(10000)
ax3.scatter(x, y)

plt.show()
“”"

When moving the
slider, the vmax of the image changes, but I get very
slow frame rates (~2/sec) on my computer with the MacOS X backend. I
was wondering whether people here have any tips on speeding things up?

As far as I can figure out, this is slow because both the slider and
the callback function call fig.canvas.draw. Slider calls it before
the callback function, so I definitely need to draw things in that
function, but I can get a factor of 2x speedup by doing

slider.drawon = False

which prevents canvas.draw() being called twice. However, this is
still much too slow, so I started to look into using draw_artist
to only update elements that need updating, but this requires
partially re-implementing the Slider class.

As a side note, using draw_artist also does not
work on the MacOS X backend:

https://github.com/matplotlib/matplotlib/issues/166

but I’m willing to have a solution that wouldn’t work on this backend
if it was the only way.

Does anyone have a clean solution to increasing the frame rate of this example?

Thanks!
Tom


This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev


Matplotlib-users mailing list
Matplotlib-users@…1220…sts.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users


This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev


Matplotlib-users mailing list
Matplotlib-users@…1867…s.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users


This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev


Matplotlib-users mailing list
Matplotlib-users@…564…net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users