web-dev-qa-db-ja.com

Dlot by Plotlyで複数の出力を実行するためのより良い方法はありますか?

はじめにのインタラクティブ機能 で確認できるように、1つのコールバック関数は複数の入力を受け入れることができますが、常に単一の出力を持ちます。

入力の変更後に更新する必要がある2つのブロックが別々にあると想定します。もちろん、最も簡単な方法は、ブロックごとに同じ入力で2つのコールバックを作成することです。問題は、リクエストが2回実行される一方で、1つですべてのデータを取得できることです。

@app.callback(
    dash.dependencies.Output('element_1', 'children'),
    [dash.dependencies.Input('filter', 'value')])
def callback_element_1(filter):
    return get_data(filter).el1

@app.callback(
    dash.dependencies.Output('element_2', 'children'),
    [dash.dependencies.Input('filter', 'value')])
def callback_element_2(filter):
    return get_data(filter).el2

私が見つけた解決策は、これらの要素を単一のブロックでラップし、単一のリクエストで完全に再レンダリングすることです。ただし、この場合、特に初期要素がDOMで互いに離れている場合は、ラッパー内のすべての静的コンテンツも更新されます。

@app.callback(
    dash.dependencies.Output('wrapper', 'children'),
    [dash.dependencies.Input('filter', 'value')])
def callback_element_wrapper(filter):
    data = get_data(filter)
    return html.Div(
        children=[
            data.el1,
            # more static content
            data.el2,
        ]
    )

たぶん、単一のリクエストで2つ以上の要素に出力するよりエレガントな方法があるでしょうか?

10

現在、Plotly Dashは1つのイベントで複数の出力をサポートしています。これはdash == 0.38.0rc1の最新バージョンです。

enter code `@app.callback([Output('output1', 'children'), Output('output2', 'children')],
          [Input('output-btn', 'n_clicks')],
          [State('output-btn', 'n_clicks_timestamp')])
def on_click(n_clicks, n_clicks_timestamp):
    if n_clicks is None:
        raise PreventUpdate

return n_clicks, n_clicks_timestamp`

Gitサンプル

4
Dimuthu

this に基づいて、方法があります。

実行できることは、非表示の「信号要素」(これはたとえばテキスト入力である場合があります)を更新することです。これにより、2つの主要な要素が更新されます。

get_data(filter)を1回実行し、結果をグローバル変数に格納します。次に、element_1およびelement_2を更新する代わりに、その信号要素を更新します。

result = []

@app.callback(
dash.dependencies.Output('signal', 'value'),
[dash.dependencies.Input('filter', 'value')])
def callback_signal(filter):
    global result
    result = get_data(filter)
    return filter

@app.callback(
dash.dependencies.Output('element_1', 'children'),
[dash.dependencies.Input('signal', 'value')])
def callback_element_1(filter):
    return result.el1


@app.callback(
dash.dependencies.Output('element_2', 'children'),
[dash.dependencies.Input('signal', 'value')])
def callback_element_2(filter):
    return result.el2

私の場合、シングルユーザー環境でDashを使用しており、グローバル変数の使用は問題になりませんでした。同時にアプリを実行する複数のユーザーがいる場合、代わりの方法が利用可能であり、同じリンクでそれらを見つけることができます。

4
Gimmly

外部の関数でアクションリスナーを構成できるとしたらどうでしょうか?オレーの例を使う

def setup_action_callbacks(app):
    result = []

    @app.callback(
    dash.dependencies.Output('signal', 'value'),
    [dash.dependencies.Input('filter', 'value')])
    def callback_signal(filter):
        result = get_data(filter)
        return filter

    @app.callback(
    dash.dependencies.Output('element_1', 'children'),
    [dash.dependencies.Input('signal', 'value')])
    def callback_element_1(filter):
        return result.el1


    @app.callback(
    dash.dependencies.Output('element_2', 'children'),
    [dash.dependencies.Input('signal', 'value')])
    def callback_element_2(filter):
        return result.el2

そのような:

def get_app_layout(app):
    setup_action_callbacks(app)
    return html.Div()

app = DjangoDash(name="a_Nice_name", app_name="a_Nice_app_name")
app.layout = get_app_layout(app)
1
kanarelo

マルチ出力コールバックのサポートがDashに統合されました(2019/03/01)。

1
TomDLT