How do I make widget values depend in hvplot .interactive

I’m trying to analyze a Dataframe with information about my repositories using hvplot .interactive.

I have created the below.

The issue is that as soon as I select some different columns I get a KeyError because the sort_value is not longer in the columns. Is it possible to implement this using hvplot .interactive or do I need to sprinkle in some pn.bind?

import hvplot.pandas  # adds .hvplot and .interactive to DataFrames
import pandas as pd
import panel as pn
from diskcache import FanoutCache

pn.extension(sizing_mode="stretch_width", template="fast")
ACCENT = "orange"
pn.state.template.param.update(site="Awesome Panel", title="Repos Analysis with hvplot .interactive", accent_base_color=ACCENT, header_background=ACCENT)

cache=FanoutCache()

@cache.memoize(expire=60*60*24, name="repos")
def get_data():
    return pd.read_json("https://api.github.com/users/marcskovmadsen/repos?perpage=100")
    
df = get_data()

all_columns = sorted(df.columns)
default_columns = ["name", "stargazers_count", "forks"]

columns = pn.widgets.MultiSelect(value=default_columns, options=all_columns, name="Show Columns", height=600)
sort_value = pn.widgets.Select(value="stargazers_count", options=all_columns, name="Sort by")
ascending = pn.widgets.Checkbox(value=False, name="Sort ascending")
rows = pn.widgets.IntSlider(value=10, start=1, end=20, step=1, name="Number of rows")

# df_interactive also works in your notebook
df_interactive = df.interactive[columns].sort_values(sort_value, ascending=ascending).head(rows)

df_interactive.widgets().servable(area="sidebar")
df_interactive.panel().servable()

I can see that I can handle it using pn.depends like below.

import hvplot.pandas  # adds .hvplot and .interactive to DataFrames
import pandas as pd
import panel as pn
from diskcache import FanoutCache

pn.extension(sizing_mode="stretch_width", template="fast")
ACCENT = "orange"
pn.state.template.param.update(site="Awesome Panel", title="Repos Analysis with hvplot .interactive", accent_base_color=ACCENT, header_background=ACCENT)

cache=FanoutCache()

@cache.memoize(expire=60*60*24, name="repos")
def get_data():
    return pd.read_json("https://api.github.com/users/marcskovmadsen/repos?perpage=100")
    
df = get_data()

all_columns = sorted([column for column in df.columns if not column.endswith("url")])
default_columns = ["name", "stargazers_count", "forks"]

columns = pn.widgets.MultiSelect(value=default_columns, options=all_columns, name="Show Columns", height=600)
sort_value = pn.widgets.Select(value="stargazers_count", options=default_columns, name="Sort by")
ascending = pn.widgets.Checkbox(value=False, name="Sort ascending")
rows = pn.widgets.IntSlider(value=10, start=1, end=20, step=1, name="Number of rows")

@pn.depends(columns, watch=True)
def _update_sort_value(columns):
    sort_value.options = columns
    if sort_value.value in columns:
        pass
    elif columns:
        sort_value.value = columns[0]
    else:
        sort_value.value = []

# df_interactive also works in your notebook
df_interactive = df.interactive[columns].sort_values(sort_value, ascending=ascending).head(rows)

df_interactive.widgets().servable(area="sidebar")
df_interactive.panel().servable()

Will this work?

df_interactive = df.interactive.sort_values(sort_value, ascending=ascending)[columns].head(rows)

1 Like

Thanks @Hoxbro

It will make the KeyError go away. But I will not end up with the functionality I want. I want to sort_values by the columns shown in the table. Not all columns.

The app could actually be turned into a nice little app for analyzing your repositories. And with the next version of hvplot I should be able to start .interactive not from an existing dataframe but from any dependent function that returns a dataframe.

2 Likes