Extending the chain
Your conditional dropdown was a smash hit! That cleaned up the dashboard and provided a much nicer user experience. When demonstrating this product, the stakeholder asked if you could implement a few updates.
Firstly, they wish to select a default value for the minor category so that something always appears on the graph. You have an idea of how to achieve this by inserting an additional chained callback between the first two created.
Secondly, they wish to have a title below the graph that reminds users what major category the chosen minor category belongs to. Rather than another callback, you think this can be achieved by sending the chosen major category to an additional output.
Diese Übung ist Teil des Kurses
Building Dashboards with Dash and Plotly
Anleitung zur Übung
- Create a callback below line
37
that is triggered by themajor_cat_dd
dropdown value and outputs to both theminor_cat_dd
dropdownoptions
and thechosen_major_cat_title
element. - Create another callback below line
52
that sets a defaultvalue
for theminor_cat_dd
dropdown when itsoptions
property updates.
Interaktive Übung
Versuche dich an dieser Übung, indem du diesen Beispielcode vervollständigst.
from dash import Dash, dcc, html, Input, Output, callback
import plotly.express as px
import pandas as pd
import random
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'}),
html.Div([
dcc.Graph(id='sales_line'),
html.H3(id='chosen_major_cat_title')],
style={'width':'700px', 'height':'650px','display':'inline-block'})
]
# Create a callback to set minor values and HTML output
@callback(
Output('____', '____'),
Output('____', 'children'),
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()
minor_options = [{'label':x, 'value':x} for x in relevant_minor_options]
if not major_cat_dd:
major_cat_dd = 'None Selected'
major_cat_title = f'This is in the Major Category of: {major_cat_dd}'
return minor_options, major_cat_title
# Create a callback to set a default minor category value
@callback(
Output('____', '____'),
Input('____', '____'))
def select_minor_cat(options):
chosen_val = 'None'
if options:
vals = [x['value'] for x in options]
chosen_val = random.choice(vals)
return chosen_val
@callback(
Output('sales_line', 'figure'),
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)