【发布时间】:2021-11-08 13:44:02
【问题描述】:
我被困在我想以两种方式更新批处理下拉列表的部分。如果在材料下拉列表中没有选择任何内容,则批次下拉列表应显示所有批次,但一旦选择了材料,它应更改为仅显示该材料类型的批次。
这是相关代码现在的样子:
import dash
from dash import dcc
from dash import html
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd
import re
app = dash.Dash(__name__)
# Convert PARQUET to CSV
df = pd.read_csv("release_cln.csv")
# Store all unique values from Basis column
df_dis = df[df['Analysis_Name_CLN'].str.contains("Dissolution").fillna(False)]
df_dis['Batch'] = df_dis['Batch'].fillna(9999)
df_dis['Basis'] = df_dis['Batch'].fillna(9999)
df_dis['Material'] = df['Material'].fillna(9999)
batch = df_dis['Batch'].unique()
material = df_dis['Material'].unique()
basis = df_dis['Basis'].unique()
#[{'label': i, 'value': i} for i in material]
app.layout = html.Div([
html.H1(children='Comparing Batches'),
html.H2('Dissolution vs Timepoint'),
# Batch 1 Dropdowns
html.Div([
html.Div(
html.H3(children='''DP Batch''')
),
html.Div([
html.Div(children='''Batch: '''),
dcc.Dropdown(
id='batch_dd',
multi=False,
clearable=True,
disabled=False
),
],style={'width': '20%','display': 'inline-block'}
),
html.Div([
html.Div(children='''Material: '''),
dcc.Dropdown(
id='material_dd',
multi=False,
clearable=True,
disabled=False
),
],style = {'width': '15%','display': 'inline-block'}
),
html.Div([
html.Div(children='''Basis: '''),
dcc.Dropdown(
id='basis_dd',
multi=False,
clearable=True,
disabled=False
),
],style = {'width': '15%','display': 'inline-block'}
),
html.Div([
html.Div(children='''Variant: '''),
dcc.Dropdown(
id='variant_dd',
multi=False,
clearable=True,
disabled=False
),
],style = {'width': '10%','display': 'inline-block'}
),
html.Div([
html.Div(children='''Analysis: '''),
dcc.Dropdown(
id='analysis_name_dd',
multi=False,
clearable=True,
disabled=False,
options=[]
),
],style = {'width': '40%','display': 'inline-block'}
)
],style = {'width': '90%', 'display': 'inline-block'}
),
html.Br(),
# Batch 2 Dropdowns
html.Div([
html.Div(
html.H3(children='''DS Batch''')
),
html.Div([
html.Div(children='''Batch: '''),
dcc.Dropdown(
id='batch_dd_1',
multi=False,
clearable=True,
disabled=False,
options=[{'label': i, 'value': i} for i in batch]
),
],style={'width': '20%','display': 'inline-block'}
),
html.Div([
html.Div(children='''Material: '''),
dcc.Dropdown(
id='material_dd_1',
multi=False,
clearable=True,
disabled=False,
options=[],
),
],style = {'width': '15%','display': 'inline-block'}
),
html.Div([
html.Div(children='''Basis: '''),
dcc.Dropdown(
id='basis_dd_1',
multi=False,
clearable=True,
disabled=False,
options=[]
),
],style = {'width': '15%','display': 'inline-block'}
),
html.Div([
html.Div(children='''Variant: '''),
dcc.Dropdown(
id='variant_dd_1',
multi=False,
clearable=True,
disabled=False,
options=[]
),
],style = {'width': '10%','display': 'inline-block'}
),
html.Div([
html.Div(children='''Analysis: '''),
dcc.Dropdown(
id='analysis_name_dd_1',
multi=False,
clearable=True,
disabled=False,
options=[]
),
],style = {'width': '40%','display': 'inline-block'}
)
],style = {'width': '90%', 'display': 'inline-block'}
),
html.Br(),
dcc.Graph(id='dissol_tp')
])
## Batch 1 Dropdowns
#Call back to update Batch options if user searches for Batches
@app.callback(
Output('batch_dd','options'),
[Input('batch_dd','search_value'),
Input('material_dd','value')]
)
def batch_options(search_value, material_dd):
if material_dd is None:
return [{'label': i, 'value': i} for i in batch]
else:
batch_df = df[df['Material']==material_dd]
return [{'label':i,'value':i} for i in batch_df['Batch'].fillna('None').unique()]
@app.callback(
Output('material_dd','options'),
Input('material_dd','search_value'))
def material_options(search_value):
return [{'label': i, 'value': i} for i in material]
# Callback to select default value in basis list
@app.callback(
Output('basis_dd','options'),
Input('basis_dd','search_value'))
def variant_default(batch_dd):
return [k['value'] for k in batch_dd]
# Chained callback to select variants with the selected batch
@app.callback(
Output('variant_dd','options'),
Input('batch_dd','value'))
def get_variant(batch_dd):
batch_df = df[df['Batch']==batch_dd]
return [{'label':i,'value':i} for i in batch_df['Variant'].fillna('None').unique()]
当前发生的情况是批次下拉列表显示所有批次值,即使选择了材料值并且不会动态更改
【问题讨论】:
-
缺少 'material_dd' 的选项,它们似乎是静态的,不像 'batch_dd',因此您可以通过在相应的 dcc.Dropdown 中添加
options=[{'label':i,'value':i} for i in material]在 app.layout 中直接定义它们。 -
我添加了一个回调来更新材料下拉列表,我会更新问题。目前发生的情况是,批次正在更新所有值,当我选择任何材料时没有任何反应
-
我建议创建一个最小的示例来重现问题并且可以按原样运行,从而更容易调试。在您共享的代码中,顺便说一句,您没有正确导入
dash_html_components和dash_core_components。 -
尝试从
batch_options回调中删除Input('batch_dd','search_value')(未使用)。可能是更新 'batch_dd' 选项会触发同一组件的 'search_value' 事件,在这种情况下,您使用 'search_value' 为 'batch_dd' 重新输入相同的回调(即使它是无),但没有值'material_dd'(因为只有一个组件触发回调)。如果您打算同时使用批量 search_value 和 material_dd 值作为输入,则需要检查 material_dd 的State 以获取实际值。
标签: python pandas plotly-dash