Smooth interaction with graphics

315 views
Skip to first unread message

mcmc...@unca.edu

unread,
Jan 14, 2017, 9:38:29 AM1/14/17
to Project Jupyter
It's quite easy to generate generate the graph of a function that depends upon a parameter and illustrate how that graph changes when we change the parameter using interact. A simple example to interact with the frequency of a sine function might be written as follows:

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from ipywidgets import interact, FloatSlider

def myplot(a):
    xs
= np.linspace(-3,3,100)
    ys
= np.sin(a*xs)
    plt
.plot(xs,ys)
demo
= interact(myplot, a=FloatSlider(value=1, min=-3, max=3, step=0.01))

When I do so, though, the axes flicker as I move the slider. I can improve the situation a bit by setting the axes ticks and limits but I can't seem to get it to go away entirely. I would guess that a better solution would be to create one axes instance and fiddle with the lines directly, but I haven't got that to work either.

What is the best practice for interacting with these types of graphics smoothly?

Sylvain Corlay

unread,
Jan 14, 2017, 9:55:31 AM1/14/17
to jup...@googlegroups.com
The problem is that the rendering logic for matplotlib resides in the backend. I would recommand using the "notebook" backend for matplotlib which should improve the situation.

Or you can use a plotting library for the notebook such as bqplot.

Sylvain

--
You received this message because you are subscribed to the Google Groups "Project Jupyter" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jupyter+unsubscribe@googlegroups.com.
To post to this group, send email to jup...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jupyter/c512ae9a-e66a-4f81-b6ef-f79fd6bf5d6e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

mcmc...@unca.edu

unread,
Jan 14, 2017, 12:17:05 PM1/14/17
to Project Jupyter
On Saturday, January 14, 2017 at 9:55:31 AM UTC-5, Sylvain Corlay wrote:

The problem is that the rendering logic for matplotlib resides in the backend. I would recommand using the "notebook" backend for matplotlib which should improve the situation.

Or you can use a plotting library for the notebook such as bqplot.

Thanks! the notebook backend seemed much worse. bqplot seems very new and, I'm guessing that it will be the way to work with 2D graphics in the notebook. For the record, I was able to piece together the following after a little fiddling:

import numpy as np
from bqplot import pyplot as plt
from ipywidgets import interact, FloatSlider


fig
= plt.figure(1)

def myplot(a):
    xs
= np.linspace(-3,3,100)
    ys
= np.sin(a*xs)

   
if fig.marks == []:
        plt
.plot(xs,ys)
   
else:
        fig
.marks[0].y = ys
demo
= interact(myplot, a=FloatSlider(value=1, min=-3, max=3, step=0.01))
plt
.ylim(-1.1,1.1)
plt
.show()

This seems to work quite well.

Thanks again!


Brian Granger

unread,
Jan 14, 2017, 1:08:51 PM1/14/17
to Project Jupyter
The main thing I have found with using matplotlib with interact is
that you have to do a bit of extra work to make sure that the overall
frame/ticks/limits/etc are the same as you vary your parameter.
Because each call to plt.plot is new, matplotlib has no way of knowing
it should hold those things invariant.
> --
> You received this message because you are subscribed to the Google Groups
> "Project Jupyter" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to jupyter+u...@googlegroups.com.
> To post to this group, send email to jup...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/jupyter/1d4935fd-b035-4c7f-bbf7-8aa04ed20d4b%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
Brian E. Granger
Associate Professor of Physics and Data Science
Cal Poly State University, San Luis Obispo
@ellisonbg on Twitter and GitHub
bgra...@calpoly.edu and elli...@gmail.com

Sylvain Corlay

unread,
Jan 14, 2017, 2:25:48 PM1/14/17
to jup...@googlegroups.com
You can make this a little bit more efficient.

import numpy as np
import bqplot.pyplot as plt
from ipywidgets import interact, FloatSlider

fig = plt.figure()
xs = np.linspace(-3,3,100)
lines = plt.plot(xs, [])

def freq(a): 
    lines.y = np.sin(a * xs)

demo = interact(freq, a=FloatSlider(value=1, min=-3, max=3, step=0.01))
plt.ylim(-1.1,1.1)
plt.show()


also, passing 

animation_duration=300

to figure() enables smooth transitions between different positions of the lines.

Cheers,

--
You received this message because you are subscribed to the Google Groups "Project Jupyter" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jupyter+unsubscribe@googlegroups.com.
To post to this group, send email to jup...@googlegroups.com.

Fernando Perez

unread,
Jan 17, 2017, 8:11:33 PM1/17/17
to Project Jupyter
This is the matplotlib version with manual data assignment, which is probably the most efficient you can make something like this without making the code a lot uglier and harder to understand.  It's the MPL equivalent of what Sylvain did:

#### Start
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from ipywidgets import interact, FloatSlider
from IPython.display import display

# setup
xs = np.linspace(-3,3,100)
fig, ax = plt.subplots()
line, = ax.plot(xs, xs)
ax.set_xlim(-3, 3)
ax.set_ylim(-1.1, 1.1)
plt.close(fig) # we'll display it manually

# Plot function only updates the data
def myplot(a):
    line.set_ydata(np.sin(a*xs))
    # we now call the display manually with the new image
    display(fig)
    
interact(myplot, a=FloatSlider(value=1.5, min=-3, max=3, step=0.01));
#### End


Cheers,

f

mcmc...@unca.edu

unread,
Jan 18, 2017, 7:38:30 PM1/18/17
to Project Jupyter


On Tuesday, January 17, 2017 at 8:11:33 PM UTC-5, Fernando Perez wrote:

This is the matplotlib version with manual data assignment, which is probably the most efficient you can make something like this without making the code a lot uglier and harder to understand.  It's the MPL equivalent of what Sylvain did:

Yes, I tried almost exactly this earlier but it didn't seem to work very well. As it turns out, the issue seems to be browser independent. I'm working on a Mac that's three years old and everything I've tried with matplotlib (including Fernando's code) look fairly bad when I interact with them in Firefox. They look pretty much perfect, when I run them in Chrome, though.

Thanks to all of you!

Denis Akhiyarov

unread,
Jan 22, 2017, 10:36:11 PM1/22/17
to Project Jupyter
Is there any tutorial provided for matplotlib and ipywidgets used in notebook? I struggled a bit few weeks ago and noticed unanswered questions on this topic:

http://stackoverflow.com/q/40122837/2230844

Reply all
Reply to author
Forward
0 new messages