panel icon indicating copy to clipboard operation
panel copied to clipboard

Implement a nested dropdown select

Open ahuang11 opened this issue 8 months ago • 10 comments

Can we have something like a nested, n-dim select dropdown built-in to Panel widgets? (I vaguely remember seeing @jlstevens implement this somewhere?)

import panel as pn
pn.extension()

WX_VARS_LEVS = {"precip": [1000], "temp": [1000, 925, 700, 500, 300], "vorticity": [500, 300]}
WX_VARS = list(WX_VARS_LEVS.keys())

def update_lev_select(var):
    return pn.widgets.Select(options=WX_VARS_LEVS[var])

var_select = pn.widgets.Select(options=WX_VARS)
lev_select = pn.bind(update_lev_select, var=var_select)
pn.Column(var_select, lev_select)
image image

Not sure if it's enough to support just one level, but for multiple levels, I imagine a dict of dict of list? {"precip": {"conus": [1000], "global": [1000]}, "temp": {"conus": [1000, 925, 700, 500, 300], "global": {"temp": [1000, 500]}}}

Here's an applicable example of multi-level dropdowns:

  1. Product
  2. Layer
  3. Time (potentially 4. Level) image

ahuang11 avatar Oct 25 '23 18:10 ahuang11

Very often the data you have is not a dict, but a dataframe

MarcSkovMadsen avatar Oct 25 '23 19:10 MarcSkovMadsen

To be consistent with other widgets, I like the idea of keeping dict, list. (I suppose Tabulator/Perspective uses param.DataFrame)

Also, I think transforming a dataframe to a dict is semi-trivial df.to_dict()

I wonder how a dataframe with multi-level would look.

ahuang11 avatar Oct 25 '23 19:10 ahuang11

Usually you'd have a multi-index that maps to the dict. I'm fine with a .from_index() method or similar.

philippjfr avatar Oct 26 '23 11:10 philippjfr

Generally I've always wanted a .from_pandas method for most widgets that automatically computes the bounds for sliders and the options for select widgets.

philippjfr avatar Oct 26 '23 11:10 philippjfr

To be consistent with other widgets, I like the idea of keeping dict, list. (I suppose Tabulator/Perspective uses param.DataFrame)

Also, I think transforming a dataframe to a dict is semi-trivial df.to_dict()

I wonder how a dataframe with multi-level would look.

Its not just transforming a dataframe to a dictionary. You might have a DataFrame with 10mn rows containing categorical columns category1, category2, category3 and other columns. You then want to select first from the unique category1 values. Then from the reduced set of unique category2 values under category1 etc.

MarcSkovMadsen avatar Oct 26 '23 12:10 MarcSkovMadsen

So I suppose this widget should definitely support n-nesting, and I agree that I prefer from_pandas or from_index instead of a param.DataFrame field.

ahuang11 avatar Oct 26 '23 22:10 ahuang11

I can try creating a prototype. Would this be a CompositeWidget?

ahuang11 avatar Oct 26 '23 22:10 ahuang11

One thing to note is that it would be nice to have some more complex dependencies. For example you could have one widgets contents be dependent on two independent widgets.

benbarn313 avatar Oct 26 '23 22:10 benbarn313

Interesting idea; not entirely clear how to express that as a Python type--perhaps tuples as keys?

{("temperature", 1000): [*times], ("temperature", 500): [*other_times]}

or actually is that the same as {"temperature": {"1000": [*times], "500": [*other_times]}}

Ah I understand, it's two separate widgets simultaneously shown...

File Type + Variable -> Levels -> Times vs File Type -> Variable -> Levels -> Times

However, is it necessary to show both simultaneously?

If so, is it within the scope of this widget or separate?

ahuang11 avatar Oct 26 '23 23:10 ahuang11

Although this feature is already merged, I want to ask, if this could be extended to Multiselect.

legout avatar Apr 22 '24 09:04 legout