There are a few questions regarding the issue of adding a select all option for filtering data with numerous values using plotly dash. The link list below performs the function but it adds every value into the dropdown bar. Rather than a single tab or component that represents all the values. This makes the app layout unworkable as the page is filled with values in the dropdown bar.
It would be constructive if a single label (all/select all etc) could be used in-place of listing all individual values.
Python Plotly Dash dropdown Adding a "select all" for scatterplot
Using below, when select all is chosen, every value appears in the dropdown-bar. Ideally, when select all
is chosen, the dropdown bar should only show a select all
label, while all data should be visible.
Further, if select all
as a single tab is present and the user wants to view a unique id, then select all
should be dropped for that id. Conversely, if a unique id is actioned and select all
is executed, then that unique id should be dropped for the single select all
tab. This should be done in one step. Not two steps, where you need to clear the bar before selecting a subsequent option.
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)
Edit 2:
Configuring select all
to be the only label appears to work but the functionality doesn't make sense. Attached is another screenshot. select all
should exist in isolation. You can't have all the values and another value.
Two conditions should be met:
If select all
is present in the dropdown bar and a separate unique id is chosen, then select all
should be dropped for that id (you shouldn't have select all
and a unique id).
Conversely, if a unique id is actioned and select all
is executed, then that unique id should be dropped for the single select all
tab.
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
You can modify your callback so that you check the most recent selection and all selections. If the user selects All
when there's already one or more selections, All
replaces everything else, and when the user selects something else when All
was previously selected, this selection overwrites 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