✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
⚡️ Concerned about the grid? Kyle Baranko teaches how to predicting peak loads using XGBoost. Register for the August webinar!

Candlestick and line graph in one graph shows, but updates with callback and disappears

I am trying to show a candlestick graph and a line graph in one graph. I try to update them via a callback, to check for new updates in a csv file. They both show up correctly until the callback is fired. After this, the line graph shows but the candlestick graph disappears. When I resize or zoom, the graph shows up correctly till it fires the callback again. How should I correctly set up a figure with multiple graphs (Candlestick and Line Graph) on a different y axis, with a working callback function.

Here is a gif to show what is happening:

This is my code:

df_btc = pd.read_csv("data/livedata.csv")
    
app = dash.Dash(__name__)
app.layout = html.Div(
    [
        html.Div([
            dcc.Graph(id='live_graph', animate=True, style={"height": "100vh"}),
            dcc.Interval(
               id='interval_component',
               interval=2000,
            ),
        ]),
    ],
    style = {"height": "100vh"}
)
    
@app.callback(Output('live_graph', 'figure'),
     [Input('interval_component', 'n_intervals')])
def graph_update(n):
     df_btc = pd.read_csv("data/livedata.csv")

     ...
     (parsing the data and making lists, asuming this works as it shows up initially)
     ...        

     graph_candlestick = go.Candlestick(x=list(btc_date),
                                open=list(btc_open),
                                high=list(btc_high),
                                low=list(btc_low),
                                close=list(btc_close),
                                xaxis="x",
                                yaxis="y",
                                visible=True)
    
     graph_rsi = get_rsi(df_btc)
     return {'data': [graph_rsi, graph_candlestick], 'layout': go.Layout(xaxis=dict(range=[min(btc_date),max(btc_date)]),
                                                    yaxis=dict(range=[min(btc_low),max(btc_high)],),
                                                    yaxis2=dict(range=[0,100], overlaying='y', side='right'),) }
    
def get_rsi(df_btc):

    ...
    (calculating the data and making lists, asuming this works as it shows up initially)
    ...

    return go.Scatter(x=list(rsi_date),
                            y=list(rsi),
                            xaxis="x1",
                            yaxis="y2",
                            visible=True,
                            showlegend=False)
    
if __name__ == '__main__':
    app.run_server(debug=True)

I hope someone can help.

As it seems that only after the second callback the graph disappears and the callback returns exactly the same figure (with the same data and the same layout), we can check if the data (or the last index) has changed. If it did not change, you can throw an PreventUpdate exception in the callback. In this way the callback only runs once, and only when new data is to be appended. This prevents the second graph from disappearing for some reason.

Inside the callback graph_update we can do the following:

prevIndex = ""
...
def graph_update(n):
    global prevIndex
    data = pd.read_csv("data/livedata.csv")
    if (data["index"].iloc[-1] != prevIndex):
        prevIndex = data["index"].iloc[-1]
        ...
        return {...}
    else:
        raise dash.exceptions.PreventUpdate()

hello, i tried this but isn’t working, you managed to find another solution?