Example Dashboard

Getting started with building a Dashboard with Dash

After my first tutorial on Dash, which was basically getting to work the Dashboard presented in this video tutorial, I decided a bit more structured approach to setup the Dashboard from scratch would be better.

For this tutorial, basic Python programming skills and some knowledge of Pandas is needed.

This tutorial consists of 4 main steps:

  1. Use components to build the Dashboard interface
  2. Add interactivity with callback functions
  3. Styling elements using CSS
  4. Optimization for efficient Data Flow

First: setup

We are going to use the Pandas library for handling the data, Plotly for creating the figures (representation of the data) and Dash to turn it into a dashboard. Learn more about these packages via these tutorials: DashPandasPlotly. So we must first install those:

Install packages

In a Terminal, run the command below to install required packages:

pip install dash pandas plotly

If needed, you can also update the packages if yours are outdated:

pip install dash pandas plotly --upgrade

Start a new code project in your editor. (Create a new folder).

Import the libraries

Now, add a new Python file to your project to start with coding.

As with all Python code that uses libraries, import the needed libraries first:

# Load necessary libraries
import pandas as pd
from dash import Dash, html, dcc, callback
from dash.dependencies import Input, Output
import plotly.express as px

Load the data

Read the data from a .csv file:

df = pd.read_csv('sales_data.csv')

Setup the Dash app

Initialize a new Dash object:

# Setup the Dash app
app = Dash(__name__)

And start it:

# Run the app
if __name__ == '__main__':
    app.run(debug=True)

If you run the app now, it will start, but as soon as you try to view the dashboard in your browser, it will crash, because it is still empty (there are no components).

1. Use components to build the Dashboard interface

Components that can be used as building blocks in Dash come in two categories:

  • Dash Core Components (DCC): Ready-to-use interactive elements like dcc.Graph, which can be used to render any plotly-powered data visualization, or more basic userinterface elements like dcc.Dropdown, dcc.Slider, and dcc.DatePickerRange.
  • Dash HTML* Components: Python classes that represent HTML components (like html.Div, html.H1) to structure your dashboard layout or provide static content.

Now we will create a page with a root element (Div) and a title (H1) to make the layout of the app:

# Add a layout with a first component
app.layout = html.Div(style={'backgroundColor': '#f0f0f0', 'padding': '20px'}, children=[
    html.H1(
        children='Interactive Sales Dashboard', 
        # Inline styling applied to the H1
        style={
            'textAlign': 'center', 
            'color': '#333333',
            'fontFamily': 'Arial',
            'borderBottom': '2px solid #007bff',
            'paddingBottom': '10px'
        }
    )
])

As you can see, the root element, the html.Div, does have an attribute “children”. This can be a list, in this case it is, as it is defined as children=[]. But it does not have to be a list, only if it has sub-elements. If it is a string, like with the html.H1, at which it is defined as children=’Interactive Sales Dashboard’, which means the only child is just plain text (representing the content of the element).

Now you may Run the app. If you do so, a message like below will appear in the Terminal. This gives you the address that the app is running on, so you must open that in your browser (click the link):

Next, we can add a Graph to visualize the data. For that, we could select the data of one year, and then create a barchart for that.

Filter the data for 2020 and create the figure:

# get data for a year
filtered_df = df[df['Year'] == 2020]

# Generate a Plotly figure
fig = px.bar(
    filtered_df, 
    x='Month', 
    y='Sales', 
    title='Monthly Sales for 2020',
    color_discrete_sequence=['#007bff']
)

Now add a dcc.Graph object with the figure to the dashboard:

# dcc.Graph is the container for the visualization
dcc.Graph(id='main-data-graph', figure=fig)

This must be added as a new element in the list of children, so append a comma ‘,’ after the H1 element:

If you run the app again, the year 2020 bar chart should show.

To prepare for our next challenge: make it possible to select a year, we will add a dropdown list selector to the interface. The code for that could look like:

