Testing ipywidgets and Music21¶
These are tests of widgets within Music21
import ipywidgets as widgets
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
@widgets.interact
def f(x=5):
print(x)
interactive(children=(IntSlider(value=5, description='x', max=15, min=-5), Output()), _dom_classes=('widget-in…
@widgets.interact(x=(0, 5))
def ff(x=5):
print(x)
interactive(children=(IntSlider(value=5, description='x', max=5), Output()), _dom_classes=('widget-interact',)…
@widgets.interact_manual(
color=['blue', 'red', 'green'], lw=(1.0, 10.0))
def plot(freq=1.0, color='blue', lw=2, grid=True):
t = np.linspace(-1.0, 1.0, 1000)
fig, ax = plt.subplots(1, 1, figsize=(8, 6))
ax.plot(t, np.sin(2 * np.pi * freq * t),
lw=lw, color=color)
ax.grid(grid)
interactive(children=(FloatSlider(value=1.0, description='freq', max=3.0, min=-1.0), Dropdown(description='col…
freq_slider = widgets.FloatSlider(
value=2.0,
min=1.0,
max=10.0,
step=0.1,
description='Frequency:',
readout_format='.1f',
)
freq_slider
FloatSlider(value=2.0, description='Frequency:', max=10.0, min=1.0, readout_format='.1f')
Create a Custom Widget¶
Older Jupyter provided require/define from RequireJS which gave access to Jupyter widgets. This is no longer the case, so we first need to install anywidget (since it’s not part of the music21 ecosystem):
%pip install anywidget
Collecting anywidget
Downloading anywidget-0.11.0-py3-none-any.whl.metadata (8.9 kB)
Requirement already satisfied: ipywidgets>=7.6.0 in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from anywidget) (8.1.8)
Collecting psygnal>=0.8.1 (from anywidget)
Downloading psygnal-0.15.1-cp313-cp313-macosx_11_0_arm64.whl.metadata (6.1 kB)
Requirement already satisfied: typing-extensions>=4.2.0 in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from anywidget) (4.14.0)
Requirement already satisfied: comm>=0.1.3 in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from ipywidgets>=7.6.0->anywidget) (0.2.3)
Requirement already satisfied: ipython>=6.1.0 in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from ipywidgets>=7.6.0->anywidget) (9.3.0)
Requirement already satisfied: traitlets>=4.3.1 in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from ipywidgets>=7.6.0->anywidget) (5.14.3)
Requirement already satisfied: widgetsnbextension~=4.0.14 in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from ipywidgets>=7.6.0->anywidget) (4.0.15)
Requirement already satisfied: jupyterlab_widgets~=3.0.15 in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from ipywidgets>=7.6.0->anywidget) (3.0.16)
Requirement already satisfied: decorator in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from ipython>=6.1.0->ipywidgets>=7.6.0->anywidget) (5.2.1)
Requirement already satisfied: ipython-pygments-lexers in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from ipython>=6.1.0->ipywidgets>=7.6.0->anywidget) (1.1.1)
Requirement already satisfied: jedi>=0.16 in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from ipython>=6.1.0->ipywidgets>=7.6.0->anywidget) (0.19.2)
Requirement already satisfied: matplotlib-inline in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from ipython>=6.1.0->ipywidgets>=7.6.0->anywidget) (0.1.7)
Requirement already satisfied: pexpect>4.3 in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from ipython>=6.1.0->ipywidgets>=7.6.0->anywidget) (4.9.0)
Requirement already satisfied: prompt_toolkit<3.1.0,>=3.0.41 in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from ipython>=6.1.0->ipywidgets>=7.6.0->anywidget) (3.0.51)
Requirement already satisfied: pygments>=2.4.0 in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from ipython>=6.1.0->ipywidgets>=7.6.0->anywidget) (2.19.1)
Requirement already satisfied: stack_data in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from ipython>=6.1.0->ipywidgets>=7.6.0->anywidget) (0.6.3)
Requirement already satisfied: wcwidth in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from prompt_toolkit<3.1.0,>=3.0.41->ipython>=6.1.0->ipywidgets>=7.6.0->anywidget) (0.2.13)
Requirement already satisfied: parso<0.9.0,>=0.8.4 in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from jedi>=0.16->ipython>=6.1.0->ipywidgets>=7.6.0->anywidget) (0.8.4)
Requirement already satisfied: ptyprocess>=0.5 in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from pexpect>4.3->ipython>=6.1.0->ipywidgets>=7.6.0->anywidget) (0.7.0)
Requirement already satisfied: executing>=1.2.0 in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from stack_data->ipython>=6.1.0->ipywidgets>=7.6.0->anywidget) (2.2.0)
Requirement already satisfied: asttokens>=2.1.0 in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from stack_data->ipython>=6.1.0->ipywidgets>=7.6.0->anywidget) (3.0.0)
Requirement already satisfied: pure-eval in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from stack_data->ipython>=6.1.0->ipywidgets>=7.6.0->anywidget) (0.2.3)
Downloading anywidget-0.11.0-py3-none-any.whl (317 kB)
Downloading psygnal-0.15.1-cp313-cp313-macosx_11_0_arm64.whl (574 kB)
[2K [38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m574.8/574.8 kB[0m [31m10.5 MB/s[0m [33m0:00:00[0m
[?25hInstalling collected packages: psygnal, anywidget
[2K [38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m2/2[0m [anywidget]
[1A[2KSuccessfully installed anywidget-0.11.0 psygnal-0.15.1
[1m[[0m[34;49mnotice[0m[1;39;49m][0m[39;49m A new release of pip is available: [0m[31;49m25.2[0m[39;49m -> [0m[32;49m26.1.1[0m
[1m[[0m[34;49mnotice[0m[1;39;49m][0m[39;49m To update, run: [0m[32;49mpip install --upgrade pip[0m
Note: you may need to restart the kernel to use updated packages.
Now create a button that synchronizes Counter value with JS value
import anywidget
import traitlets
class Counter(anywidget.AnyWidget):
_esm = r'''
export function render({ model, el }) {
const bm = document.createElement('button');
bm.textContent = '-';
const bp = document.createElement('button');
bp.textContent = '+';
const span = document.createElement('span');
span.style.marginLeft = '10px';
span.style.marginRight = '10px';
const set_span = () => {
span.textContent = String(model.get('value'));
};
bm.addEventListener('click', () => {
const x = model.get('value');
model.set('value', x - 1);
model.save_changes();
});
bp.addEventListener('click', () => {
const x = model.get('value');
model.set('value', x + 1);
model.save_changes();
});
model.on('change:value', set_span);
el.appendChild(bm);
el.appendChild(span);
el.appendChild(bp);
set_span();
}
'''
value = traitlets.Int(0).tag(sync=True)
c = Counter()
c
<__main__.Counter object at 0x10aa09940>
This number here will change (when reevaluated) with Counter’s value changing above
c.value
0
def a_w(min=0, max=100):
@widgets.interact(x=(min,max))
def f(x=50):
print(x)
a_w(20, 60)
interactive(children=(IntSlider(value=50, description='x', max=60, min=20), Output()), _dom_classes=('widget-i…
def a_w(min=0, max=100):
@widgets.interact(x=(min,max))
def f(x=(min+max)//2):
print(x)
a_w(10, 20)
interactive(children=(IntSlider(value=15, description='x', max=20, min=10), Output()), _dom_classes=('widget-i…