Есть несколько вопросов относительно добавления опции выбора всех для фильтрации данных с многочисленными значениями с использованием тире. Список ссылок ниже выполняет эту функцию, но добавляет каждое значение в раскрывающуюся панель. Вместо одной вкладки или компонента, который представляет все значения. Это делает макет приложения неработоспособным, поскольку страница заполнена значениями в раскрывающейся панели.
Было бы конструктивно, если бы вместо перечисления всех отдельных значений можно было использовать одну метку (все/выбрать все и т. д.).
Раскрывающийся список Python Plotly Dash Добавление «выбрать все» для диаграммы рассеяния
Как показано ниже, когда выбрано «Выбрать все», каждое значение отображается в раскрывающемся списке. В идеале, когда выбран select all, в раскрывающемся меню должна отображаться только метка select all, а все данные должны быть видны.
Кроме того, если select all присутствует как одна вкладка и пользователь хочет просмотреть уникальный идентификатор, то select all следует удалить для этого идентификатора. И наоборот, если выполняется действие с уникальным идентификатором и выполняется select all, то этот уникальный идентификатор следует удалить для одной вкладки select all. Это должно быть сделано за один шаг. Не два шага, где нужно очистить полоску перед выбором последующей опции.
import dash
from dash import dcc
from dash import html
from dash.dependencies import Input, Output
import dash_mantine_components as dmc
import pandas as pd
import plotly.express as px
import numpy as np
import random
from string import ascii_letters
df = pd.DataFrame(data=list(range(100)), columns=["tcd"])
df['humidity'] = pd.DataFrame(np.random.rand(100, 1) * 254)
df['Capsule_ID'] = [''.join(random.choice(ascii_letters) for x in range(10)) for _ in range(len(df))]
capsuleID = df['Capsule_ID'].unique()
capsuleID_names = list(capsuleID)
capsuleID_names_1 = [{'label': k, 'value': k } for k in sorted(capsuleID)]
capsuleID_names_2 = [{'label': '(Select All)', 'value': 'All'}]
capsuleID_names_all = capsuleID_names_1 + capsuleID_names_2
app = dash.Dash(__name__)
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
html.H1("Web Application Dashboards with Dash", style = {'text-align': 'center'}),
dcc.Dropdown(id = "capsule_select",
options=capsuleID_names_all,
optionHeight=25,
multi=True,
searchable=True,
placeholder='Please select...',
clearable=True,
value=[''],
style = {'width': "40%"}
),
html.Div([
dcc.Graph(id = "the_graph")
]),
])
@app.callback(
Output("the_graph", "figure"),
Output("capsule_select", "value"),
Input("capsule_select", "value"),
)
def update_graph(capsules_chosen):
dropdown_values = capsules_chosen
if "All" in capsules_chosen:
dropdown_values = df["Capsule_ID"]
dff = df
else:
dff = df[df["Capsule_ID"].isin(capsules_chosen)]
scatterplot = px.scatter(
data_frame=dff,
x = "tcd",
y = "humidity",
color = "Capsule_ID"
)
scatterplot.update_traces(textposition = "top center")
return scatterplot, dropdown_values
if __name__ == '__main__':
app.run_server(debug=True)
Редактировать 2:
Настройка select all в качестве единственного ярлыка, кажется, работает, но эта функциональность не имеет смысла. Прикреплен еще один скриншот. select all должен существовать изолированно. Вы не можете иметь все значения и еще одно значение.
Должны быть соблюдены два условия:
Если select all присутствует в раскрывающемся списке и выбран отдельный уникальный идентификатор, то для этого идентификатора следует удалить select all (у вас не должно быть select all и уникального идентификатора).
И наоборот, если выполняется действие с уникальным идентификатором и выполняется select all, то этот уникальный идентификатор следует удалить для одной вкладки select all.
def update_graph(capsules_chosen):
dropdown_values = capsules_chosen
if "All" in capsules_chosen:
dff = df
else:
dff = df[df["Capsule_ID"].isin(capsules_chosen)]
scatterplot = px.scatter(
data_frame=dff,
x = "tcd",
y = "humidity",
color = "Capsule_ID"
)
scatterplot.update_traces(textposition = "top center")
return scatterplot, dropdown_values






Вы можете изменить свой обратный вызов, чтобы проверять самый последний выбор и все выборы. Если пользователь выбирает All, когда уже есть один или несколько вариантов, All заменяет все остальное, а когда пользователь выбирает что-то еще, когда All был выбран ранее, этот выбор перезаписывает All
@app.callback(
Output("the_graph", "figure"),
Output("capsule_select", "value"),
Input("capsule_select", "value"),
)
def update_graph(capsules_chosen):
dropdown_chosen = capsules_chosen
## if user selects 'All' after one or more other dropdowns were selected, overwrite dropdown selection with 'All'
## if user selects another dropdown after 'All' was selected, overwrite dropdown selection with most recent
if len(dropdown_chosen) > 1:
if dropdown_chosen[-1] == 'All':
dropdown_chosen = ["All"]
if ('All' in dropdown_chosen) & (dropdown_chosen[-1] != 'All'):
dropdown_chosen = dropdown_chosen[-1]
if "All" in capsules_chosen:
dff = df
else:
dff = df[df["Capsule_ID"].isin(capsules_chosen)]
scatterplot = px.scatter(
data_frame=dff,
x = "tcd",
y = "humidity",
color = "Capsule_ID"
)
scatterplot.update_traces(textposition = "top center")
return scatterplot, dropdown_chosen
@Chopin, я обновил свой ответ, чтобы он соответствовал двум упомянутым вами случаям
Спасибо. Есть небольшая ошибка, но мы будем рады ее исправить или опубликовать отдельным вопросом. Если вы начнете с выбора «Выбрать все», а затем выберете отдельное значение, в раскрывающемся списке отобразится это единственное значение, но на графике по-прежнему будут отображаться значения «Выбрать все». Однако это исправляется, когда вы добавляете более одного значения.
@Шопен, я сейчас немного занят, но буду рад разобраться в ошибке через день или два, если ты не сможешь ее исправить – если ты это поймешь, пожалуйста, не стесняйся редактировать мой ответ
Поработайте вокруг. Как ни странно, после выбора отдельного значения в списке осталось «Все», но не второе выбранное значение. Я просто включил это перед последним оператором подмножества if/else: if len(capsules_chosen) == 2 and (capsules_chosen[0] == 'All'): capsules_chosen.remove('All')
Спасибо. Я изменил вопрос, чтобы сделать его более конкретным. Используя этот код, вы можете вернуть
select allи другое значение. Должно быть и то, и другое.