plotly/plotly.py

[BUG]: error_y.array renders error bars before initial render but not after Plotly.restyle

Open

#5.621 aberto em 8 de jun. de 2026

Ver no GitHub
 (2 comments) (0 reactions) (0 assignees)Python (2.467 forks)batch import
buggood first issuegood for agent

Métricas do repositório

Stars
 (14.684 stars)
Métricas de merge de PR
 (Mesclagem média 1d 7h) (7 fundiu PRs em 30d)

Description

Description

A scatter trace renders error_y.array differently depending on when the property is applied.

If error_y.array is set before the first render, vertical error bars are visible. If the same base figure is rendered first and the same error_y.array value is applied later with Plotly.restyle, the error bars are not shown.

Screenshots/Video

Steps to reproduce

import io

import pandas as pd
import plotly
import plotly.express as px
import plotly.io as pio
from PIL import Image, ImageChops
from playwright.sync_api import sync_playwright


print(f"Plotly version: {plotly.__version__}")


def make_fig():
    df = pd.DataFrame(
        {
            "x": [3.0, 3.2, 3.4],
            "y": [5.0, 4.8, 5.4],
            "color": [5.0, 4.8, 5.4],
        }
    )
    return px.scatter(
        df,
        x="x",
        y="y",
        color="color",
        color_continuous_scale=px.colors.sequential.Viridis,
    )


error_array = [0.0, 0.5, 1.0]

# Case 1: set error_y.array before the initial render.
fig1 = make_fig()
fig1.data[0].error_y.array = error_array
assert tuple(fig1.data[0].error_y.array) == tuple(error_array)
html1 = pio.to_html(fig1, full_html=True, include_plotlyjs=True)

# Case 2: render first, then apply the same value with Plotly.restyle.
fig2 = make_fig()
html2 = pio.to_html(fig2, full_html=True, include_plotlyjs=True)
html2 = html2.replace(
    "</body>",
    """
<script>
window.addEventListener("DOMContentLoaded", () => {
    const plotEl = document.getElementsByClassName("plotly-graph-div")[0];
    setTimeout(() => {
        Plotly.restyle(plotEl, {"error_y.array": [0.0, 0.5, 1.0]}, [0]);
    }, 1000);
});
</script>
</body>""",
)

with sync_playwright() as playwright:
    browser = playwright.chromium.launch(
        headless=True,
        args=["--no-sandbox", "--disable-dev-shm-usage", "--disable-gpu"],
    )
    page = browser.new_page(viewport={"width": 1200, "height": 800})

    page.set_content(html1, wait_until="domcontentloaded")
    page.wait_for_timeout(1500)
    img1 = page.screenshot(path="plot1.png")

    page.set_content(html2, wait_until="domcontentloaded")
    page.wait_for_timeout(2000)
    img2 = page.screenshot(path="plot2.png")

    browser.close()

diff = ImageChops.difference(
    Image.open(io.BytesIO(img1)).convert("RGB"),
    Image.open(io.BytesIO(img2)).convert("RGB"),
)

print("Saved plot1.png (Python-side before render)")
print("Saved plot2.png (JS-side restyle after render)")
assert diff.getbbox() is not None, "Reproducer did not reproduce: images are identical."
print("Bug reproduced: the two renderings differ.")

Notes

Add info here that doesn't fit in the other sections.

Guia do colaborador