param.Selector into panel.widgets.RadioButtonGroup

For the 3 values I allow for a parameter.Selector, I would like them to be shown as a RadioButtonGroup instead of a drop-down menu. How do I do that?

This is what I have for now:

import param
import panel as pn

class Det(param.Parameterized):
    _x_values = [1024, 2048, 4096]
    n_lines = param.Selector(_x_values, default=2048)
    n_samples = param.Integer(2048, bounds=(1024, 4096), step=1024)

    @param.depends("n_lines", watch=True)
    def _update_n_samples(self):
        self.n_samples = self.n_lines

pn.Column(Det())

I would use pn.Param like this

class Det(param.Parameterized):
    _x_values = [1024, 2048, 4096]
    n_lines = param.Selector(_x_values, default=2048)
    n_samples = param.Integer(2048, bounds=(1024, 4096), step=1024)

    def __init__(self, **params):
        super().__init__(**params)
        # self.controls = pn.Param(self, widgets={"n_lines": pn.widgets.RadioBoxGroup})  
        # or
        self.controls = pn.Param(
            self,
            widgets={"n_lines": {"type": pn.widgets.RadioBoxGroup, "inline": True}},
        )

    @param.depends("n_lines", watch=True)
    def _update_n_samples(self):
        self.n_samples = self.n_lines


pn.Column(Det().controls).servable()

And if you want the to remove the controls from pn.column I would inherit from pn.viewable.Viewer like:

class Det(pn.viewable.Viewer):
    _x_values = [1024, 2048, 4096]
    n_lines = param.Selector(_x_values, default=2048)
    n_samples = param.Integer(2048, bounds=(1024, 4096), step=1024)

    def __init__(self, **params):
        super().__init__(**params)
        # self.controls = pn.Param(self, widgets={"n_lines": pn.widgets.RadioBoxGroup})  
        # or
        self.controls = pn.Param(
            self,
            widgets={"n_lines": {"type": pn.widgets.RadioBoxGroup, "inline": True}},
        )

    @param.depends("n_lines", watch=True)
    def _update_n_samples(self):
        self.n_samples = self.n_lines

    def __panel__(self):
        return self.controls


pn.Column(Det()).servable()
2 Likes

@Hoxbro’s approach is a good one if you want your Parameterized class to be opinionated about its Panel representation. If you want to leave the Parameterized class as-is, you can choose the representation when you construct your panel:

import param, panel as pn
pn.extension()

class Det(param.Parameterized):
    _x_values = [1024, 2048, 4096]
    n_lines = param.Selector(_x_values, default=2048)
    n_samples = param.Integer(2048, bounds=(1024, 4096), step=1024)

    @param.depends("n_lines", watch=True)
    def _update_n_samples(self):
        self.n_samples = self.n_lines

pn.Param(Det.param, widgets={'n_lines': pn.widgets.RadioButtonGroup})

1 Like

Thanks!

And, is it a bug that the drop-down menu correctly puts a name label for n_lines on the widget, but the RadioButtonGroup does not?

Yep: https://github.com/holoviz/panel/issues/1313

Definitely could use someone making that more consistent!

1 Like