Plot dcc graph on callback not working

Hi, this code (or very similar) used to work for me but for some odd reason it’s not working anymore and I have no idea why.

The basic logic is that I want to output a graph as part of a callback function.

"""
Test graph output as part of callback
"""


import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go


app = dash.Dash()
#app.css.append_css({'external_url': 'https://codepen.io/chriddyp/pen/dZVMbK.css'})
# Loading screen CSS
#app.css.append_css({"external_url": "https://codepen.io/dfernan/pen/MVOeGz.css"})


app.layout = html.Div(
    children=[
        html.H1(id='hola', children='TEST, GRAPH BELOW'),
        html.Div(id='graphs', children='')
    ]
)


@app.callback(
    dash.dependencies.Output('graphs', 'children'),
    [dash.dependencies.Input('hola', 'id')]
)
def update_graph(input_value):

    print (' I M HERE')
    print('I M OUT OF HERE' )

    a = dcc.Graph(
        figure=go.Figure(
            data=[
                go.Bar(
                    x=[1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
                       2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012],
                    y=[219, 146, 112, 127, 124, 180, 236, 207, 236, 263,
                       350, 430, 474, 526, 488, 537, 500, 439],
                    name='Rest of world',
                    marker=go.Marker(
                        color='rgb(55, 83, 109)'
                    )
                ),
                go.Bar(
                    x=[1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
                       2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012],
                    y=[16, 13, 10, 11, 28, 37, 43, 55, 56, 88, 105, 156, 270,
                       299, 340, 403, 549, 499],
                    name='China',
                    marker=go.Marker(
                        color='rgb(26, 118, 255)'
                    )
                )
            ],
            layout=go.Layout(
                title='US Export of Plastic Scrap',
                showlegend=True,
                legend=go.Legend(
                    x=0,
                    y=1.0
                ),
                margin=go.Margin(l=40, r=0, t=40, b=30)
            )
        ),
        style={'height': 300},
        id='my-graph'
    )

    print('I M OUT OF HERE AGAIN')
    return a


if __name__ == '__main__':
    app.run_server(host='0.0.0.0', port=8699, debug=True)

The output I see is:

image

Which only contains the H1 element, but not the graph, no idea why. I also get no warning and no error.

It looks like the issue is that the front end doesn’t know what a dcc.Graph is, since none existed on page load.
I’m seeing the following error stack in chrome’s javascript console when running your example unmodified:

bundle.js:14 Uncaught (in promise) Error: dash_core_components was not found.
    at Object.resolve (bundle.js:14)
    at s (bundle.js:14)
    at Array.map (<anonymous>)
    at s (bundle.js:14)
    at Array.map (<anonymous>)
    at s (bundle.js:14)
    at e.value (bundle.js:14)
    at p._renderValidatedComponentWithoutOwnerOrContext (react-dom.min.js:13)
    at p._renderValidatedComponent (react-dom.min.js:13)
    at p._updateRenderedComponent (react-dom.min.js:13)

Doing something like this in the initial layout will send the required code to the front end initially so it then knows how to handle a graph object later when your callback runs:

app.layout = html.Div(
    children=[
        html.H1(id='hola', children='TEST, GRAPH BELOW'),
        html.Div(id='graphs', children=dcc.Graph(id='dummy'))
    ]
)

Interesting. Thanks so much, you are the man! could this be considered a bug?

That’s a question for @chriddyp, but probably not. You wouldn’t want to burden the front end with the javascript for every kind of interface that your back end is capable of producing, so I’m sure the server does some work to figure out what’s needed and only send that. I’ve run into other places where it seems like trying to add novel content to the page out of the blue doesn’t work well, so I’d advise using the pattern of ‘placeholder and replace’ rather than pushing out totally new things.

1 Like

Yeah exactly. Ideally, we’d load these component files on the fly, this is reported here: Handle loading component suites dynamically · Issue #46 · plotly/dash-renderer · GitHub

1 Like