Events on plots made with overlay

I need to listen to client-side events on plots made with hvplot.line but am not having success. I have tried:

import pandas as pd
import holoviews as hv

def update_handler(e):
    print(e)
    
df = pd.DataFrame([[1,2],[3,4]])
plot = df.hvplot.line()
plot.on_event('rangesupdate', update_handler)

the above code results in

AttributeError: 'NdOverlay' object has no attribute 'on_event'

Help is appreciated

With some digging around I have a solution. The NdOverlay is part of a rich hierarchy of objects. I found this resource very helpful: Building Composite Objects ā€” HoloViews v1.16.0

I had to set up a stream and then bind the client-side event Iā€™m interested (changes in the x_range) to a server-side python function. Here is a working implementation:

import numpy as np
import pandas as pd
import holoviews as hv
import panel as pn
import hvplot.pandas

hv.extension('bokeh')
pn.extension()


def x_range_changed(xr):
    value = f"x_range changed to: ({xr[0]:.3f}, {xr[1]:.3f})" if xr else None
    print(value)


num_pts = 1000
df1 = pd.DataFrame({'x': np.linspace(0, 100, num_pts),
                    'y1': np.cumsum(np.random.randn(num_pts)),
                    'y2': np.cumsum(np.random.randn(num_pts))})

overlay = df1.hvplot.line(x='x', y=['y1', 'y2'])  # return type is NdOverlay

# however note that the following returns a Curve
hvObject = df1.hvplot.line(x='x', y=['y1'])
print(type(hvObject))  # <class 'holoviews.element.chart.Curve'>

# get the underlying curve
curve = next(iter(overlay.data.values()))  # grab the first Curve object
rng = hv.streams.RangeX(source=curve)
client_to_server_link = pn.bind(x_range_changed, xr=rng.param.x_range)

column = pn.Column(overlay, client_to_server_link)
column.servable()

1 Like