3

I'm currently trying to bring in some data through np, do some processing on that initial data, plot it, but then be interactive with my plot. Plotly has a tutorial of how to take the plot and change the color of the data points (in jupyter using the click event https://plotly.com/python/click-events/). What I'm hoping to do is be able to take the click event click on 2 points and then create a line between the points selected and gather my positions of the line. The only thing I have found in plotly is just hovering over the data but not being able to do this processing. Is there a better way of doing this rather than using plotly? The documentation on plotly is suggesting to just use dash, but I haven't found a way of doing this with dash. The follow-up question would be how do I get this data if I export my plot (fig.write_html)?

Sample of what I have is:

import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt

# Import libraries
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go


x=np.random.uniform(-10,10,size=50)
y=np.sin(x)

fig=go.FigureWidget([go.Scatter(x=x, y=y, mode='markers')])

fig.update_layout(template='simple_white')

scatter=fig.data[0]
colors=['#a3a7e4']*100
scatter.marker.color=colors
scatter.marker.size=[10]*100
fig.layout.hovermode='closest'

fig.update_traces(marker=dict(line=dict(color='DarkSlateGrey')))

# create our callback function
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 fig.batch_update():
            scatter.marker.color=c
            scatter.marker.size=s

scatter.on_click(update_point)

fig

1 Answer 1

5
  • given you attempted example is ipwidgets I have extended this
  • create an empty trace that will be target for lines
  • for debugging create widgets.Output()
  • now just a case of creating UI using HBox() and VBox()
  • for now have demonstrated how you can export by printing to stdout. This clearly could save the JSON to a file
# Import libraries
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
import json
import ipywidgets as widgets

x=np.random.uniform(-10,10,size=50)
y=np.sin(x)

fig=go.FigureWidget([go.Scatter(x=x, y=y, mode='markers'), go.Scatter(x=[], y=[], mode="lines")])

fig.update_layout(template='simple_white')

scatter=fig.data[0]
line = fig.data[1]
colors=['#a3a7e4']*100
scatter.marker.color=colors
scatter.marker.size=[10]*100
fig.layout.hovermode='closest'

fig.update_traces(marker=dict(line=dict(color='DarkSlateGrey')))

out = widgets.Output(layout={'border': '1px solid black'})
out.append_stdout('Output appended with append_stdout\n')

# create our callback function
@out.capture()
def update_point(trace, points, selector):
    x = list(line.x) + points.xs
    y = list(line.y) + points.ys
    line.update(x=x, y=y)
scatter.on_click(update_point)

reset = widgets.Button(description="Reset")
export = widgets.Button(description="Export")

@out.capture()
def on_reset_clicked(b):
    line.update(x=[], y=[])
    out.clear_output()
@out.capture()
def on_export_clicked(b):
    print(fig.to_dict()["data"][1])

reset.on_click(on_reset_clicked)
export.on_click(on_export_clicked)

widgets.VBox([widgets.HBox([reset, export]), widgets.VBox([fig, out])])

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! This worked perfectly! Do you know if there's a way to have this functionality if I try to create my plot in a pop out window instead of inline from jupyter?
I've not used ipwidgets extensively, but would suspect not. if you used dash and callbacks from it I would expect pop outs to work

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.