Interactive plot with ipyvidgets and matplotlib on binder produces static images
Question:
I’m trying to share a github repo on binder. Locally, my interactive plot using matplotlib and @interact works ok. On binder it works half way. Same code adds static images to the cell output in binder notebook when slider value changes.
Question: how to fix binder behavior and make an interactive plot?
git repository https://github.com/queezz/Complex_Numbers
My notebook looks like this:
%pylab inline
from ipywidgets import interact, widgets
x = np.linspace(0,np.pi,100)
@interact
def plot_interactive(a=widgets.FloatSlider(min=1, max=10, val=1)):
plot(x,np.sin(x*a))
gca().set_aspect('equal')
ylim(-1.1,1.1)
Answers:
Found a good working example:
https://github.com/Kapernikov/ipywidgets-tutorial
The gist of it is to use %matplotlib widget
and @widgets.interact
.
It seems that usage of %pylab inline
is discouraged now, see this git issue.
I copy a part of the code from the tutorial which produces the same result as wanted in the question.
%matplotlib widget
import ipywidgets as widgets
import matplotlib.pyplot as plt
import numpy as np
# set up plot
fig, ax = plt.subplots(figsize=(6, 4))
ax.set_ylim([-4, 4])
ax.grid(True)
# generate x values
x = np.linspace(0, 2 * np.pi, 300)
def my_sine(x, w, amp, phi):
"""
Return a sine for x with angular frequeny w and amplitude amp.
"""
return amp*np.sin(w * (x-phi))
@widgets.interact(w=(0, 10, 1), amp=(0, 4, .1), phi=(0, 2*np.pi+0.01, 0.01))
def update(w = 1.0, amp=1, phi=0):
"""Remove old lines from plot and plot new one"""
[l.remove() for l in ax.lines]
ax.plot(x, my_sine(x, w, amp, phi), color='C0')
I wasn’t able to get @queez’s answer that uses ‘interact’ to work today (later updated in early 2023 is below); however, the ipywidgets documentation presently includes a matplotlib example, which uses ‘interactive’, that I was able to take and adapt @qqueezz’s solution to get it working. This seems to be a much more streamlined route to make an interactive plot.
#%matplotlib inline # from the example in the documentation. but doesn't seem necessary in current JupyterLab 3.1.11 or the classic notebook available now https://github.com/fomightez/communication_voila
from ipywidgets import interactive
import matplotlib.pyplot as plt
import numpy as np
def my_sine(x, w, amp, phi):
"""
Return a sine for x with angular frequency w and amplitude amp.
"""
return amp*np.sin(w * (x-phi))
def f( w, amp, phi):
plt.figure(2)
x = np.linspace(0, 2 * np.pi, 300)
plt.plot(x, my_sine(x, w, amp, phi), color='C0')
#plt.ylim(-5, 5)
plt.grid(True) #optional grid
plt.show()
interactive_plot = interactive(f, w=(0, 10, 1), amp=(0, 4, .1), phi=(0, 2*np.pi+0.01, 0.01))
#output = interactive_plot.children[-1]
#output.layout.height = '450px'
interactive_plot
You can go to the repo here, launch a session by choosing the launch binder
badge to the right of ‘Start with the matplotlib & widget demo as a notebook’ under ‘Direct links to start out in notebook mode:’.
Or click here to launch directly into that notebook via MyBinder.
UPDATE:
Later (early 2023), I found queez’s code from Kapernikov: Ipywidgets with matplotlib did work with interact
in JupyterLab using ipympl
.
Not following yet what changed; however, wanted to note.
I’m trying to share a github repo on binder. Locally, my interactive plot using matplotlib and @interact works ok. On binder it works half way. Same code adds static images to the cell output in binder notebook when slider value changes.
Question: how to fix binder behavior and make an interactive plot?
git repository https://github.com/queezz/Complex_Numbers
My notebook looks like this:
%pylab inline
from ipywidgets import interact, widgets
x = np.linspace(0,np.pi,100)
@interact
def plot_interactive(a=widgets.FloatSlider(min=1, max=10, val=1)):
plot(x,np.sin(x*a))
gca().set_aspect('equal')
ylim(-1.1,1.1)
Found a good working example:
https://github.com/Kapernikov/ipywidgets-tutorial
The gist of it is to use %matplotlib widget
and @widgets.interact
.
It seems that usage of %pylab inline
is discouraged now, see this git issue.
I copy a part of the code from the tutorial which produces the same result as wanted in the question.
%matplotlib widget
import ipywidgets as widgets
import matplotlib.pyplot as plt
import numpy as np
# set up plot
fig, ax = plt.subplots(figsize=(6, 4))
ax.set_ylim([-4, 4])
ax.grid(True)
# generate x values
x = np.linspace(0, 2 * np.pi, 300)
def my_sine(x, w, amp, phi):
"""
Return a sine for x with angular frequeny w and amplitude amp.
"""
return amp*np.sin(w * (x-phi))
@widgets.interact(w=(0, 10, 1), amp=(0, 4, .1), phi=(0, 2*np.pi+0.01, 0.01))
def update(w = 1.0, amp=1, phi=0):
"""Remove old lines from plot and plot new one"""
[l.remove() for l in ax.lines]
ax.plot(x, my_sine(x, w, amp, phi), color='C0')
I wasn’t able to get @queez’s answer that uses ‘interact’ to work today (later updated in early 2023 is below); however, the ipywidgets documentation presently includes a matplotlib example, which uses ‘interactive’, that I was able to take and adapt @qqueezz’s solution to get it working. This seems to be a much more streamlined route to make an interactive plot.
#%matplotlib inline # from the example in the documentation. but doesn't seem necessary in current JupyterLab 3.1.11 or the classic notebook available now https://github.com/fomightez/communication_voila
from ipywidgets import interactive
import matplotlib.pyplot as plt
import numpy as np
def my_sine(x, w, amp, phi):
"""
Return a sine for x with angular frequency w and amplitude amp.
"""
return amp*np.sin(w * (x-phi))
def f( w, amp, phi):
plt.figure(2)
x = np.linspace(0, 2 * np.pi, 300)
plt.plot(x, my_sine(x, w, amp, phi), color='C0')
#plt.ylim(-5, 5)
plt.grid(True) #optional grid
plt.show()
interactive_plot = interactive(f, w=(0, 10, 1), amp=(0, 4, .1), phi=(0, 2*np.pi+0.01, 0.01))
#output = interactive_plot.children[-1]
#output.layout.height = '450px'
interactive_plot
You can go to the repo here, launch a session by choosing the launch binder
badge to the right of ‘Start with the matplotlib & widget demo as a notebook’ under ‘Direct links to start out in notebook mode:’.
Or click here to launch directly into that notebook via MyBinder.
UPDATE:
Later (early 2023), I found queez’s code from Kapernikov: Ipywidgets with matplotlib did work with interact
in JupyterLab using ipympl
.
Not following yet what changed; however, wanted to note.