Last active
March 11, 2023 10:42
-
-
Save scottire/a8e5b74efca37945c0f1b0670761d568 to your computer and use it in GitHub Desktop.
Interactive and clickable plots using Panel, Holoviz and Bokeh in Jupyter Notebooks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
import panel as pn | |
import holoviews as hv | |
hv.extension("bokeh") | |
# hv.extension('matplotlib') | |
from holoviews.streams import Stream, Params | |
from scipy.io import wavfile | |
from scipy.signal import spectrogram | |
rate, data = wavfile.read('/filepath.wav') | |
width = 1000 | |
audio = pn.pane.Audio(data, sample_rate=rate, name='Audio', throttle=500) | |
time = np.linspace(0, len(data) / rate, num=len(data)) | |
line_plot = hv.Curve((time, data), ["time (s)","amplitude"]).opts(width=width) | |
f, t, sxx = spectrogram(data, rate) | |
spec_gram = hv.Image((t, f, np.log10(sxx)), ["time (s)","frequency (hz)"]).opts(width=width) | |
def interactive_play(x,y,t): | |
if x is None: | |
return hv.VLine(t).opts(color='green') | |
else: | |
audio.time = x | |
return hv.VLine(x).opts(color='green') | |
stream = Params(parameters=[audio.param.time], rename={'time': 't'}) | |
tap = hv.streams.SingleTap(transient=True) | |
dmap_time = hv.DynamicMap(interactive_play, streams=[stream, tap]) | |
pn.Column( audio, (spec_gram * dmap_time), (line_plot * dmap_time)) |
Thanks @philippjfr, I've tried your suggestions and the #2 decorator strangely stops the tap event from working.
I removed audio.param.time
to simplify things
This works:
tap = hv.streams.SingleTap(x=0, y=0, transient=True)
def interactive_play(x,y):
return hv.VLine(x).opts(color='green')
dmap_time = hv.DynamicMap(interactive_play, streams=[tap])
This doesn't:
tap = hv.streams.SingleTap(x=0, y=0, transient=True)
@pn.depends(x=tap.param.x, y=tap.param.y)
def interactive_play(x,y):
return hv.VLine(x).opts(color='green')
dmap_time = hv.DynamicMap(interactive_play)
I'm sure there's something obvious I'm missing. Should that above code work or is there something I'm doing wrong?
Hmm, odd, which version of HoloViews do you have?
which version of HoloViews do you have
import holoviews as hv
hv.__version__
>>> '1.13.2'
There is a related issue, pane Audio is broken for np.array
waveform input. Downgrading to panel==0.10.3
solved the issue where audio doesn't seem to play for me.
I tried this but the vertical line is not sliding as the audio is being played. Any ideas what could be the reason?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Minor suggestions for simplification:
You only need either pn.extension or hv.extension, i.e.
hv.extension("bokeh")
should be sufficient.You can now use
pn.depends
orparam.depends
to declareDynamicMap
callbacks: