#python #dynamic #callback #tabs #plotly-dash
Вопрос:
В настоящее время я создаю приложение dash с 1-50-ю вкладками. Я намерен использовать это в качестве гибкого инструмента визуализации для различных биологических наборов данных, и количество вкладок зависит от набора данных (рассматриваемые биологические данные могут быть разделены на группы, поэтому в каждой группе есть одна вкладка).
Проблема в том, что я не уверен, как организовать приложение — все примеры, похоже, имеют дело с тем, когда вы знаете, сколько вкладок вы получите (чего я не знаю, так как данные могут иметь разное количество групп и, следовательно, вкладок). Я думаю, что, возможно, мне следует связать обратные вызовы, чтобы определить, какая вкладка открыта (что-то вроде метода 1), а затем обновить графики, связанные с этой вкладкой, но я не уверен, что есть лучший способ.
Есть какие-нибудь предложения? Пожалуйста, обратите внимание на ошибки в приложении ниже, так как количество входов в функцию обратного вызова равно Nx ожидаемому числу, где N — количество групп. Это связано с тем, что я не знаю, как организовать функцию обратного вызова для конкретной вкладки 🙁
Спасибо! Тим
df = biological_dataframe
types = set(list(chain.from_iterable(df['groups_column'])))
app = dash.Dash(__name__)
app.layout = html.Div([
#one tab per biological 'group'
dcc.Tabs([
dcc.Tab(label=f'{typ}',
children=[
dcc.Graph(id = f'{typ}_id2'),
dcc.Graph(id = f'{typ}_id3'),
dcc.Graph(id = f'{typ}_id4'),
dcc.Slider(id=f'{typ}_id5',
#.....other params
),
dcc.Slider(id=f'{typ}_id6',
#.....other params
),
dcc.Slider(id=f'{typ}_id7',
#.....other params
),
]
)
for typ in types] )])
#lotsss of inputs/outputs
@app.callback(
list(chain.from_iterable([[Output(f'{typ}_id2', 'figure'),
Output(f'{typ}_id3', 'figure'),
Output(f'{typ}_id4', 'figure')]
for typ in types])),
list(chain.from_iterable([[Input(f'{typ}_id5', 'value'),
Input(f'{typ}_id6', 'value'),
Input(f'{typ}_id7', 'value'),
Input(f'{typ}_id1', 'value')]
for typ in types]))
)
def update_figure(num_res, num_bio, diversity_val):
scope_df = copy.deepcopy(df)
filtered_df = #filtered df based on slider vals, deleting to save space
scope_df['filtered'] = True
scope_df['filtered'][filtered_df.index] = False
fig1 = px.pie(filtered_df,
values='interesting_vals_1',
names='interesting_names_1')
fig2 = px.pie(filtered_df,
values='interesting_vals_2',
names='interesting_names_2')
fig3 = px.pie(scope_df,
values='interesting_vals_3',
names='interesting_names_3')
fig1.update_layout(transition_duration=500)
fig2.update_layout(transition_duration=500)
fig3.update_layout(transition_duration=500)
return fig1, fig2, fig3
if __name__ == '__main__':
app.run_server(debug=True)