Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
robertcollar-kobold opened this issue Dec 7, 2024 · 8 comments · Fixed by #4956
Assignees
Labels
bug something broken P1 needed for current cycle

Comments

@robertcollar-kobold
Copy link

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

@gvwilson gvwilson added bug something broken P1 needed for current cycle labels Dec 9, 2024
@marthacryan
Copy link
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
Copy link
Author

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

@robertcollar-kobold
Copy link
Author

robertcollar-kobold commented Dec 10, 2024

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
Copy link
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
Copy link
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
Copy link
Author

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

@robertcollar-kobold
Copy link
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
Copy link
Collaborator

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug something broken P1 needed for current cycle
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants