Skip to content

[BUG]: FigureWidget: layout.shapes not updated after drawing a path in JupyterLab #5689

Description

@eugenekwaNeuromics

Description

When attempting to enable draw closed paths on a plotly.graph_objects.FigureWidget, I noticed that there was an issue when attempting to delete the existing drawn paths. It seems that while fig.layout.to_plotly_json().get("shapes") is able to detect the path drawn, this information is not relayed to fig.layout.shapes. This can be fixed by manually editing fig.layout.to_plotly_json().get("shapes"), plugging it into fig.layout.shapes, and then deleting. The manual edits are to remove the <object object at 0x000001BFE6411440> that is assigned to both "name" and "legendwidth".

Steps to reproduce

import plotly.graph_objects as go
import ipywidgets as widgets
from IPython.display import display

fig = go.FigureWidget(
    go.Heatmap(
        z=[[1, 2], [3, 4]],
        showscale=False,
    )
)

fig.update_layout(
    dragmode="drawclosedpath",
    newshape=dict(
        line=dict(color="red", width=2)
    )
)

fail_clear_button = widgets.Button(description="Clear ROI (Fails)")
working_clear_button = widgets.Button(description="Clear ROI (Works)")
out = widgets.Output() 

def clear_roi(_):
    with out:
        print("layout.shapes:", fig.layout.shapes)
        print("JSON shapes:", fig.layout.to_plotly_json().get("shapes"))
        with fig.batch_update():         
            fig.layout.shapes = []
        print("After update_layout")
        print("layout.shapes:", fig.layout.shapes)
        print("JSON shapes:", fig.layout.to_plotly_json().get("shapes"))

def clear_roi_alt(_):
    with out:
        print("layout.shapes:", fig.layout.shapes)
        print("JSON shapes:", fig.layout.to_plotly_json().get("shapes"))
        json_shapes = fig.layout.to_plotly_json().get("shapes", [])
        for s in json_shapes:
            s['legendwidth'] = 0
            s['name'] =  ''
        fig.layout.shapes = json_shapes
        print("After pulling from JSON")
        print("layout.shapes:", fig.layout.shapes)
        print("JSON shapes:", fig.layout.to_plotly_json().get("shapes"))
        fig.layout.shapes = []
        print("After clearing")
        print("layout.shapes:", fig.layout.shapes)
        print("JSON shapes:", fig.layout.to_plotly_json().get("shapes"))

fail_clear_button.on_click(clear_roi)
working_clear_button.on_click(clear_roi_alt)

display(widgets.VBox([fail_clear_button, working_clear_button, fig, out]))

Notes

Python: 3.12.13
Plotly: 6.9.0
JupyterLab: 4.5.6
ipywidgets: 8.1.8
OS: Windows-11-10.0.26100-SP0

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions