How to bidirectionally link a param and hv stream?

I want self.param.x & self.param.y to sync up with tap.param.x and tap.param.y.

If it was a plain widget, something like:
pn.widgets.TextInput().link(... bidirectional=True)

import param
import panel as pn

import holoviews as hv

class Test(param.Parameterized):
    
    y = param.Number()
    x = param.Number()
    
    def __init__(self):
        self.tap = hv.streams.Tap()
    
    def draw(self, x, y):
        return hv.Points((x, y))
    
    def panel(self):
        return pn.Column(
            hv.DynamicMap(self.draw, streams=[self.tap]),
            pn.Row(self.param.x, self.param.y)
        )

Test().panel()

This seem to do the trick

class Test(param.Parameterized):
    x = param.Number(0)
    y = param.Number(0)

    def __init__(self, **params):
        super().__init__(**params)
        self.tap = hv.streams.Tap(x=self.x, y=self.y)
        self.dmap = hv.DynamicMap(self.draw, streams=[self.tap])

    def draw(self, x, y):
        self.x, self.y = x, y
        return hv.Points((x, y))

    @param.depends("x", "y", watch=True)
    def _update_param(self):
        self.dmap.event(x=self.x, y=self.y)

    def panel(self):
        return pn.Column(
            self.dmap,
            pn.Row(self.param.x, self.param.y)
        )

Thanks you’re awesome!
A suggestion is replacing
self.x, self.y = x, y
with
self.param.set_param(x=x, y=y)
So it’s updated together as a batch!

1 Like