plotly / plotly/plotly.py

Explicit figure height replaced with autosize=True in callback

Open
#3,936 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug P3
Dominant language
Python
Stars
18.8k
Forks
2.8k
Avg merge
16h 26m
Merged PRs (30d)
21

Description

I'm creating a plotly express line chart and seeing an explicit height=300 being replaced with autosize=True in the layout when used as an Input or State to a callback. This causes size issues when trying to serialize the chart and load it back later.

I'm using Plotly 5.10.0, Dash 2.6.2 with Python 3.10.7.

The following demonstrates the problem.

import plotly.express as px
import dash
from dash import Dash, dcc, html, Output, Input, State
import dash_bootstrap_components as dbc


@dash.callback(
    Output("main-content", "children"),
    Output("loaded-values", "children"),
    Input("load-button", "n_clicks"),
    prevent_initial_call=True
)
def add_chart(clicks):
    df = px.data.stocks()
    df = df.melt(id_vars="date", value_name="price", var_name="stock")

    fig = px.line(
        df,
        x="date",
        y="price",
        color="stock",
        title="Stock Prices",
        height=300,
    )

    info = {
        "width": fig.layout.width,
        "height": fig.layout.height,
        "autosize": fig.layout.autosize,
    }

    return dcc.Graph(figure=fig, id="plot"), f"{clicks}: {info}"


@dash.callback(
    Output("callback-values", "children"),
    # Note: height=300 is seen when triggered by main-content, but autosize=True
    #  is seen when triggered by observe-button
    Input("observe-button", "n_clicks"),
    Input("main-content", "children"),
    prevent_initial_call=True
)
def observe_chart(clicks, content):
    ctx = dash.callback_context
    info = {}
    for k in ["width", "height", "autosize"]:
        try:
            info[k] = content["props"]["figure"]["layout"][k]
        except Exception as e:
            info[k] = None

    return f"{clicks}: {info}"


app = Dash(external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = dbc.Container([
    dbc.Button("Load", id="load-button", class_name="m-2"),
    dbc.Button("Observe", id="observe-button", class_name="m-2"),
    html.Br(),
    dbc.Label("Loaded Chart"),
    dbc.Container([], id="main-content"),
    dbc.Label("Loaded Layout Values"),
    dbc.Container(id="loaded-values"),
    dbc.Label("Callback Layout Values"),
    dbc.Container(id="callback-values"),
])
app.run_server(debug=True)

Click the "Load" button to "load" the chart. The layout parameters of interest will be shown under "Loaded Layout Values" and the "Callback Layout Values" will be correct. Then click the "Observe" button to update the "Callback Layout Values". Instead of a height=300 there will be an autosize=True.

With the explicit height being discarded the user selected size can't be serialized and loaded later...

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Run the supplied Python reproduction, focusing on the add_chart and observe_chart callbacks and the dcc.Graph figure passed between them. Compare the figure layout before and after callback serialization; done when an explicit height of 300 remains available in the observed callback data instead of being replaced by autosize=True.

Written by the indexing model from the issue text.

Assessment

Tech stack
plotly, python
Domain
api
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.