How do you populate charts with data on clicking button in Dash with python?

I am experimenting with Dash/Plotly. I can’t work out how to populate charts with data on the click of a button. I know that if I pass the same thing I am returning from my callbacks directly to the figure argument in the app layout the chart works. I know that I can get the callback to change the text of a heading. I hit the submit button and the chart doesn’t change. Here is my code:

app = dash.Dash(__name__, assets_external_path=assets)

app.layout = html.Div(children=[

    html.Div(className='parent', children=[

        html.Div(className='pD', children=[

           dcc.Dropdown(id='size', options=[
                {'label': 'Small', 'value': 'small'},
                {'label': 'Medium', 'value': 'medium'},
                {'label': 'Large', 'value': 'large'}
            ])

        ]),

        html.Div(className='submit', children=[

            html.Button('Submit', id='submit', n_clicks=0)

        ]),

        html.Div(className='graph_box cD', children=[dcc.Graph(id='graph')])

    ]),

])

@app.callback(
    Output('graph', 'figure'),
    [Input('submit', 'n_clicks')],
    [State('size', 'value')]
)
def update_chart(clicks, size):
    if clicks > 1:        
        return {'data': [{'x': np.random.randint(0, 100, 1000), 'type': 'histogram'}]}

app.run_server(debug=False, port=8000)

Hi @TaxpayersMoney
First I would recommend turning “app.run_server(debug=False)” to TRUE. That would sometimes give you a hint of the problem. In this case, it said:

Cannot read property ‘data’ of null

If you google that term with the keywords Dash, plotly, forum, you would find the answer, which is:

Your callback doesn’t return anything if clicks <=1. This means figure gets a null value. There are different ways to solve this. But most importantly, you should instruct the “update_chart” function to do something if clicks <=1.

For example I added the ELSE section:

def update_chart(clicks, size):
    if clicks > 1:
        return {'data': [{'x': np.random.randint(0, 100, 1000), 'type': 'histogram'}]}
    else:
        return {'data': [{'x': np.random.randint(0, 100, 2000), 'type': 'histogram'}]}

Hope this helps.
Adam,

1 Like