Making the app interactive
Basic Dash Callbacks
See part 2 of the tutorial at https://dash.plotly.com/basic-callbacks
Inputs and Outputs
from dash.dependencies import Input, Output
The “inputs” and “outputs” of the application’s interface are described declaratively as the arguments of the @app.callback
decorator.
The “inputs” and “outputs” are properties of a particular component.
For example the input is the “value” property of a component with a specified id while the “output” is the “children” property of a component with a specified id.
Reactive programming: whenever an input changes, everything that depends on that input gets automatically updated.
Whenever an input property changes, the function that the callback decorator wraps is automatically called. The new value of the input property is provided as an input argument to the function. Dash updates the property of the output component with whatever was returned by the function.
-
component_id
and component_property
are optional keywords
-
There is no need to specify a value for the children
property of the output ( html.Div(id='my-output')
in the app below) component in the layout
because when the app starts up, all of the callbacks are automatically called with the initial values of the input components to populate the initial state of the output components. Any value specified would be overwritten when the app starts.
Component Id and Property
The component_id
and component_property
are optional and are usually excluded.
@app.callback(
Output(component_id='my-output', component_property='children'),
Input(component_id='my-input', component_property='value')
)
Text box
A simple text box where you just change the value of the text box and the output changes as a result
- the Layout
# here the input is the value property of the component with id "my-input"
dcc.Input(id='my-input', value='initial value', type='text')
- The Callback function
component_id
, component_property
# callback for the simple text box
@app.callback(
# the output is the "children" property of the component with id "my-output"
Output(component_id='my-output', component_property='children'),
# here the input is the value property of the component with id "my-input"
Input(component_id='my-input', component_property='value')
)
def update_output_div(input_value):
return 'Output: {}'.format(input_value)
Slider and Graph
The dcc.slider
here updates the dcc.Graph
.
- the
layout
html.Br(),
html.Div([
dcc.Graph(id='graph-with-slider'),
dcc.Slider(
id='year-slider',
min=df['year'].min(),
max=df['year'].max(),
value=df['year'].min(),
marks={str(year): str(year) for year in df['year'].unique()},
step=None
)
]),
- The Callback function
The value property from the slider component (id ‘year-slider’) is the input of the app and used to update the output of the app - the ‘figure’ property of the graph component (with id ‘graph-with-slider’).
Whenever the value of the slider changes, the update_figure
callback function is called with this new value. The function filters the dataframe with the new value and creates a figure object which is returned to the app.
# callback for the graph with slider
@app.callback(
# `component_id`, `component_property`
Output('graph-with-slider', 'figure'),
Input('year-slider', 'value'))
def update_figure(selected_year):
filtered_df = df[df.year == selected_year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp",
size="pop", color="continent", hover_name="country",
log_x=True, size_max=55)
fig.update_layout(transition_duration=500)
return fig
Dash app running on http://127.0.0.1:8051/
Loading the pandas DataFrame
The pandas DataFrame is loaded at the start of the app and is in the global state of the app, therefore it can be read inside the callback functions.
The dataframe is only loaded at the start and therefore the data is already in memory when the user visits or interacts with the app.
It is recommended to always download or query data (or any other expensive initialisation) in the global scope and not within the scope of the callback functions.
A copy of the dataframe is created by the callback function - the original data variable should never be mutated outside of it’s scope. Otherwise one user’s session might affect the next user’s session.
layout.transition
layout.transistion
can be used to show how a dataset evolves over time.
- allows a chart to update from one state to the next smoothly.
Multiple Inputs and Outputs
-
A dash app can have multiple inputs.
-
Any “Output” can have multiple “Input” components.
-
More than one “Output” components can be updated at once.
-
Avoid combining outputs:
- if the Outputs depend on some but not all of the same Inputs to avoid unnecessary updates
- if independent computations are performed on these inputs - keep them separate allows them to be run in parallel.
The app below from https://dash.plotly.com/basic-callbacks tutorial binds several inputs to a single Output component (the figure
property of the Graph
component.
The Input
’s are the value
property of various dcc components (including dcc.Dropdown
, dcc.RadioItems
, dcc.Slider
etc).
@app.callback(
Output('indicator-graphic', 'figure'),
Input('xaxis-column', 'value'),
Input('yaxis-column', 'value'),
Input('xaxis-type', 'value'),
Input('yaxis-type', 'value'),
Input('year--slider', 'value'))
The callback here executes whenever the ‘value’ property of any of these components change.
The input arguments of the callback are the new or current value of each of the Input properties in the order they are specified in the callback function. As you can only update one input in a particular moment, Dash will take the current state of all the specified Input properties and passes them into the function.
This means if you just move the slider or select some other value from the dropdown or select a different radio item, the moment you change one value the output will be updated.
Chaining Callbacks
Outputs and inputs can also be chained together with the output one callback function being the input of another callback function. This allows for dynamic user interfaces where one input component updates the available options of the next input component.
In the app below there are 3 callback functions.
The first callback handles a user clicking on another country using a set of radio buttons.
It then updates the available cities to choose from in the cities radio button.
Dash waits for the value of the cities component to be updated before calling the final function to which outputs that the selected city is in the correct country.
This prevents the callbacks from being updated with inconsistent state.
Dash app with State
Sometimes if you have something like a form in the app, you will only want the value of the input component to only be read when the user has finished entering all the information in the form.
The first callback below is fired whenever any of the attributes described by the Input
changes.
The second callback illustrates using State
which allows you to pass along extra values without firing the callbacks.
The callback is triggered in the above example by listening to the n_clicks
property of the button component.
n_clicks
is a property that get incremented everytime the component is clicked on and is available in every component in the dash_html_components
library.
Summary of Basic Callbacks tutorial from
Declarative UI’s are customisable through reactive and functional Python callbacks.
Every element attribute of the declarative components can be updated through a callback. A subset of the attributes such as the value
properties of a dropdown component can be edited by the users in the user interface.
Basic Dash Callbacks
See part 2 of the tutorial at https://dash.plotly.com/basic-callbacks
Inputs and Outputs
from dash.dependencies import Input, Output
The “inputs” and “outputs” of the application’s interface are described declaratively as the arguments of the @app.callback
decorator.
The “inputs” and “outputs” are properties of a particular component.
For example the input is the “value” property of a component with a specified id while the “output” is the “children” property of a component with a specified id.
Reactive programming: whenever an input changes, everything that depends on that input gets automatically updated.
Whenever an input property changes, the function that the callback decorator wraps is automatically called. The new value of the input property is provided as an input argument to the function. Dash updates the property of the output component with whatever was returned by the function.
-
component_id
andcomponent_property
are optional keywords -
There is no need to specify a value for the
children
property of the output (html.Div(id='my-output')
in the app below) component in thelayout
because when the app starts up, all of the callbacks are automatically called with the initial values of the input components to populate the initial state of the output components. Any value specified would be overwritten when the app starts.
Component Id and Property
The component_id
and component_property
are optional and are usually excluded.
@app.callback(
Output(component_id='my-output', component_property='children'),
Input(component_id='my-input', component_property='value')
)
Text box
A simple text box where you just change the value of the text box and the output changes as a result
- the Layout
# here the input is the value property of the component with id "my-input"
dcc.Input(id='my-input', value='initial value', type='text')
- The Callback function
component_id
, component_property
# callback for the simple text box
@app.callback(
# the output is the "children" property of the component with id "my-output"
Output(component_id='my-output', component_property='children'),
# here the input is the value property of the component with id "my-input"
Input(component_id='my-input', component_property='value')
)
def update_output_div(input_value):
return 'Output: {}'.format(input_value)
Slider and Graph
The dcc.slider
here updates the dcc.Graph
.
- the
layout
html.Br(),
html.Div([
dcc.Graph(id='graph-with-slider'),
dcc.Slider(
id='year-slider',
min=df['year'].min(),
max=df['year'].max(),
value=df['year'].min(),
marks={str(year): str(year) for year in df['year'].unique()},
step=None
)
]),
- The Callback function
The value property from the slider component (id ‘year-slider’) is the input of the app and used to update the output of the app - the ‘figure’ property of the graph component (with id ‘graph-with-slider’).
Whenever the value of the slider changes, the update_figure
callback function is called with this new value. The function filters the dataframe with the new value and creates a figure object which is returned to the app.
# callback for the graph with slider
@app.callback(
# `component_id`, `component_property`
Output('graph-with-slider', 'figure'),
Input('year-slider', 'value'))
def update_figure(selected_year):
filtered_df = df[df.year == selected_year]
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp",
size="pop", color="continent", hover_name="country",
log_x=True, size_max=55)
fig.update_layout(transition_duration=500)
return fig
Dash app running on http://127.0.0.1:8051/
Loading the pandas DataFrame
The pandas DataFrame is loaded at the start of the app and is in the global state of the app, therefore it can be read inside the callback functions. The dataframe is only loaded at the start and therefore the data is already in memory when the user visits or interacts with the app. It is recommended to always download or query data (or any other expensive initialisation) in the global scope and not within the scope of the callback functions.
A copy of the dataframe is created by the callback function - the original data variable should never be mutated outside of it’s scope. Otherwise one user’s session might affect the next user’s session.
layout.transition
layout.transistion
can be used to show how a dataset evolves over time.- allows a chart to update from one state to the next smoothly.
Multiple Inputs and Outputs
-
A dash app can have multiple inputs.
-
Any “Output” can have multiple “Input” components.
-
More than one “Output” components can be updated at once.
-
Avoid combining outputs:
- if the Outputs depend on some but not all of the same Inputs to avoid unnecessary updates
- if independent computations are performed on these inputs - keep them separate allows them to be run in parallel.
The app below from https://dash.plotly.com/basic-callbacks tutorial binds several inputs to a single Output component (the figure
property of the Graph
component.
The Input
’s are the value
property of various dcc components (including dcc.Dropdown
, dcc.RadioItems
, dcc.Slider
etc).
@app.callback(
Output('indicator-graphic', 'figure'),
Input('xaxis-column', 'value'),
Input('yaxis-column', 'value'),
Input('xaxis-type', 'value'),
Input('yaxis-type', 'value'),
Input('year--slider', 'value'))
The callback here executes whenever the ‘value’ property of any of these components change. The input arguments of the callback are the new or current value of each of the Input properties in the order they are specified in the callback function. As you can only update one input in a particular moment, Dash will take the current state of all the specified Input properties and passes them into the function. This means if you just move the slider or select some other value from the dropdown or select a different radio item, the moment you change one value the output will be updated.
Chaining Callbacks
Outputs and inputs can also be chained together with the output one callback function being the input of another callback function. This allows for dynamic user interfaces where one input component updates the available options of the next input component.
In the app below there are 3 callback functions. The first callback handles a user clicking on another country using a set of radio buttons. It then updates the available cities to choose from in the cities radio button. Dash waits for the value of the cities component to be updated before calling the final function to which outputs that the selected city is in the correct country. This prevents the callbacks from being updated with inconsistent state.
Dash app with State
Sometimes if you have something like a form in the app, you will only want the value of the input component to only be read when the user has finished entering all the information in the form.
The first callback below is fired whenever any of the attributes described by the Input
changes.
The second callback illustrates using State
which allows you to pass along extra values without firing the callbacks.
The callback is triggered in the above example by listening to the n_clicks
property of the button component.
n_clicks
is a property that get incremented everytime the component is clicked on and is available in every component in thedash_html_components
library.
Summary of Basic Callbacks tutorial from
Declarative UI’s are customisable through reactive and functional Python callbacks. Every element attribute of the declarative components can be updated through a callback. A subset of the attributes such as the
value
properties of a dropdown component can be edited by the users in the user interface.