Voorwaardelijke dropdown-opties
Een senior inkoopmedewerker bij het e-commercebedrijf heeft een interessant probleem voorgelegd. Hun bestaande dashboard, dat de omzet per maand toont voor subcategorieën van items, heeft een dropdown op twee niveaus (hoofdcategorie en subcategorie) met veel te veel opties. Het is vooral vervelend, zo hoor je, dat er in de tweede dropdown opties verschijnen die niet geselecteerd kunnen worden.
Je stelt de stakeholder gerust dat je kunt helpen — dit is een uitstekende kans om chained callbacks te gebruiken om een voorwaardelijke dropdown te maken.
Deze oefening maakt deel uit van de cursus
Dashboards bouwen met Dash en Plotly
Oefeninstructies
- Maak een callback onder regel
31om deoptionsvan de dropdownminor_cat_ddbij te werken op basis van de waarde van de dropdownmajor_cat_dd. - Herformatteer de variabele
relevant_minor_options(onder regel39) naar een lijst met dictionaries met identieke sleutelslabelenvalue. - Maak nog een callback onder regel
43die defigurevan de grafieksales_linebijwerkt op basis van de waarde van de dropdownminor_cat_dd.
Interactieve oefening met praktijkervaring
Probeer deze oefening door deze voorbeeldcode aan te vullen.
from dash import Dash, dcc, html, Input, Output, callback
import plotly.express as px
import pandas as pd
ecom_sales = pd.read_csv('/usr/local/share/datasets/ecom_sales.csv')
major_categories = list(ecom_sales['Major Category'].unique())
minor_categories = list(ecom_sales['Minor Category'].unique())
logo_link = 'https://assets.datacamp.com/production/repositories/5893/datasets/fdbe0accd2581a0c505dab4b29ebb66cf72a1803/e-comlogo.png'
ecom_country = ecom_sales.groupby('Country')['OrderValue'].agg(['sum', 'count']).reset_index().rename(columns={'count':'Sales Volume', 'sum':'Total Sales ($)'})
app = Dash()
app.layout = [
html.Img(src=logo_link, style={'margin':'30px 0px 0px 0px'}),
html.H1('Sales breakdowns'),
html.Div([
html.H2('Controls'),
html.Br(),
html.H3('Major Category Select'),
dcc.Dropdown(
id='major_cat_dd',
options=[{'label':category, 'value':category} for category in major_categories],
style={'width':'200px', 'margin':'0 auto'}),
html.Br(),
html.H3('Minor Category Select'),
dcc.Dropdown(id='minor_cat_dd', style={'width':'200px', 'margin':'0 auto'})],
style={'width':'350px', 'height':'350px', 'display':'inline-block',
'vertical-align':'top', 'border':'1px solid black', 'padding':'20px'}),
dcc.Graph(id='sales_line',style={'width':'700px', 'height':'650px','display':'inline-block'})
]
# Create a callback from the Major Category dropdown to the Minor Category Dropdown
@callback(
Output('____', '____'),
Input('major_cat_dd', 'value'))
def update_minor_dd(major_cat_dd):
major_minor = ecom_sales[['Major Category', 'Minor Category']].drop_duplicates()
relevant_minor_options = major_minor[major_minor['Major Category'] == major_cat_dd]['Minor Category'].values.tolist()
# Set up the Major Category options with the same label and value
formatted_relevant_minor_options = [{'label':____, 'value':____} for ____ in ____]
return formatted_relevant_minor_options
# Create a callback for the Minor Category dropdown to update the line plot
@callback(
Output('____', '____'),
Input('minor_cat_dd', 'value'))
def update_line(minor_cat):
minor_cat_title = 'All'
ecom_line = ecom_sales.copy()
if minor_cat:
minor_cat_title = minor_cat
ecom_line = ecom_line[ecom_line['Minor Category'] == minor_cat]
ecom_line = ecom_line.groupby('Year-Month')['OrderValue'].agg('sum').reset_index(name='Total Sales ($)')
line_graph = px.line(ecom_line, x='Year-Month', y='Total Sales ($)', title=f'Total Sales by Month for Minor Category: {minor_cat_title}')
return line_graph
if __name__ == '__main__':
app.run(debug=True)