Nested Tabs from Nested Dict

Hello,

I have a nested dictionary of DynamicMap objects:

{'MH_coupled': {'temp2': :DynamicMap   []
     :Overlay
        .Image.I     :Image   [lon,lat]   (temp2)
        .Coastline.I :Feature   [Longitude,Latitude],
  'precip': :DynamicMap   []},
 'LIG_coupled': {'temp2': :DynamicMap   []
     :Overlay
        .Image.I     :Image   [lon,lat]   (temp2)
        .Coastline.I :Feature   [Longitude,Latitude],
  'precip': :DynamicMap   []},
 '4CO2_coupled': {'temp2': :DynamicMap   []
     :Overlay
        .Image.I     :Image   [lon,lat]   (temp2)
        .Coastline.I :Feature   [Longitude,Latitude],
  'precip': :DynamicMap   []},
 '1percCO2_coupled': {'temp2': :DynamicMap   []
     :Overlay
        .Image.I     :Image   [lon,lat]   (temp2)
        .Coastline.I :Feature   [Longitude,Latitude],
  'precip': :DynamicMap   []
     :Overlay
        .Image.I     :Image   [lon,lat]   (value)
        .Coastline.I :Feature   [Longitude,Latitude]}}

I’d like to make nested tabs from this, so:

def nested_dict_to_tabs(a):
    ret_list = []
    for k, v in a.items():
        if isinstance(v, dict):
            ret_list.append(nested_dict_to_tabs(v))
        else:
            ret_list.append((k, v))
    return pn.Tabs(*ret_list)
nested_dict_to_tabs(a)

However, this doesn’t set up the tab titles correctly for everything except the inner most tabs:

Anything I’m doing wrong?

I suspect you meant:

def nested_dict_to_tabs(a):
    ret_list = []
    for k, v in a.items():
        if isinstance(v, dict):
            ret_list.append((k, nested_dict_to_tabs(v)))
        else:
            ret_list.append((k, v))
    return pn.Tabs(*ret_list)

or the way I would write it:

def nested_dict_to_tabs(a):
    return pn.Tabs(*[(k,nested_dict_to_tabs(v) if isinstance(v, dict) else v)
                     for k, v in a.items()])
1 Like

Yes! Thanks!!! That explains why the inner most level worked. I have two follow up questions:

  1. Would it be sensible to include little helper functions like this in Panel? Maybe as part of the package itself, or maybe just in the example or reference notebooks?

  2. Changing an outer tab will normally “reset” the inner tabs, e.g. if I have the tab precip selected for 4CO2_coupled but then change to MH_coupled, the inner tab resets to temp2. I guess I need some sort of callback which switches the inner tabs to the same active tab for all upper ones. Any hints about how I do that?

Cheers,
Paul

Would it be sensible to include little helper functions like this in Panel?

Probably out-of-scope to be honest, there are a lot of formats you could imagine specifying Tabs and nested tabs in.

Changing an outer tab will normally “reset” the inner tabs, e.g. if I have the tab precip selected for 4CO2_coupled but then change to MH_coupled, the inner tab resets to temp2.

That’s true, I can only suggest that before you replace it you iterate over the items in the subtab and record the active state and then restore that state on the new subtab.