我正在尝试使用两个不同的下拉菜单作为输入来更新一个绘图图破折号。
这是我的示例数据框:
const loginsSchema = new mongoose.Schema({
displayName:{
type:String,
required:true,
},
serviceId:{
required:true,
type:String,
unique:true
}
})
const logins = mongoose.model('logins',loginsSchema);
module.exports = logins;
const usersSchema = new mongoose.Schema({
userName: {
type: String,
required: true,
},
email: {
type: String,
unique: true,
},
user: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'logins',
unique: true
}
})
我假装要做的是,如果选择类别A,则将所有对应点散布在该类别中,但如果选择“另类”,则选择一个子类别,该子类别修改仅绘制该类别的对应类别-子类别点的图形数据框。
代码在下面,如果我仅添加第一个下拉列表的回调,它就可以工作,但是当我将第二个回调添加到子类别时,它将不起作用。 我遵循仪表板虚线教程中的建议:
const usersSchema = new mongoose.Schema({ name1: { type: String, required: true, }, name2: { type: String, unique: true, }, emailref: { /// reference the username schema with the email property instead of the objectId } })
但是无论如何,如果我将输出放在单独的回调中或放在相同的回调中,则无法使其正常工作,这是我正在尝试的代码(使用jupyter笔记本):
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
如果我在回调上使用多个输入,例如:
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.
它的效果更好(或更接近我的假想),但是当我在类别之间切换时,我看不到任何数据。
预先感谢您的帮助和建议。
答案 0 :(得分:1)
我遇到了类似的问题,技巧是在第二个下拉列表中添加一个选项all
。然后,我想在第二个下拉列表中仅显示给定类别中的子类别。所以我实际上使用2个回调进行下拉菜单,使用1个回调进行绘制。
app.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)