Panel Param change in .visible property is not applied

I am trying to let one parameter influence whether or not a second parameter is visible in a panel. When I check in the console, the params.widgets['k'].visible is updated correctly, but the changes are not reflected in what is actually shown in my panel.

What can I do to make the .visible property actually change the visibility of the widget in the panel?

MWE:

import numpy as np
import pandas as pd

import holoviews as hv
import hvplot.pandas
hv.extension('bokeh', logo=False)

import panel as pn
import param

data_1 = pd.DataFrame(np.random.normal(0, 1000000, size=(10,2))).rename(columns={0: 'easting', 1: 'northing'})
data_2 = pd.DataFrame(np.random.normal(0, 1000000, size=(10,2))).rename(columns={0: 'easting', 1: 'northing'})

class DataParameters(param.Parameterized):
    dataset = param.Selector(objects=['Data 1', 'Data 2'])
    k = param.Integer(bounds=(0,10))
    
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

data_params = DataParameters()

params = pn.Param(data_params.param, widgets={
    'dataset': pn.widgets.RadioBoxGroup,
    'k': pn.widgets.IntSlider,
    },
    )

@pn.depends(dataset=data_params.param.dataset,
            k=data_params.param.k)
def plot_data(dataset, k):
    if dataset == 'Data 1':
        plot = data_1.hvplot(kind='points', x='easting', y='northing', color='red')
    else:
        plot = data_2.hvplot(kind='points', x='easting', y='northing', color='red')
    return plot


@pn.depends(dataset=data_params.param.dataset, watch=True)
def show_widgets(dataset):
    if dataset == 'data_1':
        params.widgets['k'].visible = True
    else:
        params.widgets['k'].visible = False  # This value does change correctly. But I can still see the widget in the panel...


dataview = hv.DynamicMap(plot_data)


panel_row = pn.Row(params, dataview)
bokeh_server = panel_row.show(port=12345)

In your code params.widgets['k'] returns the widget class that you’ve defined in pn.Param(...). You need to modify the widget instance, to which you can get a handle on with params.layout[2] (it’s the third widget, after the title and the dataset widget).

@pn.depends(dataset=data_params.param.dataset, watch=True)
def show_widgets(dataset):
    print('Hey', dataset)
    if dataset == 'Data 1':
        params.layout[2].visible = True
    else:
        params.layout[2].visible = False
1 Like