Подсвечник и линейный график в Da sh Plotly, который обновляется с помощью обратного вызова, но исчезает - PullRequest
0 голосов
/ 30 марта 2020

Я пытаюсь показать график Candlestick и график Line в одном графике. Я пытаюсь обновить их с помощью обратного вызова, чтобы проверить наличие новых обновлений в CSV-файле. Они оба отображаются правильно, пока не сработает обратный вызов. После этого линейный график все еще отображается, но график свечей становится невидимым. Когда я изменяю размер или увеличиваю масштаб, график отображается правильно, пока не будет выполнен обратный вызов. Как правильно настроить фигуру с несколькими графиками (Candlestick и Line Graph) на другой оси Y с работающей функцией обратного вызова.

Вот рисунок, который показывает, что происходит: enter image description here

Это мой код:

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)

Я сравнил вывод функции обратного вызова в первый раз и во второй раз. Они оказываются точно такими же.

1 Ответ

0 голосов
/ 30 марта 2020

Поскольку кажется, что только после второго обратного вызова график исчезает и обратный вызов возвращает точно такой же показатель (с теми же данными и той же разметкой), мы можем проверить, изменились ли данные (или последний индекс). Если оно не изменилось, вы можете вызвать исключение PreventUpdate в обратном вызове. Таким образом, обратный вызов выполняется только один раз и только в случае добавления новых данных.

Внутри обратного вызова graph_update мы можем сделать следующее:

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()
...