Return value other than index on hover

Hi, I have another question. I’ve made a (quite cool I think) dashboard which retrieves info on points in a scatter plot when hovering over a point, similar to Jon’s car exploration example:

(https://github.com/jonmmease/plotly_ipywidget_notebooks/blob/master/notebooks/cars_exploration.ipynb)

In my version though I have it set to retrieve the index of a point on hover like in the example using:

def hover_fn(trace, points, state):

    ind = points.point_inds[0]

scatter.on_hover(hover_fn)

But I can’t get this to work with my code. I was wondering if there was a way to retrieve the X value of a point, rather than the index with points.point_inds? That would fix my problem I think.

I’ve been googling around but can’t figure it out. I might be asking for more than is possible at this stage!

Thanks

Hi @KidSampson,

If you check out the bottom of the on_hover docstring (you can display docstrings in the Jupyter Notebook using the Shift+ Tab keyboard shortcut) you’ll see this example:

The two lines above the hover_fn definition are there to show you the data type of the points and state arguments that will be passed to your function. If you evaluate these lines, before writing hover_fn you’ll get tab completion on the available properties of points and state.

from plotly.callbacks import Points, InputDeviceState
points, state = Points(), InputDeviceState()

10%20AM

So there you can see that in addition to point_inds you can also get a list of the x and y coordinates of the hovered point(s). For completeness, I’ll point out that there are some useful properties in state that you can use to build more flexible interactions.

32%20AM

Hope that helps!
-Jone

1 Like

That’s great, thanks Jon. Those docstrings weren’t showing up for me because of how my notebook is arranged but they work in your example notebooks.

I’ve got a follow-up question now. Is it possible to apply the on_hover method to several traces? My plot has a few traces in it and I’d like to be able to use my hover method on all of them, but if I call the function several times to apply to my various traces, only the last one that its called on responds.

I’ve tried adding the append=True option but that only applies to calling the function on the same trace multiple times right?

Thanks again!

I’m not sure if I’m following exactly what you mean, but here’s an example of attaching a hover callback to multiple traces that works for me:

import plotly.graph_objs as go

fig = go.FigureWidget(layout={'hovermode': 'closest'})
fig

scatt0 = fig.add_scatter(y=[2, 3, 1], mode='markers')
scatt1 = fig.add_scatter(y=[3, 1, 0], mode='markers')
scatt2 = fig.add_scatter(y=[1, 0, 1.5], mode='markers')

def do_hover(trace, points, *_):
    if points.point_inds:
        print(points)

scatt0.on_hover(do_hover)
scatt1.on_hover(do_hover)
scatt2.on_hover(do_hover)

fig

As I hover over multiple points the callback is called for each trace (Note that printing from a callback function like this only works in the classic notebook, in JupyterLab you need to use an OutputWidget to display output from a callback function).

Points(point_inds=[1],
       xs=[1],
       ys=[3],
       trace_name='trace 0',
       trace_index=0)
Points(point_inds=[1],
       xs=[1],
       ys=[1],
       trace_name='trace 1',
       trace_index=1)
Points(point_inds=[1],
       xs=[1],
       ys=[0],
       trace_name='trace 2',
       trace_index=2)

And you are right that the append=True arg is only relevant if you’re attaching multiple callbacks to the same trace.

Hope that helps, but feel free to post a specific example if not :slightly_smiling_face:
-Jon

1 Like

Jon, I’m not sure which part of my code was wrong and what you’ve fixed, but it works perfectly now and I couldn’t be happier.

Thanks for the help!

1 Like