Black Lives Matter. Please consider donating to Black Girls Code today.

Interactive Graph Click Event

I’m trying to figure out if it’s possible to create a PlotLy Pie Chart in python with an on_click event in JupyterLab. I’ve been able to run the scatter plot example:

When I try to adapt this for a pie chart, though, the callback doesn’t look like it’s ever being called. I’m not sure if this is possible and there’s something missing in my adaptation, or if it’s a capability that’s only available for scatter and not for other kinds of plots.

Can anyone advise or provide feedback on this? Thanks!

Hi @tdonadio,

Click events on pie charts should work. Here’s an example that’s working for me

import plotly.graph_objs as go
from ipywidgets import Output, VBox

fig = go.FigureWidget()
pie = fig.add_pie(values=[1, 2, 3])

out = Output()
@out.capture(clear_output=True)
def handle_click(trace, points, state):
    print(points.point_inds)

pie.on_click(handle_click)

VBox([fig, out])

pie_click

Hope that helps!
-Jon

1 Like

Thanks! Yes, that works for me as well. And seeing a successful example allowed me to identify what what I was doing to adapt the scatterplot example that wasn’t working.

I noticed two things that don’t work following the scatterplot example (that is, it will create plots, but the callback won’t fire on click):

  • iplot won’t work for a callback-based interactive pie chart (or at least, it doesn’t when I change the example only to use iplot rather than VBox).
  • it won’t work if I create the “pie” object with go.Pie instead of with fig.add_pie (as in: fig = go.FigureWidget([go.Pie(labels=labels, values=values)])).

I can move forward now with a working example, but I’m curious to understand these differences a bit better. Can someone help to explain the reason(s) for them? I’m new to using PlotLy, so it may just be that this isn’t clear to me because of my lack of familiarity with the programming model. Thanks!

Hi @tdonadio,

Glad you got it working!

iplot won’t work for a callback-based interactive pie chart (or at least, it doesn’t when I change the example only to use iplot rather than VBox).

This is correct, when a FigureWidget is displayed using iplot, the resulting view is not an ipywidget and so the events can’t be synced back to the Python side. A FigureWidget should be allowed to display itself (by being the last expression in an input cell), or it can be displayed using the ipywidgets.display method (See https://ipywidgets.readthedocs.io/en/stable/examples/Widget%20Basics.html#display()).

it won’t work if I create the “pie” object with go.Pie instead of with fig.add_pie (as in: fig = go.FigureWidget([go.Pie(labels=labels, values=values)])).

What’s happening here is that traces are copied when they are passed to figure constructors. So you do need to add a trace to the figure and then access it in order for the callbacks to be synced up. As an alternative to using the add_* methods, you can retrieve the trace from the figure’s data property. E.g.

fig = go.FigureWidget([go.Pie(labels=labels, values=values)]))
pie = fig.data[0]

Hope that helps clear things up a bit!
-Jon

1 Like

Hi, is there an example of click and select points in 3D scatter? !

I try to let “dragmode”:‘select’, but this method is not suitable for 3D scatter.

Hi @visual,

Unfortunately 3D point selection isn’t supported yet. See https://github.com/plotly/plotly.js/issues/3511 for initial discussion.

-Jon

I tried running the pie example above, but got the following error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-13-75f1733261e8> in <module>
     10     print(points.point_inds)
     11 
---> 12 pie.on_click(handle_click)
     13 
     14 VBox([fig, out])

AttributeError: 'FigureWidget' object has no attribute 'on_click'
1 Like

#try this on jupyter notebook. I don’t know why indentation doesn’t work

import plotly.graph_objects as go
import webbrowser

from ipywidgets import Output, VBox

import numpy as np
np.random.seed(1)

x = np.random.rand(100)
y = np.random.rand(100)

f = go.FigureWidget([go.Scatter(x=x, y=y, mode=‘markers’)])

scatter = f.data[0]
colors = [’#a3a7e4’] * 100
scatter.marker.color = colors
scatter.marker.size = [10] * 100
f.layout.hovermode = ‘closest’

create our callback function

out = Output()
@out.capture(clear_output=True)
def update_point(trace, points, selector):
c = list(scatter.marker.color)
s = list(scatter.marker.size)
for i in points.point_inds:
c[i] = ‘#bae2be
s[i] = 20
with f.batch_update():
scatter.marker.color = c
scatter.marker.size = s
webbrowser.open(‘http://example.com’)

scatter.on_click(update_point)
VBox([f, out])

Thanks for your reading.

I have some problems about click event in pie chart.
I fellow your post on jupyter notebook, it worked well!

But I want to run this not on jupyter notebook, on py file.

Could you let me know solution?

Warm Regards.
Take care

I can’t get the minimal example working, and I wonder if it’s because something broke with plotply-ipywidget integration or if it’s a configuration issue with my notebook setup (e.g. a missing extension). When I run this minimal example based on the pie chart example, it doesn’t render anything (neither the ipywidget nor the figure):

import ipywidgets as widgets
import plotly.graph_objects as go

fig = go.FigureWidget()
fig.add_pie(values=[1, 2, 3])
out = widgets.HTML()
out.value = 'hello'
widgets.VBox([out, fig])

I can render without including a plotly widget., e.g.:

import ipywidgets as widgets

out1 = widgets.HTML()
out2 = widgets.HTML()
out1.value = 'hello'
out2.value = 'world'
widgets.VBox([out1, out2])

I can render the FigureWidget with fig.show(), but I can’t capture events if I render that way.

plotly.version is 4.3.0
widgets.version is 7.5.1

Thanks!

Do you have an up to date version of the plotlywidget labextension installed as per https://plotly.com/python/getting-started/ ?

I would recommend updating everything to the latest versions: 4.8.2

Thanks for the reply, Nicolas! Unfortunately this is in a shared development environment where I may not be able to upgrade plotly in short order, but I may have more luck adding extensions.

I’m using a notebook platform based on Jupyter but not JupyterLab, and my understanding from the getting started guide is the plotlywidget extension is just for JupyterLab. Are there installation steps missing from the Jupyter Notebook Support section? https://plotly.com/python/getting-started/#jupyter-notebook-support

I notice in that section there isn’t a figure rendering below this code block, which is the same use case I’m having trouble with — is it exhibiting the same problem?

import plotly.graph_objects as go
fig = go.FigureWidget(data=go.Bar(y=[2, 3, 1]))
fig

So in Jupyter, the plotlywidget extension is loaded automatically, and in JupyterLab it must be installed manually. If you’re in a custom notebook platform, you’ll need to get the extension loaded in one way or the other to get widgets to work :slight_smile:

Can you provide more details on your notebook system? Is it Google Colab or SageMaker or something like that or from some smaller vendor?

Thanks so much, Nicholas. It’s a notebook platform built internally at my company, and I don’t know enough about its creation and development to be able to say more about how it differs. They’re now looking at getting plotlywidget to load properly.

It may take some time for them to get it working, and I need a temporary work-around to be able to do the demo I need (or switch to ggplot or matplotlib). Is there any way, even if very hacky, to capture click events on a figure rendered using show()? There’s clearly some mouse-to-figure communication going on because hovertext works. I would be grateful for a hint of where to hook into the code base with the understanding that I’m on my own from there. :slight_smile:

For catching click events within the notebook without using FigureWidgets I would recommend using https://github.com/plotly/jupyter-dash