html.Div([
        html.Label("Select Year:", className='dropdown-label'),
        dcc.Dropdown(
            id='year-selector',
            options=[{'label': str(y), 'value': y} for y in df['Year'].unique()],
            value=2021,
            className='year-dropdown'
        ),
    ], className='dropdown-container'),

This code has to be inserted above the dcc.Graph, to put the list above it (do not forget a comma). Check if it shows up. To make it work, continue to the next part:

2. Add interactivity with callback functions

Remove the filtering of the dataframe and the figure generation from the top of the script.

Add callback function including input and output specification (the decorator part, that starts with @callback):

# Callback function that links the Dropdown (Input) to the Graph (Output)
@callback(
    # OUTPUT: The 'figure' property of the component with id='main-data-graph'
    Output(component_id='main-data-graph', component_property='figure'),
    # INPUT: The 'value' property of the component with id='year-selector'
    Input(component_id='year-selector', component_property='value')
)
def update_graph(selected_year):
    # The selected_year variable holds the 'value' from the dropdown
    
    # 1. Process Data (filter the global DataFrame 'df')
    filtered_df = df[df['Year'] == selected_year]
    
    # 2. Generate a Plotly figure
    fig = px.bar(
        filtered_df, 
        x='Month', 
        y='Sales', 
        title=f'Monthly Sales for {selected_year}',
        color_discrete_sequence=['#007bff']
    )
    
    # 3. Return the figure to the dcc.Graph component
    return fig

As you can see from the @callback part, the output (result) of the function will be connected to the component with the id ‘main-data-graph’ and be shown in that component’s property ‘figure’.

The input (value) comes from component with id ‘year-selector’, specifically its property ‘value’.

You can see the full code here (in case you are having trouble putting everything together).

If you run the app now, you should be able to change the year using the dropdown.

3. Styling elements using CSS

You might have seen the “style=” parameter when we defined the components (step 1). Instead of this inline styling, we can also put the CSS code of the components in an external .css file. Dash will automatically load .css files that are in the “assets” folder. To target specific element from the .css file, add an id or a class name to them:

So for instance the H1 heading:

html.H1(
        children='Interactive Sales Dashboard', 
        # Inline styling applied to the H1
        style={
            'textAlign': 'center', 
            'color': '#333333',
            'fontFamily': 'Arial',
            'borderBottom': '2px solid #007bff',
            'paddingBottom': '10px'
        }
    )

Can be replaced by:

html.H1(
        children='Interactive Sales Dashboard',
        className='main-title'
    )

And then add this selector to the .css file:

.main-title {
    text-align: center;
    color: #333333;
    font-family: Arial, sans-serif;
    border-bottom: 2px solid #007bff;
    padding-bottom: 10px;
}

You may now add some additonal styling to the .css file. Eg. try to adjust colors, or add a background. An example:

Add a semi-transparent light grey background to the main container:

.main-container {
    background-color: rgba(150,150,150, 0.7);
    padding: 20px;
}

Add a cover background with an image and specify other font:

html {
	background: url('https://home.et.utwente.nl/slootenvanf/div/campusbg.png') no-repeat center center fixed;
	background-size: cover;
}

body {
	margin: 50px 0;
	padding: 0;
	text-align: center;
	font-family: Georgia, "Times New Roman", Times, serif;
}

You can see the full code here (in case you are having trouble putting everything together).

If you run the app now, you should be able to see the changed styling. This is how it could look:

Learn more about web design:

4. Optimization for efficient Data Flow

Think about data efficiency: load data once (do not put code that requires intense processing in callbacks). Filtering is Ok, as long as its not taking too much time. So what we do in our example: loading the data before initializing the app (at start of the code) and doing some light filtering (year selection) is Ok.

Other strategies to help improve performance:

Extra challenge

There is a second dataset in the repository that has more data (full years). Create additional views that can:

  • Change the view to see a view per quartile or by full year.
  • Add a combined view that shows all data of all years into one bar chart and allow switching between the new view and the old view.

Solution for the above is here. (changes have been made to the .css files in the assets folder also). But try adding this yourself first!

More information