🚀 Gen 5 of the leading AI app deployment platform launches October 6. Click for the livestream.

Inconsistent Callback Error Updating Scatter Plot

Hey everyone,

I’m having a hard time determining the source of a callback error as it only occurs a small percentage of times during app initialization. The error can occur for any of my graphs but I’ve shared the relevant code for the simplest callback below.

import dash
import dash_html_components as html
import pandas as pd
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate
import numpy as np
import plotly_express as px


# =Set color scheme for all plots=
plot_color = "plotly"


app = dash.Dash(
    __name__,
    # external_stylesheets=external_stylesheets,
    # suppress_callback_exceptions=True,
)

app.layout = html.Div(
    html.Div(
        id="simulator-graph-zone",
        className="six columns",
        children=[
            html.H6(
                html.Span(
                    "Range Simulator",
                    id="simulator-tooltip-target",
                    style={"textDecoration": "underline", "cursor": "pointer",},
                ),
                className="graph-title",
            ),
            dbc.Tooltip("Test", target="simulator-tooltip-target", placement="right",),
            html.Div(
                [
                    html.P("Input nameplate battery capacity in kWh:",),
                    dcc.Input(
                        id="simulator-graph-input",
                        type="number",
                        placeholder="Nameplate Capacity (kWh)",
                        value=350,
                        min=10,
                        max=1000,
                        step=5,
                        style={"width": 220},
                    ),
                ],
                id="simulator-header",
                # className="seven columns",
            ),
            html.Br([]),
            html.Div(id="simulator-graph-container", className="pretty_container",),
        ],
    ),
)


def range_simulator(batt_capacity):
    # Makes range projections based on capacity and efficiency on a scatterplot
    nameplate_energy_capacity = batt_capacity
    usable_energy_capacity = (
        0.8 * nameplate_energy_capacity
    )  # assuming 80% usable energy
    set_efficiencies = np.linspace(1, 4, 7)
    vehicle_range = usable_energy_capacity / set_efficiencies
    vehicle_range_df = pd.DataFrame(vehicle_range, columns=["Range"])
    vehicle_range_df.insert(1, "Efficiency", set_efficiencies)
    range_graph = px.scatter(
        vehicle_range_df,
        x="Range",
        y="Efficiency",
        title=f"Vehicle Range Simulator ({usable_energy_capacity} kWh Usable)",
        labels={
            "Range": "Range (miles)",
            "Efficiency": "Vehicle Efficiency (kWh/mile)",
        },
        template=plot_color,
    )

    return range_graph


@app.callback(
    Output("simulator-graph-container", "children"),
    [Input("simulator-graph-input", "value"),],
)
def input_to_simulator(batt_capacity):
    if batt_capacity == None:
        raise PreventUpdate
    else:
        range_graph = range_simulator(batt_capacity)

    return dcc.Graph(id="simulator-graph", figure=range_graph)


if __name__ == "__main__":
    app.run_server(debug=True)

Here is the traceback:

Traceback (most recent call last):
File “/Users/fieldmichael/projects/cte/dashboards/zebra/app.py”, line 1053, in input_to_simulator
range_graph = range_simulator(batt_capacity)
File “/Users/fieldmichael/projects/cte/dashboards/zebra/app.py”, line 363, in range_simulator
range_graph = px.scatter(
File “/Users/fieldmichael/projects/cte/dashboards/zebra/conda-env/lib/python3.8/site-packages/plotly/express/_chart_types.py”, line 64, in scatter
return make_figure(args=locals(), constructor=go.Scatter)
File “/Users/fieldmichael/projects/cte/dashboards/zebra/conda-env/lib/python3.8/site-packages/plotly/express/_core.py”, line 1824, in make_figure
apply_default_cascade(args)
File “/Users/fieldmichael/projects/cte/dashboards/zebra/conda-env/lib/python3.8/site-packages/plotly/express/_core.py”, line 906, in apply_default_cascade
args[“symbol_sequence”] = [
File “/Users/fieldmichael/projects/cte/dashboards/zebra/conda-env/lib/python3.8/site-packages/plotly/express/_core.py”, line 907, in
scatter.marker.symbol for scatter in args[“template”].data.scatter
File “/Users/fieldmichael/projects/cte/dashboards/zebra/conda-env/lib/python3.8/site-packages/plotly/graph_objs/scatter/_marker.py”, line 1032, in symbol
return self[“symbol”]
File “/Users/fieldmichael/projects/cte/dashboards/zebra/conda-env/lib/python3.8/site-packages/plotly/basedatatypes.py”, line 3896, in getitem
elif self._props is not None and prop in self._props:
File “/Users/fieldmichael/projects/cte/dashboards/zebra/conda-env/lib/python3.8/site-packages/plotly/basedatatypes.py”, line 3595, in _props
return self.parent._get_child_props(self)
File “/Users/fieldmichael/projects/cte/dashboards/zebra/conda-env/lib/python3.8/site-packages/plotly/basedatatypes.py”, line 3609, in _get_child_props
if self._props is None:
File “/Users/fieldmichael/projects/cte/dashboards/zebra/conda-env/lib/python3.8/site-packages/plotly/basedatatypes.py”, line 3595, in _props
return self.parent._get_child_props(self)
File “/Users/fieldmichael/projects/cte/dashboards/zebra/conda-env/lib/python3.8/site-packages/plotly/basedatatypes.py”, line 3629, in _get_child_props
child_ind = BaseFigure._index_is(children, child)
File “/Users/fieldmichael/projects/cte/dashboards/zebra/conda-env/lib/python3.8/site-packages/plotly/basedatatypes.py”, line 3410, in _index_is
raise ValueError(“Invalid value”)
ValueError: Invalid value

The function is always passed an initial value of 350 so I can not figure out what could be causing the seemingly random ValueError. It occurs roughly 1/20 times during app initialization and does not seem to have any relation to the order in which the callbacks are fired. Any help is greatly appreciated, thank you!

Hi @bigmike did you manage to resolve?
Facing the same issue

Looking back, I’m still not entirely sure what caused the issue as I ended up making some major changes to the structure of my app. I believe it has something to do with the initialization of the app, how default values are passed to your callbacks, and the order in which callbacks are fired on load. This link goes into some of the complexities of callback initialization.

I ended up setting prevent_initial_call=True and triggering this callback with the output of a separate callback. Sorry I could not be of more help!

HI @Math did you manage to find any solutions to this? I am struggling with the same problem.

Hi @lutherrichards I did not find the source of the issue, I settled for a simple try and except logic to catch the error and try again once more. For me it always works on second trial so I left it as such

Ahh okay that’s smart. Mine has similar behaviour, so I will give it a go. Thanks @Math

1 Like

Hi everyone!
I am struggling with this issue too. Anybody found any resolution or at least any causes of that error?