Search⌘ K

Linking Bar Charts and Drop-Downs

Explore how to link drop-down menus with bar charts in Dash to build dynamic, interactive visualizations. Learn to use callback functions including handling PreventUpdate exceptions, constructing app layout with rows and columns, and creating both horizontal and vertical bar charts based on user inputs. This lesson enables you to integrate controls that filter data by year and country, helping you design responsive dashboards that effectively compare values.

We now want to put everything together that we’ve done so far. The plan is to have two drop-downs side by side with a chart underneath each. The first will provide years as options that will generate a horizontal bar chart. The second will generate a vertical bar chart based on the selected country. The end goal is to produce a new section in our app that looks like the illustration below:

The Gini Index section in the app with two drop-down components and two bar charts
The Gini Index section in the app with two drop-down components and two bar charts

Building the application in JupyterLab

Let’s start by building this as a complete and independent app in JupyterLab and make sure it works as expected.

C++
# necessary imports
from jupyter_dash import JupyterDash
import dash_html_components as html
import dash_core_components as dcc
import dash_bootstrap_components as dbc
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
app = JupyterDash(__name__)
# create gini dataFrame
gini_df = poverty[poverty[gini].notna()]
# create app layout and add components
app.layout = html.Div([
html.Br(),
html.H2('Gini Index - World Bank Data', style={'textAlign': 'center'}),
html.Br(),
dbc.Row([
dbc.Col([
dcc.Dropdown(id='gini_year_dropdown',
options=[{'label': y, 'value': y}
for y in gini_df['year'].drop_duplicates().sort_values()]),
html.Br(),
dcc.Graph(id='gini_year_barchart')
]),
dbc.Col([
dcc.Dropdown(id='gini_country_dropdown',
multi=True,
options=[{'label': country, 'value': country}
for country in gini_df['Country Name'].unique()]),
html.Br(),
dcc.Graph(id='gini_country_barchart')
]),
])
])
# create a callback. Input: year and returns a chart
@app.callback(Output('gini_year_barchart', 'figure'),
Input('gini_year_dropdown', 'value'))
def plot_gini_year_barchart(year):
if not year:
raise PreventUpdate
df = gini_df[gini_df['year'].eq(year)].sort_values(gini).dropna(subset=[gini])
n_countries = len(df['Country Name'])
fig = px.bar(df,
x=gini,
y='Country Name',
orientation='h',
height=200 + (n_countries*20),
title=gini + ' ' + str(year))
return fig
# create a second callback
@app.callback(Output('gini_country_barchart', 'figure'),
Input('gini_country_dropdown', 'value'))
def plot_gini_country_barchart(countries):
if not countries:
raise PreventUpdate
df = gini_df[gini_df['Country Name'].isin(countries)].dropna(subset=[gini])
fig = px.bar(df,
x='year',
y=gini,
height=100 + (250*len(countries)),
facet_row='Country Name',
labels={gini: 'Gini Index'},
color='Country Name',
title=''.join([gini, '<br>', '<b>',
', '.join(countries), '</b>']))
return fig
# run the app
if __name__ == '__main__':
app.run_server(mode='inline')
  • Lines 2–9: We first run the necessary imports and instantiate the app. We already ...