I want a Panel app with dynamic plots, and different plots depending on which menu/button is selected from a sidepanel, so I started from this great answer to a previous q: Multi page app documentation - #2 by maximlt?
Each page had a sine & cosine plot which updated based on widget values, using @pn.depends
.
Then I updated the code so that the sine plot would be a scatter plot, and the widget would be a selection drop-down menu instead of a slider. But now that scatter plot is not updating when I update the selection drop-down widget. What am I doing wrong? Clearly I’m misunderstanding something about what @pn.depends()
is doing or not doing. Any help would be super appreciated!
Full code below:
import pandas as pd
import panel as pn
import holoviews as hv
import hvplot.pandas
import numpy as np
import time
from datetime import datetime
pn.extension()
template = pn.template.FastListTemplate(title='My Dashboard')
# load detailed data
durations = np.random.randint(0, 10, size=10)
activity_codes = ['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3', 'C3']
activity_categories = ['A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C', 'C']
df = pd.DataFrame({'Duration': durations,
'ActivityCode': activity_codes,
'ActivityCategory': activity_categories})
# Page 1 Widget Controls
ac_categories = ['A', 'B', 'C']
ac_cat_radio_button = pn.widgets.Select(name='Activity Category', options=ac_categories)
# Page 1 Plotting Code
@pn.depends(ac_cat=ac_cat_radio_button)
def scatter_detail_by_ac(df, ac_cat):
print(f"ac_cat is {ac_cat}")
print(f"ac_cat.value is {ac_cat.value}")
df_subset = df.loc[df.ActivityCategory==ac_cat.value]
print(f"number of records in df_subset to scatter plot: {len(df_subset):,}")
return df_subset.hvplot.scatter(x='ActivityCode', y='Duration')
freq2 = pn.widgets.FloatSlider(name="Frequency", start=0, end=10, value=2)
phase2 = pn.widgets.FloatSlider(name="Phase", start=0, end=np.pi)
xs = np.linspace(0,np.pi)
@pn.depends(freq=freq2, phase=phase2)
def cosine(freq, phase):
return hv.Curve((xs, np.cos(xs*freq+phase))).opts(
responsive=True, min_height=400)
page = pn.Column(sizing_mode='stretch_width')
content1 = [
pn.Row(ac_cat_radio_button), #grouping_vars_radio_button),
scatter_detail_by_ac(df, ac_cat_radio_button),
]
content2 = [
pn.Row(freq2, phase2),
hv.DynamicMap(cosine),
]
link1 = pn.widgets.Button(name='Scatter')
link2 = pn.widgets.Button(name='Cosine')
template.sidebar.append(link1)
template.sidebar.append(link2)
template.main.append(page)
def load_content1(event):
template.main[0].objects = content1
def load_content2(event):
template.main[0].objects = content2
link1.on_click(load_content1)
link2.on_click(load_content2)
template.show()
Also, here’s the versions I’m using, from my requirements.in
(which I pip-compile
into a requirements.txt / lockfile):
panel==v1.0.0rc6
pandas==1.5.3
holoviews==1.16.0a2
hvplot
pandas-gbq>=0.19.1