You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Plotly+ipywidgets回调函数外访问点击坐标列表?

解决Plotly FigureWidget点击点后无法访问clicked列表的问题

你遇到的问题是在Jupyter环境中,使用FigureWidget的点击回调更新clicked列表后,无法在回调外部访问或打印最新的列表内容。以下是几种可行的解决方法:

问题重现代码

import numpy as np
import plotly.graph_objects as go
import ipywidgets as widgets

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

# 构建图表
fig = go.FigureWidget(
    [go.Scatter(x=x, y=y, mode="markers", name="base_points")]
)
fig.update_layout(template="simple_white")

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

# 点击回调函数
@out.capture()
def base_click(trace, points, selector):
    global clicked
    clicked.append(points.__dict__)

fig.data[0].on_click(base_click)

widgets.HBox([fig, out])

解决方法

1. 添加按钮触发查看点击数据

通过添加一个按钮控件,点击按钮时将clicked列表的内容输出到out组件,这样可以随时获取最新的点击记录:

import numpy as np
import plotly.graph_objects as go
import ipywidgets as widgets

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

fig = go.FigureWidget(
    [go.Scatter(x=x, y=y, mode="markers", name="base_points")]
)
fig.update_layout(template="simple_white")

out = widgets.Output(layout={"border": "1px solid black"})
out.append_stdout("点击图表点后,点击下方按钮查看坐标数据\n")

# 回调函数:提取坐标并保存
def base_click(trace, points, selector):
    clicked.append({"x": points.xs[0], "y": points.ys[0]})

fig.data[0].on_click(base_click)

# 按钮点击事件:输出clicked列表
def show_clicked_data(b):
    with out:
        print("当前已点击的坐标列表:")
        print(clicked)

button = widgets.Button(description="查看点击数据")
button.on_click(show_clicked_data)

# 组装界面
widgets.VBox([widgets.HBox([fig, out]), button])

2. 在回调中直接输出坐标信息

修改回调函数,每次点击时直接将坐标数据输出到out组件,同时更新clicked列表,实现实时反馈:

import numpy as np
import plotly.graph_objects as go
import ipywidgets as widgets

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

fig = go.FigureWidget(
    [go.Scatter(x=x, y=y, mode="markers", name="base_points")]
)
fig.update_layout(template="simple_white")

out = widgets.Output(layout={"border": "1px solid black"})
out.append_stdout("点击图表点查看坐标数据\n")

@out.capture()
def base_click(trace, points, selector):
    coord = {"x": points.xs[0], "y": points.ys[0]}
    clicked.append(coord)
    print(f"新增点击坐标:{coord}")
    print(f"累计点击次数:{len(clicked)}")

fig.data[0].on_click(base_click)

widgets.HBox([fig, out])

3. 使用类封装状态(更规范的实现)

如果需要更复杂的交互逻辑,用类来封装点击状态和回调函数,避免使用global变量,代码结构更清晰:

import numpy as np
import plotly.graph_objects as go
import ipywidgets as widgets

class ClickCoordinateTracker:
    def __init__(self):
        self.clicked_coords = []
        # 初始化图表数据
        x = np.random.uniform(-10, 10, size=50)
        y = np.sin(x)
        # 创建图表
        self.fig = go.FigureWidget(
            [go.Scatter(x=x, y=y, mode="markers", name="base_points")]
        )
        self.fig.update_layout(template="simple_white")
        # 创建输出组件
        self.out = widgets.Output(layout={"border": "1px solid black"})
        self.out.append_stdout("点击图表点记录坐标,点击按钮查看所有数据\n")
        # 绑定点击回调
        self.fig.data[0].on_click(self._on_point_click)
        # 创建查看按钮
        self.view_button = widgets.Button(description="查看所有点击坐标")
        self.view_button.on_click(self._show_all_coords)
        # 组装界面
        self.ui = widgets.VBox([widgets.HBox([self.fig, self.out]), self.view_button])
    
    def _on_point_click(self, trace, points, selector):
        coord = {"x": points.xs[0], "y": points.ys[0]}
        self.clicked_coords.append(coord)
        with self.out:
            print(f"已记录坐标:{coord}")
    
    def _show_all_coords(self, b):
        with self.out:
            print("\n所有已记录的点击坐标:")
            print(self.clicked_coords)

# 实例化并显示界面
tracker = ClickCoordinateTracker()
tracker.ui

内容的提问来源于stack exchange,提问作者Raxhacks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 21:45:37