Holoviews, panel, hvplot - linked selection doesn't reset when using dropdown

I have a dropdown, a chart and a table interlinked. All works fine, except when I make a new selection from the dropdown, the brush selection doesn’t reset itself and I have to click refresh on the chart to see new values corresponding to the newly selected value from the dropdown.
How do I change it so when I select a new value from the dropdown (new island), the chart resets automatically and all the previous linked selections or filters get reset without me needing to click ‘refresh’ manually? Thanks

Here is the self-contained example and attached gif

import panel as pn
import holoviews as hv
pn.extension('tabulator', template='material', sizing_mode='stretch_width')
import hvplot.pandas # noqa
pd.options.display.float_format = '{:.0f}'.format

island_dropdown = pn.widgets.Select(name='Island',
                                     options=penguins_df.Island.unique().tolist(),
                                     value=penguins_df.Island.unique().tolist()[0])

penguins_dfi =  penguins_df.interactive(sizing_mode='stretch_width')
penguins_dfi = penguins_dfi[(penguins_dfi['Island'] == island_dropdown)]
# # points plot
points_plot = penguins_dfi.hvplot(x='Species',
                                      y='Body Mass (g)',
                                      kind='points',
                                      height=350, 
                                      width=900,
                                      persist=True,
                                      hover_cols=['Body Mass (g)','Beak Length (mm)', 'Flipper Length (mm)'],
                                      yformatter='%d')

ls_common = hv.link_selections.instance(unselected_alpha=0.08)

# # Table is not yet dynamically linked to the linked selection
table = penguins_dfi[['Island', 'Species', 'Sex', 'Body Mass (g)','Beak Length (mm)', 'Flipper Length (mm)']].pipe(ls_common.filter, selection_expr=ls_common.param.selection_expr).pipe(
    pn.widgets.Tabulator, pagination='remote', page_size=10)

column = pn.Column(penguins_dfi.widgets(),ls_common(points_plot.holoviews()), ls_common(table.panel()))
column

enter image description here

1 Like

Hi @pepopepa,

I don’t have a solution to your code but if you simplify it down to remove the linked selection, you can see the box tool in operation, you can simply press the escape key to clear or long click on the box tool and select clear. The code above kind of breaks this feature, I don’t know if there’s a different way to do it to keep box tool functioning correctly.

I didn’t quite get what you meant. I tried the esc button, but it doesn’t reset the filters. Removing the link_selection would defeat the purpose for my use case (If I understood your suggestion correctly)
My need is to have three pieces dependent on each other. 1 - dropdown, 2 - chart with selections affecting 3 - the table . When I use the dropdown and choose a new value, all the previous selections should get reset to nothing. Kind of like it works out-of-the-box if to use the groupby

Hi @pepopepa,

What I see from the supplied code is that the box select feature doesn’t behave like I would expect / anticipate. So lets see where it starts to break down; specifically with the link selection because perhaps it could be done differently, maybe it operates differently due to the feature required and maybe it’s a bug or something else that should be reported. That’s really what I’m suggesting I think.

I had a look through the holoviews page (sorry lost the link) following the tutorial and this is how I see it

If you use box select out the box with no linking it makes use of bokeh JavaScript and seems to work fluently as one would expect, you can easily reset, press escape and long press the tool for other options - of course as you’ve said this wouldn’t be any use for your use case as your looking for it to be linked

When you activate the linking it now uses python on the backend server that I can gather from reading but immediately the box select behaves differently from the above but it behaves same as your code sample in the tutorial guide. So my question here would be is that intended behavior with the feature or has something changed on versions and stopped functioning properly.

I’ve been playing around with your code, I added a handy depends on the drop down widget and cleared the expression and now seems to work when you change the drop down it resets the selection. hope it helps and nice work by the way something I’ve been meaning to implement myself in ages

import panel as pn
import holoviews as hv
import pandas as pd
import hvplot.pandas # noqa

from bokeh.sampledata.penguins import data as penguins_df

pn.extension('tabulator', template='material', sizing_mode='stretch_width')
pd.options.display.float_format = '{:.0f}'.format

island_dropdown = pn.widgets.Select(name='island',
                                     options=penguins_df.island.unique().tolist(),
                                     value=penguins_df.island.unique().tolist()[0])

penguins_dfi =  penguins_df.interactive(sizing_mode='stretch_width')
penguins_dfi = penguins_dfi[(penguins_dfi['island'] == island_dropdown)]
# # points plot
points_plot = penguins_dfi.hvplot(x='species',
                                      y='body_mass_g',
                                      kind='points',
                                      height=350, 
                                      width=900,
                                      persist=True,
                                      hover_cols=['body_mass_g','bill_length_mm', 'flipper_length_mm'],
                                      yformatter='%d')


ls_common = hv.link_selections.instance()
ls_common.show_regions=True


@pn.depends(island_dropdown.param.value,watch=True)
def clear_selection_on_drop_down_change(self):
    ls_common.selection_expr = None


# # Table is not yet dynamically linked to the linked selection
table = penguins_dfi[['island', 'species', 'sex', 'body_mass_g','bill_length_mm', 'flipper_length_mm']].pipe(ls_common.filter, selection_expr=ls_common.param.selection_expr).pipe(
    pn.widgets.Tabulator, pagination='remote', page_size=10)

column = pn.Column(penguins_dfi.widgets(),ls_common(points_plot.holoviews()), ls_common(table.panel()))
column.show()

This work and works very nicely. There is a small lag when I select a new value from the dropdown and on my own dataset, which is multiple gigs of RAM the lag would be a bit bigger, but the behaviour is exactly what I was looking for.
I bet I saw the tutorial you mention, but I couldn’t make it work with the depends option. It would break the link to the table somehow. I actually wanted to use Altair first. It has a really nice linked brush that once selected, you can just pan over the chart and the selection would persist. But I couldn’t make it work either. So I went through a maze of tutorials and cannibalised pieces of code for my use case. Thanks a lot for correcting it @carl . What I don’t get is how come the function clear_selection_on_drop_down_change works even though it’s not even called anywhere. It’s just declared, but not called ?!

This is the magic line

@pn.depends(island_dropdown.param.value,watch=True)

It sets up some behind the scenes magic, watch = true kind of throws me, naturally I make the wrong assumption your telling the system to keep an eye on things but actually I think you use it if you use return in the method or if you don’t use return you put in the watch statement.

1 Like

Thanks for the explanation. I get it now. Just unusual in python to assume the function is doing something behind the scenes without being called. Even if that function has another func wrapped around it like the @depends does. The important point is that it works. Thanks for that

2 Likes