Welcome to Dash Crush, your walk-through tutorial to advanced interactive Data Viz dashboards using Dash Plotly.
TL;DR
In this chapter:
- Introduction to dash
- Installation
- Your first app: layout and callback
- Running your first app
What is Dash?
Dash is an open-source framework by Plotly to build data-centric apps. It was originally released as a Python library, so I will focus on Python code. (Currently, there are Dash implementations for R, Julia, and F#). Using Dash you can build a dashboard without excessive knowledge of all the web stuff like HTML, CSS or JS (Though we will reach a point where you will benefit from knowing them).
The backbone of Dash consists of Flask, React, and Plotly.js. Hopefully, they are hidden from the user, so you do not have to worry.
Strengths of Dash
After a few years of intensive usage of Dash, I identified a few key strengths contributing to its success:
- Immanent power: you can do a lot with core Dash libraries and new features are added in every release.
- Community: over 5 million developers using Dash equals many community SW components available and many colleagues to ask for advice.
- Extensibility: if the previous points do not provide an answer to your question, you can create a Dash component from React ones.
- Paid options: you can use Dash Enterprise or sponsor implementing the feature you need by Plotly.
Web resources
My intention is not to copy content you can easily find on the web, so I'll only list some very useful links for further reading:
- Dash has detailed (and usually working) documentation, including basic tutorials and API references. You can find them here:
https://dash.plotly.com/ - Plotly community forum where you can ask questions that bother you. And you will be heard:
https://community.plotly.com/c/python/25 - Especially worth mentioning is the list of community components for Dash:
https://community.plotly.com/t/community-components-index/60098
Basic concepts of Dash
There are two basic concepts behind the Dash framework:
- Layout - defines how your application looks. It's a hierarchy of nested components like Row, Col, and Div used analogously, as in good old HTML.
- Callbacks - are functions that define interactivity between components. They are executed when given properties of components (marked as
Input
in callback definition) change, and define the way to modify properties marked asOutput
s.
Let's start coding
To be able to work with Dash, you will need to have the following prerequisites installed:
- Python,
- Pip,
- (optional, but recommended) virtual environment.
Let's create your first Dash app.
Creating the virtual env
Create your virtual env:
python -m venv dashenv
and activate it with:
- on Linux/macOS:
source dashenv/bin/activate
- on Windows:
dashenv/Scripts/activate
Installing Dash Plotly
To use Dash, we need to install it first. We will also need pandas
for data manipulation.
Open the terminal and run the following command:
pip install dash pandas
First Dash app
We will create a simple dashboard that plots the precalculated Band Structure of Gallium Arsenide or Indium Arsenide, depending on material selection in the dropdown. (I will use examples from Quantum Physics in this tutorial, as those are most of the techniques I used to build http://qc.slashdev.team:8866/dash/)
Main file
The entry point of the app is dashboard.py
. To create an empty dashboard, we only need to create an instance of Dash
and call its run_server
method
# dashboard.py
import dash
APP = dash.Dash(__name__)
# Run the Dash app
if __name__ == "__main__":
APP.run_server(debug=True)
To fill the content of the app, we need to set APP.layout
. There are two ways we could do that:
- Provide a tree of the components,
- Provide a function that returns the tree of components.
I will use the 2nd option and define the function create_layout
in the file src/layout
Layout
Our simple layout looks like this:
# src/layout.py
from dash import dcc, html
MATERIALS = ["GaAs", "InAs"]
def create_layout():
"""Build layout"""
return html.Div(
[
html.H5("Material:"),
dcc.Dropdown(
id="material_dropdown",
options=[{"label": name, "value": name} for name in MATERIALS],
value="GaAs",
),
dcc.Graph(
id="band_structure_graph",
),
],
)
Let's go through it step by step:
- Dash provides two modules that contain components:
html
has a component for every HTML element (we useh5
header anddiv
)dash_core_components
(dcc
) contains higher level components that are not pure HTML. Instead, they are interactive and are generated with JavaScript, HMTL, CSS using React.js library
- Function
create_layout
defines simple layout that consists of header, dropdown enabling material selection and graph
Now, we can set the layout of our app. We need to modify dashboard.py
to import the layout module
from src import layout
and pass the create_layout function to APP:
APP.layout = layout.create_layout
The resulting code is:
import dash
from src import layout
APP = dash.Dash(__name__)
APP.layout = layout.create_layout
# Run the Dash app
if __name__ == "__main__":
APP.run_server(debug=True)
At this moment, we have an empty layout. To make it interactive, we need one more element.
Callback
We will define callbacks in the src/callbacks.py
file.
from dash import Input, Output
from dash.exceptions import PreventUpdate
import pandas as pd
import plotly.graph_objs as go
MATERIAL_DATA = {"GaAs": pd.read_csv("GaAs.dat"), "InAs": pd.read_csv("InAs.dat")}
TRACES = ["E_so", "E_lh", "E_hh", "E_c"]
def create_figure(to_draw):
"""Style graph"""
layout = go.Layout(
autosize=True,
title="Band structure",
xaxis={"title": "k (wave vector) [1/nm]"},
yaxis={"title": "E (Energy) [eV]"},
)
return go.Figure(data=to_draw, layout=layout)
def create_callbacks(app):
"""Create callbacks"""
@app.callback(
Output("band_structure_graph", "figure"),
Input("material_dropdown", "value"),
prevent_initial_call=True,
)
def plot(material):
if not material:
raise PreventUpdate
data = MATERIAL_DATA[material]
to_draw = []
for trace in TRACES:
to_draw.append(go.Scatter(x=data["k"], y=data[trace], mode="lines", name=trace))
return create_figure(to_draw)
Let's go through it step-by-step:
-
imports
Input, Output
are definitions of Callback Input and Output objectsPreventUpdate
is a special exception that is used if we do not want to modify the existing state of the appimport plotly.graph_objs as go
is a module providing various types of plots. We will use the scatter plot
-
we read data files, containing energy profile data for each material and define traces to be plotted:
MATERIAL_DATA = {"GaAs": pd.read_csv("GaAs.dat"), "InAs": pd.read_csv("InAs.dat")} TRACES = ["E_so", "E_lh", "E_hh", "E_c"]
-
create_figure
is a helper method that defines the layout of the graph itself, sets the graph and axes' titles. -
Actual callback: we need to define a callback function to plot a new graph on trigger. It's done by adding
app.callback
decorator to the function definition@app.callback( Output("band_structure_graph", "figure"), Input("material_dropdown", "value"), prevent_initial_call=True, ) def plot(material):
- The decorator means that the
plot
function is executed whenever thevalue
property of thematerial_dropdown
dcc.Dropdown component changes. app
is a Dash object passed from the caller.prevent_initial_call
is used to prevent firing a callback when a webpage is loaded in a browser
- The decorator means that the
-
Inside the
plot
function, we fill in graph content. We add a newScatter
trace for each series in input data. -
We turn data into a graph with
create_figure
As with the layout, we need to import create_callbacks
in dashboard.py
:
from src.callbacks import create_callbacks
and call it there:
create_callbacks(APP)
Starting the app:
Start the app with python dashboard.py
. You should see an indication of a running app in your console. The dashboard is available under http://localhost:8050. Navigate to that URL in your browser and enjoy your first dashboard!
Summary:
Quick recap:
- To run Dash you need Python and a virtual env
- Install dash with
pip install dash
- Create your app with
APP = dash.Dash(__name__)
- Setup
APP.layout =
and create callbacks - Run your app with
python dashboard.py
- Enjoy the result under http://localhost:8050
The complete code from this tutorial can be found on GitHub:
https://github.com/ptrhbt/dash-crush/tree/0-intro
There is also a file requirements.txt
which lists all used packages. Just install it to your virtual env with pip install -r requirements.txt
.
More detailed info can be found in the official Dash documentation:
https://dash.plotly.com/
including Minimal Dash App, Dash in 20 Minutes Tutorial, and Layout/Callbacks fundamentals.
We will explore more of Dash magic in the upcoming parts of Dash Crush.