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

Plotly中点击按钮更新手绘线条颜色及获取绘制结果的方法

问题解决:Plotly手绘标注颜色切换与数据获取

一、修复手绘线条颜色切换按钮

你代码里第二个按钮用了restyle方法,这是错的——newshape_line_color属于布局(layout)属性,得用relayout方法才能生效。另外要提醒你:按钮切换的是之后新画线条的颜色,已经画好的线条不会自动变颜色(要是想改已有的线条,得遍历fig.layout.shapes逐个更新)。

修正后的按钮代码:

fig.update_layout(
    updatemenus=[
        dict(
            type="buttons",
            direction="right",
            active=0,
            showactive=True,
            x=0.57,
            y=1.2,
            buttons=list([
                {
                    'label': "红色",
                    'method': "relayout",
                    'args': [{'newshape_line_color': 'red'}],
                },
                {
                    'label': "蓝色",
                    'method': "relayout",
                    'args': [{'newshape_line_color': 'blue'}],
                },
            ]),
        )
    ])

二、无需手动保存获取手绘线条数据

要是想在Python里实时拿到手绘数据,别用普通的Figure,换成plotly.graph_objects.FigureWidget就行,它支持事件监听,画完线条就能自动捕获数据。

示例代码:

import plotly.graph_objects as go
import plotly.express as px
import cv2

# 读取图片,注意转成RGB格式(cv2默认读出来是BGR)
img = cv2.imread(fpath)
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 使用FigureWidget替代普通Figure
fig_widget = go.FigureWidget(px.imshow(img_rgb).data)
fig_widget.update_layout(
    dragmode='drawopenpath',
    newshape_line_color='cyan',
    modebar_add=['drawopenpath', "eraseshape"]
)

# 加上颜色切换按钮
fig_widget.update_layout(
    updatemenus=[
        dict(
            type="buttons",
            direction="right",
            active=0,
            showactive=True,
            x=0.57,
            y=1.2,
            buttons=list([
                {'label': "红色", 'method': "relayout", 'args': [{'newshape_line_color': 'red'}]},
                {'label': "蓝色", 'method': "relayout", 'args': [{'newshape_line_color': 'blue'}]},
            ]),
        )
    ])

# 定义监听函数,线条变化时自动输出数据
def on_shape_change(trace, update_dict, selector):
    # 获取所有手绘线条的数据
    all_shapes = fig_widget.layout.shapes
    print("当前手绘线条数据:")
    for i, shape in enumerate(all_shapes):
        print(f"线条 {i+1}:")
        print(f"  类型: {shape.type}")
        print(f"  坐标路径: {shape.path}")  # 手绘线条的坐标存在path属性里
        print(f"  线条颜色: {shape.line.color}")

# 绑定事件,线条增删改都会触发这个函数
fig_widget.layout.on_change(on_shape_change, 'shapes')

# 显示交互图
fig_widget

运行之后,每次画线条、删线条,控制台都会自动打印对应的线条数据,不用手动保存。

要是你用Dash做Web应用,还能通过dcc.Graph的relayoutData属性来捕获手绘数据,实现更复杂的交互逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 15:10:42