Skip to content

Make it easy for me to provide examples that my users can run a model on #6205

@MarcSkovMadsen

Description

@MarcSkovMadsen

Use Case

Sometimes you want to make it easy for your users to input a value. For example if you have a model and you want your user to try it out.

For example Gradio supports this and uses it extensible for demos of model. See Examples. Please note that their Examples component support more than text buttons. It can be buttons representing any kind of media including audio and video.

Panel has different Button groups. But they don't serve my purpose because they are associated with one or more options being checked. Also visually.

Hack Code

A hack is to develop something like the below. I added an ExampleSelect too because that is also used a lot in the Hugging Face/ Gradio universe.

import panel as pn
import param

pn.extension(sizing_mode="stretch_width", design="material")

class ExamplesButtons(pn.viewable.Viewer):
    value = param.String()

    def __init__(self, names, button_type="default", default_layout=pn.Column):
        super().__init__()
        group = default_layout()
        for name in names:
            button = pn.widgets.Button(name=name, button_type=button_type, sizing_mode="fixed", button_style="outline")
            button.param.watch(self._update_value, "clicks")
            group.append(button)
        
        self._group = group

    def __panel__(self):
        return self._group

    def _update_value(self, event):
        self.value = event.obj.name

class ExamplesSelect(pn.viewable.Viewer):
    value = param.String()

    def __init__(self, names,):
        super().__init__()
        
        self._names=names
        
        widget = pn.widgets.Select(options=["Examples", *names])
        widget.param.watch(self._update_value_first_time, "value")
        self._group = pn.Column(widget)

    def __panel__(self):
        return self._group

    def _update_value_first_time(self, event):
        self.value = event.new
        
        widget = pn.widgets.Select(value=self.value, options=self._names)
        widget.param.watch(self._update_value, "value", queued=True)
        self._group[:] = [widget]

    def _update_value(self, event):
        self.value = event.new

        


examples=[f"Example {i}" for i in range(10)]

button_group = ExamplesButtons(examples, default_layout=pn.layout.FlexBox)
button_layout = pn.Column(
    "## Examples", button_group, "## Input", button_group.param.value, pn.widgets.Button(name="Submit", button_type="primary")
)

select_group = ExamplesSelect(examples)
select_layout = pn.Column(
    "## Examples", select_group, "## Input", select_group.param.value, pn.widgets.Button(name="Submit", button_type="primary")
)

pn.Row(button_layout, select_layout).servable()
examples.mp4

Additional Context

I was starting to write a small article about using Panel with Transformers library. But having to show and explain the above to users just makes everything so much more complicated.

Gradio users would assume something like the above is very easy to do.

Note

The options of the Select widget in the example above are hard to update dynamically. I could not figure out how to do it.

Question

Are we interested in adding missing Gradio functionality like this to Panel?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions