[英]Plotly Conditional on_click
有沒有辦法為控制另一個的 function `on_click 設置條件語句? 我打算做以下事情:
我原以為使用條件fake_click_check
語句會起作用,但它沒有做任何事情。 我想一旦我可以修復這個當前的條件語句(以及如何將它們與on_click
一起使用),我將能夠執行 rest 的步驟。
@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)
clicks=len(fig.to_dict()['data'][2]['x'])
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
if (clicks==2):
fict_x1=float(fig.to_dict()['data'][2]['x'][0])
fict_x2=float(fig.to_dict()['data'][2]['x'][2])
fict_x_start=np.minimum(fict_x1,fict_x2)
fict_x_end=np.maximum(fict_x1,fict_x2)
fict_x=np.arange(fict_x_start,fict_x_end,0.1)
x_len=fict_x.size
fict_y1=float(fig.to_dict()['data'][2]['y'][0])
fict_y2=float(fig.to_dict()['data'][2]['y'][2])
fict_y_start=np.minimum(fict_y1,fict_y2)
fict_y_end=np.maximum(fict_y1,fict_y2)
fict_y_tick=(fict_y_end-fict_y_start)/x_len
fict_y=np.arange(fict_y_start,fict_y_end,fict_y_tick)
new_point.update(x=fict_x,y=fict_y)
fake_click_check=1
if (clicks > 2):
line.update(x=[],y=[])
scatter.marker.color=['#a3a7e4']*100
scatter.marker.size=[10]*100
out.clear_output
@out.capture()
def set_new_point(trace,points,selector):
fake_click=len(fig.to_dict()['data'][2]['x'])
if (fake_click_check < 1):
if (fake_click>1):
c = list(new_point.marker.color)
s = list(new_point.marker.size)
fake_click_check=fake_click_check+1
for i in points.point_inds:
c[i]='#bae2be'
s[i]=20
with fig.batch_update():
new_point.marker.color = c
new_point.marker.size = s
scatter.on_click(update_point)
if (fake_click_check==1):
new_point.on_click(set_new_point)
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
import ipywidgets as widgets
x = np.random.uniform(-10, 10, size=50)
y = np.sin(x)
# construct figure that has holders for points, interpolated line and final lines
fig = go.FigureWidget(
[
go.Scatter(x=x, y=y, mode="markers", name="base_points"),
go.Scatter(name="points", mode="markers", marker={"size": 20}),
go.Scatter(name="interp", showlegend=False),
go.Scatter(name="lines", line={"color": "orange"}, mode="lines"),
]
)
fig.update_layout(template="simple_white")
out = widgets.Output(layout={"border": "1px solid black"})
out.append_stdout("Output appended with append_stdout\n")
# interpolated line between first two selected points
@out.capture()
def line_click(trace, points, selector):
# print(trace.name, points.xs, points.ys)
if len(points.xs) == 1 and len(fig.data[1].x) == 2:
t = fig.data[1]
t.update(x=list(t.x) + points.xs, y=list(t.y) + points.ys)
# create our callback function
@out.capture()
def base_click(trace, points, selector):
# print(trace.name, points.xs, points.ys)
if len(points.xs) == 0:
return
if fig.data[1].x is None: # first point
t = fig.data[1]
t.update(x=points.xs, y=points.ys)
elif len(fig.data[1].x) in [1, 3]: # second and fourth point
t = fig.data[1]
t.update(x=list(t.x) + points.xs, y=list(t.y) + points.ys)
if len(fig.data[1].x) == 2:
# need a set of points so click events work on second points
xx = np.linspace(*fig.data[1].x, 20)
yy = np.interp(xx, fig.data[1].x, fig.data[1].y)
t = fig.data[2]
t.update(x=xx, y=yy, marker={"size": 2}, mode="markers")
else: # fourth point create the lines
# use order of points to construct wanted lines
fig.data[3].update(
x=np.array(fig.data[1].x)[[0, 3, 3, 2, 3, 1]],
y=np.array(fig.data[1].y)[[0, 3, 3, 2, 3, 1]],
)
fig.data[0].on_click(base_click)
fig.data[2].on_click(line_click)
reset = widgets.Button(description="Reset")
@out.capture()
def on_reset_clicked(b):
# line.update(x=[], y=[])
fig.data[1].update(x=None, y=None)
fig.data[2].update(x=None, y=None)
fig.data[3].update(x=None, y=None)
out.clear_output()
reset.on_click(on_reset_clicked)
widgets.VBox([widgets.HBox([reset]), widgets.HBox([fig, out])])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.