How to add additional callbacks to Annotators?

Is there a way to add additional callbacks to the Annotators? I would like to wrap it in a param-style app. Here is my attempt, building upon the example in the user guide.

import param
import panel as pn
import pandas as pd
import holoviews as hv
hv.extension('bokeh')

data = {
    "lon": [1,2000000],
    "lat": [1,2000000],
    "site": list("ab"),
}

class AA(param.Parameterized):

    plot = param.ClassSelector(class_=hv.DynamicMap)

    annotator = param.ClassSelector(class_=hv.annotators.PointAnnotator)

    counter = param.Integer(default=0,)

    def __init__(self, df=pd.DataFrame(data)):

        annotator = hv.annotate.instance()
        points = hv.Points(
            df, kdims=['lon', 'lat',], vdims=["site"]
        ).opts(size=10)

        layout = annotator(points, annotations=['site'], empty_value='')

        dm = layout.DynamicMap.I
        dm.opts(active_tools=['wheel_zoom','point_draw'])

        super().__init__(
            annotator = annotator.annotator,
            plot = dm,
            counter=0
        )
        # I would have rather had the table as a valid parameter,
        # but I did not know how to make it work
        self.table = annotator.annotator.layout[1][0]

    # @pn.depends("plot.data") # does not work
    # @pn.depends("plot.param.data") # does not work
    @pn.depends() # does not work
    def _update_internals(self, watch=True):
        # trivial example, the reality is much more complex :-)
        self.counter += 1

a = AA()
pn.Column(
    a.plot,
    pn.Row("interactions counter: ", a.counter),
    a.table,
).servable()

Also, is anyone knows how to have a pn.Tabulator instead of hv.Table there, I’d be more than happy. I saw similar examples here, but not when it comes to full functionality of the PointDraw tool. FWIW, I only need table -> plot sync for the label change.

I really tried to find the parameter you can depends on when you add an annotation, but could not. Do you know how to do this @philippjfr ?

Thanks for looking into this, @Marc. I’ve also spent probably hours digging through documentation, hv.helps, even dirs and __dict__s before posting the question :slight_smile:

1 Like

I tried an alternative approach using PointDraw for plot->df, and TextInput+Selection1D for renaming, and… it almost works, except for a small hurdle. Maybe this is trivial.