簡體   English   中英

如何使用不同的下拉菜單更新 plotly 圖表破折號

[英]How to update a plotly graph dash with different dropdowns

我正在嘗試使用兩個不同的下拉列表作為輸入來更新 plotly 圖表破折號。

這是我的樣品 dataframe:

import pandas as pd
df1 = {'category' : ['A','A','A','B','B','B'],'subcategory' : ['x', 'y', 'z', 'x1','y1','z1'],
      'x_coord' : [1, 2,3,2,2,2],'y_coord' : [1,3,2,1,3,2]}

df_test = pd.DataFrame(df1)
df_test

在此處輸入圖像描述

And what I pretend to do is if I select category A, that plots in a scatter all the correspondent points to the category, but If Also I select a subcategory that modifies the graph plotting only the correspondent category-subcategory point of the dataframe.

代碼如下,如果我只添加第一個下拉列表的回調,它就可以工作,但是當我將第二個回調添加到子類別時它不起作用。 我遵循破折號 plotly 教程中的建議,其中說:

 A word of caution: it's not always a good idea to combine Outputs, even if you can: If the Outputs depend on some but not all of the same Inputs, keeping them separate can avoid unnecessary updates. If they have the same Inputs but do independent computations with these inputs, keeping the callbacks separate can allow them to run in parallel.

Dash 文檔回調

但無論如何,如果我將 output 放在單獨的回調中或在同一個回調中,我無法使其工作,這是我正在嘗試的代碼(使用 jupyter notebook):

import dash
import plotly as py
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objects as go
from jupyter_plotly_dash import JupyterDash
py.offline.init_notebook_mode(connected = True)

app = JupyterDash('Test')

app.layout = html.Div([
    dcc.Dropdown(id='dropdown1',
                 options=[{'label':i, 'value':i} for i in df_test['category'].unique()]),
    dcc.Dropdown(id='dropdown2',
                 options=[{'label':i, 'value':i} for i in df_test['subcategory'].unique()]),
    dcc.Graph(id='graphic')
])

@app.callback(
    Output('dropdown2', 'options'),
    [Input('dropdown1', 'value')])

def update_drop2(selected_drop):
    filtered_df = df_test[(df_test.category == selected_drop)]
    return [{'label':i, 'value':i} for i in filtered_df['subcategory'].unique()]

@app.callback(
    Output('graphic', 'figure'),
    [Input('dropdown1', 'value')])

def update_figure(selected_drop):

    filtered_df = df_test[(df_test.category == selected_drop)]

    fig = go.Figure()

    fig.add_trace(go.Scatter(x=filtered_df.x_coord,y=filtered_df.y_coord, marker = dict(size=15, color='green'), mode='markers'))

    return fig


@app.callback(
    Output('graphic', 'figure'),
    [Input('dropdown2', 'value')])

def update_figure(selected_drop):

    filtered_df = df_test[(df_test.subcategory == selected_drop)]

    fig = go.Figure()

    fig.add_trace(go.Scatter(x=filtered_df.x_coord,y=filtered_df.y_coord, marker = dict(size=15, color='green'), mode='markers'))

    return fig

app

如果我像這樣在回調中使用多個輸入:

@app.callback(
Output('graphic', 'figure'),
[Input('dropdown1', 'value'), Input('dropdown2', 'value')])

def update_figure(selected_drop1, selected_drop2):

    if not selected_drop2:
        filtered_df = df_test[(df_test.category == selected_drop1)]
    else: 
        filtered_df = df_test[(df_test.category == selected_drop1) & 
                      (df_test.subcategory == selected_drop2)]
    fig = go.Figure()

    fig.add_trace(go.Scatter(x=filtered_df.x_coord,y=filtered_df.y_coord, 
    marker = dict(size=15, color='green'), mode='markers'))

    return fig

它效果更好(或更接近我假裝的效果),但是當我在類別之間切換時,我看不到任何數據。

提前感謝您的幫助和建議。

我有一個類似的問題,訣竅是在第二個下拉列表中添加一個選項all 然后我想在第二個下拉列表中只顯示給定類別中的子類別。 所以我實際上為下拉菜單使用了 2 個回調,為 plot 使用了 1 個回調。

應用程序.py

import pandas as pd
import os
import plotly.graph_objs as go
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

df = pd.DataFrame({'category' : ['A','A','A','B','B','B'],
                   'subcategory' : ['x', 'y', 'z', 'x1','y1','z1'],
                   'x_coord' : [1, 2,3,2,2,2],
                   'y_coord' : [1,3,2,1,3,2]})

# lists of categories
options1 = sorted(df["category"].unique().tolist())

# dictionary of category - subcategories
all_options = df.groupby("category")["subcategory"].unique()\
                .apply(list).to_dict()

# we add as first subcategory for each category `all`
for k, v in all_options.items():
    all_options[k].insert(0, 'all')


app = dash.Dash()
app.layout = html.Div([
    dcc.Dropdown(
        id='first-dropdown',
        options=[{'label': k, 'value': k} for k in all_options.keys()],
        value=options1[0]
    ),

    html.Hr(),

    dcc.Dropdown(id='second-dropdown'),

    html.Hr(),

    dcc.Graph(id='display-selected-values')
])

# the following two callbacks generate a dynamic 2 option

@app.callback(
    dash.dependencies.Output('second-dropdown', 'options'),
    [dash.dependencies.Input('first-dropdown', 'value')])
def set_2_options(first_option):
    return [{'label': i, 'value': i} for i in all_options[first_option]]


@app.callback(
    dash.dependencies.Output('second-dropdown', 'value'),
    [dash.dependencies.Input('second-dropdown', 'options')])
def set_2_value(available_options):
    return available_options[0]['value']


@app.callback(
    dash.dependencies.Output('display-selected-values', 'figure'),
    [dash.dependencies.Input('first-dropdown', 'value'),
     dash.dependencies.Input('second-dropdown', 'value')])
def update_graph(selected_first, selected_second):
    if selected_second == 'all':
        ddf = df[df["category"]==selected_first]
    else:
        ddf = df[(df["category"]==selected_first) &
                 (df["subcategory"]==selected_second)]

    fig = go.Figure()
    fig.add_trace(
        go.Scatter(x=ddf["x_coord"],
                   y=ddf["y_coord"],
                   marker = dict(size=15, color='green'),
                   mode='markers'))
    return fig

if __name__ == '__main__':
    app.run_server(debug=True, port=8051)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM