Skip to content

Cannot link tap to float slider #6384

@ahuang11

Description

@ahuang11

For widgets, there’s pn.Param and from_param.

What’s the equivalent for HoloViews streams?

https://discourse.holoviz.org/t/whats-the-best-practice-for-linking-up-holoviews-streams-with-parameterized/8215/3

I thought the following would work, but I get TypeError: Constant parameter 'x' cannot be modified

Can we remove the constant=True, or create a dedicated method like from_param or from_params?

image
import param
import holoviews as hv
import panel as pn
pn.extension()

class TapTest(pn.custom.PyComponent):
    x = param.Number(default=0)
    y = param.Number(default=0)

    def __init__(self, **params):
        super().__init__(**params)

        self._tap = hv.streams.Tap()

        hv_pane = pn.pane.HoloViews()
        hv_pane.object = hv.DynamicMap(self.plot, streams=[self._tap])

        x_spinner = pn.widgets.FloatSlider.from_param(self.param.x)
        y_spinner = pn.widgets.FloatSlider.from_param(self.param.y)
        x_spinner.link(self._tap, value='x', bidirectional=True)
        y_spinner.link(self._tap, value='y', bidirectional=True)
        self._layout = pn.Column(hv_pane, x_spinner, y_spinner)


    def plot(self, x, y):
        return hv.Points([(x, y)]).opts(tools=['tap'])

    def __panel__(self):
        return self._layout

pn.serve(TapTest())

The workaround is a bit more code

import param
import holoviews as hv
import panel as pn
pn.extension()

class TapTest(pn.custom.PyComponent):
    x = param.Number(default=0)
    y = param.Number(default=0)

    def __init__(self, **params):
        super().__init__(**params)

        self._tap = hv.streams.Tap()
        hv_pane = pn.pane.HoloViews()
        hv_pane.object = hv.DynamicMap(self.plot, streams=[self._tap])
        
        pn.bind(self.update_tap, self.param.x, self.param.y, watch=True)
        
        self._layout = pn.Column(hv_pane, self.param.x, self.param.y)

    def update_tap(self, x, y):
        self._tap.event(x=x, y=y)

    def plot(self, x, y):
        if x and y:
            self.param.update(x=x, y=y)
        return hv.Points([(self.x, self.y)]).opts(tools=['tap'])

    def __panel__(self):
        return self._layout

pn.serve(TapTest())

Metadata

Metadata

Assignees

No one assigned

    Labels

    type: enhancementMinor feature or improvement to an existing feature

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions