我被困在一个部分,我想通过两种方式更新批次下拉列表。如果在材料下拉列表中没有选择任何内容,批次下拉列表应该显示所有批次,但一旦选择材料,它应该更改为只显示该材料类型的批次。
下面是相关代码现在的样子:
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()]
当前发生的是批次下拉菜单显示所有批次值,即使选择了材料值,也不会动态更改
1条答案
按热度按时间2ic8powd1#
动态下拉实时更新
编辑(2023年2月):* 原始答案的简化代码,现在还演示了可选 * Dash
dcc.Dropdown
multi=True
* 参数 * 的使用。*两个UI下拉菜单元素。第一个是硬编码的,是一个可能的"材料"选项列表,对应于唯一的"批次"的子集(这里简单地表示为具有#'s 1 - 100的总批次集合)。每种材料通过从总集合(即,这里为
total_batches
)中抽取50次(即,k=50
)来随机取样而不进行替换。* 用户选择的多个选项(
multi=True
)如果用户从第一个下拉列表中选择了多个材料选项,则只有在所有选定子集中找到的那些批次将立即在第二个"批次"下拉列表中动态更新(使用
set.intersection()
在集-投列表的列表上计算[即,材料选定批次子集])。请注意,每次添加另一个用户选择的选项时,动态同步的第二个下拉列表将更改为显示更新的相应"批处理"(在这种情况下,每个选项["材料"]具有值= 50个从范围1 - 100中唯一随机采样的整数)并且如预期的那样,随着每个进一步选项("材料")的添加,随机采样子集之间存在相当大的(尽管在减少)交集。
(最终,在这个特定的模拟示例中,碰巧在每个可能的"材料"选项中随机抽取了3个批次ID #。)
Stderr报告示例(来自上面记录和显示的实时样本模拟)
原始答案(不使用
multi=True
参数)注:即使不需要用户从第一个下拉列表中选择多个选项(在这种情况下,只需进行更改:将
multi=False
设置为定义的应用布局中的dcc.Dropdown
参数。下面是一个基于您的代码的演示,展示了如何使批处理下拉列表动态地依赖于在物料下拉列表中选择的内容。
我是这么做的: