You can use the click_data
for example via something like
@pn.depends(parent_plot_pane.param.click_data)
def child_plot_from_click(event, data=data):
try:
row = event["points"][0]["x"]
return to_child_plot(data, row=row, height=300)
except:
return "Click a Country to show its timeseries"
The full code is here
import pandas as pd
import panel as pn
import plotly.express as px
# World Bank API. See https://github.com/tgherzog/wbgapi
import wbgapi as wb
pn.extension("plotly", sizing_mode="stretch_width", template="fast")
ACCENT="#00A170"
SERIES = "EN.ATM.CO2E.PC"
SERIES_PATH = SERIES + ".csv"
def extract():
try:
return pd.read_csv(SERIES_PATH, index_col=0)
except FileNotFoundError:
data = wb.data.DataFrame(SERIES, labels=True)
data.to_csv(SERIES_PATH, )
return data
def transform(source_data):
data = source_data.dropna(how="all", axis=1)
data = data.set_index("Country")
data.columns = [int(column[2:]) for column in data.columns]
return data
def get_template():
if pn.state.session_args.get("theme", [b'default'])[0].decode()=="dark":
return "plotly_dark"
else:
return "plotly"
TEMPLATE = get_template()
def to_parent_plot(plot_data: pd.DataFrame, column, rows=20):
data=plot_data[column].dropna()
data=data.sort_values(ascending=False)
data=data.head(rows)
fig = px.bar(data, y=column, color_discrete_sequence=[ACCENT], template=TEMPLATE)
fig.layout.autosize = True
return fig
def to_child_plot(plot_data: pd.DataFrame, row, height=300):
data=plot_data.loc[row].dropna()
data=pd.DataFrame(data, columns=[row])
data.index.name="Year"
fig = px.line(data, y=row, template=TEMPLATE, height=height)
fig.update_traces(line=dict(color=ACCENT, width=4))
return fig
source_data=extract()
data=transform(source_data)
source = pn.pane.Alert(f"""## Source
[World Bank {SERIES}](https://data.worldbank.org/indicator/{SERIES})""", margin=(10,10), alert_type="secondary").servable(area="sidebar")
column = list(data.columns)[-1]
parent_plot = to_parent_plot(data, column=column)
parent_plot_pane = pn.pane.Plotly(parent_plot, config={'responsive': True}, height=400)
@pn.depends(parent_plot_pane.param.click_data)
def child_plot_from_click(event, data=data):
try:
row = event["points"][0]["x"]
return to_child_plot(data, row=row, height=300)
except:
return "Click a Country to show its timeseries"
pn.Column(parent_plot_pane, child_plot_from_click, sizing_mode="stretch_both").servable()
pn.state.template.param.update(site="Awesome Panel", title="CO2 emissions (tons per capita)", accent_base_color=ACCENT, header_background=ACCENT)
To serve the app you will need to
panel serve name_of_script.py --show --autoreload