Black Lives Matter. Please consider donating to Black Girls Code today.

Live Chart on dash tab

I am writing simple app with Dash and I have problem with making the live graph. I have made two tabs and want to display the live graph on one of them. I made an index.py file with basic layout:

app.layout = html.Div(
    [
    #header
    html.Div([
        html.Span("Automation for Binance", className='app-title'),

    ],
    className='row header',
    ),
    html.Div([

            dcc.Tabs(
                id="tabs",
                style={"height":"20","verticalAlign":"middle"},
                children=[
                    dcc.Tab(label="Analysis", value="analysis_tab"),
                    dcc.Tab(label="Settings", value="settings_tab"),
                ],
                value="analysis_tab",
            )

            ],
            className="row tabs_div"
            ),

    html.Div(id="tab_content", className="row", style={"margin": "2% 3%"}),
    ])


@app.callback(Output("tab_content", "children"), [Input("tabs", "value")])
def render_content(tab):
    if tab == "analysis_tab":
        return analysis.layout
    elif tab == "settings_tab":
        return html.Div([
            html.H3('Tab content 1')
        ])
    else:
        return analysis.layout

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

In the same directory as index.py I made apps folder with __init__.py and 2 files for each tab as external apps, here is my file for first tab analysis.py:

colors = {
    'background': '#111111',
    'text': '#7FDBFF'
}

def candlestick_chart(df):
    trace = go.Candlestick(x=df.Date,
                       open=df.Open,
                       high=df.High,
                       low=df.Low,
                       close=df.Close)

    layout = go.layout(
        xaxis=dict(range=[df.Date[-30], df.Date[-1]]),
        plot_bgcolor=colors['background'],
        paper_bgcolor=colors['background'],
        font=dict(color=colors['text']),
    )

    return {'data':[trace], 'layout': layout,}


layout = [
    html.Div([
        html.Div(
            dcc.Graph(
                id="price-graph",
                style={"height": "90%", "width": "98%"},
            ),
            dcc.Interval(
                id="graph-update",
                interval=4000,
            )
        )
    ])
]

@app.callback(Output('price-graph', 'figure'),
            events=[Event('graph-update', 'interval')])
def update_graph(df):
    df = manager.get_candles('BTCUSDT', '1m')
    return candlestick_chart(df)

Now my problem is that when I run my app all what I get is empty candlestick chart with no data. And in the console I don’t even see auto updating POST responses. When I was trying to make “test chart” without tabs just one file and callback everything worked perfectly now it doesn’t even try to update or download data.

What Am I doing wrong?

I’m not 100% sure, but I think part of the issue is you are outputting to the to the children of tabs and not tab. Here is a snippet of my code where I use tabs to display different data:

app.layout = html.Div(
        [dcc.Interval(id='interval-component', interval=20_000),
         dcc.Tabs(id="tabs",
                  children=[
                      dcc.Tab(label='AMER', id='status-tab-amer'),
                      dcc.Tab(label='EMEA', id='status-tab-emea'),
                      dcc.Tab(label='APAC', id='status-tab-apac'),
                      ])
                  ]
        )

@app.callback(
        output=dash.dependencies.Output('status-tab-amer', 'children'),
        inputs=[dash.dependencies.Input('interval-component', 'n_intervals')])
def update_tab_amer(n_intervals):
    ...

Switching tabs works well for me, if I click analysis tab it renders empty graph but does not update data and does not even try to update anything from analysis.py callback

hmmm, reading your code more carefully I notice that you’re using the obsolete “events” argument and your callback has no inputs:

@app.callback(Output('price-graph', 'figure'),
            events=[Event('graph-update', 'interval')])
def update_graph(df):
    df = manager.get_candles('BTCUSDT', '1m')
    return candlestick_chart(df)

Does this fix it?

@app.callback(Output('price-graph', 'figure'),
            inputs=[Input('graph-update', 'n_intervals')])
def update_graph(n_intervals):
    df = manager.get_candles('BTCUSDT', '1m')
    return candlestick_chart(df)

It doesn’t work. But When I am using something like this:

 app.layout = html.Div(style={'backgroundColor': colors['background']},children=[
        html.H1(children='Some candlestick chart',
                style={
                'textAlign': 'center',
                'color': colors['text']
            }),

        html.Div(children='''
            Graph
        ''',
            style={
                'textAlign': 'center',
                'color': colors['text']
            }),

        dcc.Graph(
            id='graph',
            animate=False,

        ),
        dcc.Interval(
            id='graph-update',
            interval=4000
        )
    ])
    @app.callback(Output('graph', 'figure'),
                  events=[Event('graph-update', 'interval')])
    def update_graph():
                     df = manager.get_candles('BTCUSDT', '1m')
                     return candlestick_chart(df)

Everything same except not using tabs and separete .py files and chart works perfect and refreshes every 4 sec

I deleted 1 html.Div from analysis.py and it started to work… Anyways thanks for your help :slight_smile:

1 Like