Skip to content

Erratic behavior when working with multiple FigureWidget instances (after adoption of anywidget?) #4933

Closed
@robertcollar-kobold

Description

@robertcollar-kobold

Hey Plotly team!

I had just created an issue about images failing with the new FigureWidget. However, I've come to realize that the issue is more nuanced (and general) than previously noted and so thought I'd close that issue and open a new one.

An image can be added to an instance of a FigureWidget, but only to the first instance; an image cannot be added to a second. The same goes for heatmaps. Slightly different behavior, though still unexpected, is observed for bars. I suspect this erratic behavior is associated with the adoption of anywidget (PR #4823).

Consider the following examples (run from a classic jupyter notebook in Chrome):

Example 1a: successful addition of image to two FigureWidget instances (expected behavior, pre-anywidget)

plotly v5.24.1
anywidget not installed
notebook v7.3.1

run the cell below twice

import plotly.graph_objects as go

fig = go.FigureWidget()
# Add an image to the figure
fig.add_layout_image(
    dict(
        source="https://raw.githubusercontent.com/cldougl/plot_images/add_r_img/vox.png",
        xref="x",
        yref="y",
        x=1,
        y=1,
        sizex=1,
        sizey=1, 
        xanchor="center",
        yanchor="middle"
    )
)
fig.show()

first output:
Image

second output:
Image

Example 1b: unsuccessful addition of image to two FigureWidget instances (unexpected behavior, post-anywidget)

plotly v6.0.0rc0
anywidget v0.9.13
notebook v7.3.1

run the cell below twice

import plotly.graph_objects as go

fig = go.FigureWidget()
# Add an image to the figure
fig.add_layout_image(
    dict(
        source="https://raw.githubusercontent.com/cldougl/plot_images/add_r_img/vox.png",
        xref="x",
        yref="y",
        x=1,
        y=1,
        sizex=1,
        sizey=1, 
        xanchor="center",
        yanchor="middle"
    )
)
fig.show()

first output:
Image

second output:
Image

Example 2a: successful addition of heatmap to two FigureWidget instances (expected behavior, pre-anywidget)

plotly v5.24.1
anywidget not installed
notebook v7.3.1

run the cell below twice

import plotly.graph_objects as go

fig1 = go.FigureWidget()

fig1.add_trace(go.Heatmap(
                    z=[[1, 20, 30],
                      [20, 1, 60],
                      [30, 60, 1]]))
fig1.show()

first output:
Image

second output:
Image

Example 2b: unsuccessful addition of heatmap to two FigureWidget instances (unexpected behavior, post-anywidget)

plotly v6.0.0rc0
anywidget v0.9.13
notebook v7.3.1

run the cell below twice

import plotly.graph_objects as go

fig1 = go.FigureWidget()

fig1.add_trace(go.Heatmap(
                    z=[[1, 20, 30],
                      [20, 1, 60],
                      [30, 60, 1]]))
fig1.show()

first output:
Image

second output:
Image

Example 3a: successful addition of bars to two FigureWidget instances (expected behavior, pre-anywidget)

plotly v5.24.1
anywidget not installed
notebook v7.3.1

run the cell below twice

import plotly.graph_objects as go

animals=['giraffes', 'orangutans', 'monkeys']

fig1 = go.FigureWidget([go.Bar(x=animals, y=[20, 14, 23])])
fig1.show()

first output
Image

second output
Image

Example 3b: discrepancy in addition of bars to two FigureWidget instances (uexpected behavior, post-anywidget)

plotly v6.0.0rc0 (after anywidget added as dependency)
anywidget v0.9.13
notebook v7.3.1

run the cell below twice

import plotly.graph_objects as go

animals=['giraffes', 'orangutans', 'monkeys']

fig1 = go.FigureWidget([go.Bar(x=animals, y=[20, 14, 23])])
fig1.show()

first output
Image

second output
Image

I suspect that, for an experienced Plotly developer, the change in the last example might be diagnostic (fingers crossed).

Of note, this issue doesn't arise when adding multiple datasets to the same FigureWidget instance; consider the following:

Example 4: (expected behavior, post-anywidget)

plotly v6.0.0rc0
anywidget v0.9.13
notebook v7.3.1

cell 1

import plotly.graph_objects as go
fig = go.FigureWidget()
# Add an image to the figure
fig.add_layout_image(
    dict(
        source="https://raw.githubusercontent.com/cldougl/plot_images/add_r_img/vox.png",
        xref="x",
        yref="y",
        x=1,
        y=1,
        sizex=1,
        sizey=1, 
        xanchor="center",
        yanchor="middle"
    )
)
fig.show()

cell 2

fig.add_trace(go.Heatmap(
                    z=[[1, 20, 30],
                      [20, 1, 60],
                      [30, 60, 1]]))
fig.show()

cell 3

# Add an image to the figure
fig.add_layout_image(
    dict(
        source="https://images.plot.ly/language-icons/api-home/python-logo.png",
        xref="x",
        yref="y",
        x=2,
        y=2,
        sizex=1,
        sizey=1, 
        xanchor="center",
        yanchor="middle"
    )
)
fig.show()

Image

Any ideas on why having multiple FigureWidget instances would cause such erratic behavior following the adoption of anywidget?

This is the official end of the issue, but I had gone through some additional examples and have included them below in case they're of use:

Example 5a: successful addition of image to both FigureWidget instances (expected behavior, pre-anywidget)

plotly v5.24.1
anywidget not installed
notebook v7.3.1

cell 1

import plotly.graph_objects as go

# Create a Plotly figure
fig1 = go.FigureWidget()

# Add an image to the figure
fig1.add_layout_image(
    dict(
        source="https://raw.githubusercontent.com/cldougl/plot_images/add_r_img/vox.png",
        xref="x",
        yref="y",
        x=1,
        y=1,
        sizex=1,
        sizey=1, 
        xanchor="center",
        yanchor="middle"
    )
)
fig1.show()

Image

cell 2

# Create a Plotly figure
fig2 = go.FigureWidget()

# Add an image to the figure
fig2.add_layout_image(
    dict(
        source="https://images.plot.ly/language-icons/api-home/python-logo.png",
        xref="x",
        yref="y",
        x=1,
        y=1,
        sizex=1,
        sizey=1, 
        xanchor="center",
        yanchor="middle"
    )
)
fig2.show()

Image

Example 5b: unsuccessful addition of image to first FigureWidget instance but not second (unexpected behavior, post-anywidget)

plotly v6.0.0rc0
anywidget v0.9.13
notebook v7.3.1

cell 1

import plotly.graph_objects as go
fig1 = go.FigureWidget()
# Add an image to the figure
fig1.add_layout_image(
    dict(
        source="https://raw.githubusercontent.com/cldougl/plot_images/add_r_img/vox.png",
        xref="x",
        yref="y",
        x=1,
        y=1,
        sizex=1,
        sizey=1, 
        xanchor="center",
        yanchor="middle"
    )
)
fig1.show()

Image

cell 2

# Create a Plotly figure
fig2 = go.FigureWidget()

# Add an image to the figure
fig2.add_layout_image(
    dict(
        source="https://images.plot.ly/language-icons/api-home/python-logo.png",
        xref="x",
        yref="y",
        x=1,
        y=1,
        sizex=1,
        sizey=1, 
        xanchor="center",
        yanchor="middle"
    )
)
fig2.show()

Image

Example 6a: successful addition of image to second FigureWidget instance regardless of data added to first FigureWidget instance (expected behavior, pre-anywidget)

plotly v5.24.1
anywidget not installed
notebook v7.3.1

cell 1

import plotly.graph_objects as go

fig1 = go.FigureWidget(data=go.Heatmap(
                    z=[[1, 20, 30],
                      [20, 1, 60],
                      [30, 60, 1]]))
fig1.show()

Image

cell 2

import plotly.graph_objects as go

# Create a Plotly figure
fig2 = go.FigureWidget()

# Add an image to the figure
fig2.add_layout_image(
    dict(
        source="https://raw.githubusercontent.com/cldougl/plot_images/add_r_img/vox.png",
        xref="x",
        yref="y",
        x=1,
        y=1,
        sizex=1,
        sizey=1, 
        xanchor="center",
        yanchor="middle"
    )
)
fig2.show()

Image

Example 6b: unsuccessful addition of image to second FigureWidget instance regardless of data added to first FigureWidget instance (unexpected behavior, post-anywidget)

plotly v6.0.0rc0
anywidget v0.9.13
notebook v7.3.1

cell 1

import plotly.graph_objects as go

fig1 = go.FigureWidget(data=go.Heatmap(
                    z=[[1, 20, 30],
                      [20, 1, 60],
                      [30, 60, 1]]))
fig1.show()

Image

cell 2

# import plotly.graph_objects as go
fig2 = go.FigureWidget()
# Add an image to the figure
fig2.add_layout_image(
    dict(
        source="https://raw.githubusercontent.com/cldougl/plot_images/add_r_img/vox.png",
        xref="x",
        yref="y",
        x=1,
        y=1,
        sizex=1,
        sizey=1, 
        xanchor="center",
        yanchor="middle"
    )
)
fig2.show()

Image

Activity

added
bugsomething broken
P1needed for current cycle
on Dec 9, 2024
marthacryan

marthacryan commented on Dec 9, 2024

@marthacryan
Collaborator

Thank you for this detailed bug report! I'm looking into this now. I am seeing what you're seeing with rerunning the cells.

One behavior I'm already seeing is that if you restart the kernel before re-running the cell, this bug doesn't occur (still a bug, just noting this for debugging).

robertcollar-kobold

robertcollar-kobold commented on Dec 9, 2024

@robertcollar-kobold
Author

@marthacryan great! Happy to provide support where it'd be of use :)

robertcollar-kobold

robertcollar-kobold commented on Dec 10, 2024

@robertcollar-kobold
Author

Hi @marthacryan, I've observed some new, potentially positive behavior. If I first create an instance of go.Figure and then convert it to a go.FigureWidget , the documented problem does not occur. Strange!

Example:
Run the below in a cell as many times as you'd like 🥳

import plotly.graph_objects as go

# Create a Plotly figure
fig = go.Figure()

# Add an image to the figure
fig.add_layout_image(
    dict(
        source="https://images.plot.ly/language-icons/api-home/python-logo.png",
        xref="x",
        yref="y",
        x=1,
        y=1,
        sizex=1,
        sizey=1, 
        xanchor="center",
        yanchor="middle"
    )
)

fig = go.FigureWidget(fig)

fig
robertcollar-kobold

robertcollar-kobold commented on Dec 11, 2024

@robertcollar-kobold
Author

Update: I've corrected the above example; fig = go.FigureWidget(fig) must happen after adding the image for this band-aid solution to work

marthacryan

marthacryan commented on Jan 7, 2025

@marthacryan
Collaborator

@robertcollar-kobold Thank you again for making this detailed bug report! I've added a PR (#4956) that fixes it for me in all of your examples. Do you mind trying it out to make sure that it's working for you too? You can use this command to install that branch: pip install https://output.circle-artifacts.com/output/job/4a9ab984-cdcf-49b5-b45e-75482d4d912f/artifacts/0/packages/python/plotly/dist/plotly-6.0.0rc0+24.g11154b1cc.tar.gz

robertcollar-kobold

robertcollar-kobold commented on Jan 9, 2025

@robertcollar-kobold
Author

Sure! I'll give it a shot first thing tomorrow.

robertcollar-kobold

robertcollar-kobold commented on Jan 9, 2025

@robertcollar-kobold
Author

@marthacryan Woohoo! All the previously misbehaving examples now behave as expected. Thank you for your efforts here; from the PR, it clearly took some sleuthing to nail down the issue!

marthacryan

marthacryan commented on Jan 9, 2025

@marthacryan
Collaborator

@robertcollar-kobold Thank you for trying that out! It should go into the next release.

iisakkirotko

iisakkirotko commented on Feb 21, 2025

@iisakkirotko

Hey @marthacryan! Just wanted to cross-link to an issue with anywidget. I think this issue is still affecting non-Jupyter environments that might use widgets, since it isn't guaranteed that _repr_mimebundle is called in them. At least, it was still affecting Solara. Either way, manzt/anywidget#804 should address the issue at its root.

I haven't tested if the solution in #4956 is still needed afterwards, and while I suspect it might not be, it's of course good to keep around to support earlier versions of anywidget, should manzt/anywidget#804 be merged.

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

Metadata

Metadata

Assignees

Labels

P1needed for current cyclebugsomething broken

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    Participants

    @gvwilson@iisakkirotko@marthacryan@robertcollar-kobold

    Issue actions

      Erratic behavior when working with multiple FigureWidget instances (after adoption of anywidget?) · Issue #4933 · plotly/plotly.py