Plotly Dash — A Structured Framework for a Multi-Page Dashboard

-

Plotly Dash is a framework that enables the creation of interactive dashboards, facilitating the presentation of a wide range of knowledge and data in a straightforward to digest and aesthetically pleasing format.

Typically, examples and guidance on methods to create a Dash app have all of the code inside a single python file. Although this can be a nice concise technique to start, even easy dashboards can develop into overwhelming to administer when all of the code is in a single file.

This text presents a smart, and fully functional, multi-file project structure, containing all of the essentials to start.

Managing and expanding the project, even when the project is kind of extensive, should develop into much easier to take care of.


Introduction

Many online examples for Dash dashboards are presented in a single file, and although that is high-quality for small easy dashboards, it becomes unimaginable to administer as a project increases in size, and potentially onto multiple pages.

It subsequently becomes mandatory to begin breaking up the one file to create a logical project structure to make project management easier.

Nevertheless, guidance on methods to approach a structured multi-page app, specifically with Dash, are few and much between. There also appears to be no standard “official” technique to structure a Dash app.

Moreover, any examples of multi-page apps are likely to present a bear-bones structure that typically doesn’t include any example graphing (i.e. they usually are not fully functional). This leaves some guesswork with regard to really getting the app to run and work reliably with the info you ought to present.

This text provides a totally functional base that the user can run, and experiment with, immediately. It also provides a useful reference point to start developing a project from.

Aim

With the above in mind, this text is primarily concerned with 4 items in relation to making a Dash dashboard:

  1. Multi-page
  2. Logical project structure (i.e. not multi functional file, and with a multi-folder structure)
  3. Fully functional including data (API) and graphing (Plotly)
  4. Git ready

Detailed Features

The precise output (dark mode) showing the features of the project structure – Image by Creator – Data from GAPMINDER.ORG, CC-BY LICENSE

A summary

Along with the fundamental goals detailed within the previous section, the next features have been included to offer a usable, aesthetically pleasing, and functional base:

  1. A sidebar which lists the available pages, and highlights which page is energetic because the page changes
  2. A header with website name, logo and dark/light theme switch
  3. Mobile ready responsive layout with collapsible sidebar
  4. Dark/light theme switching, including dark light theming of the Plotly graphs
  5. Two different API integrations, one local (Plotly Gapminder), and one distant with logic for API keys (NinjasAPI)
  6. Git ready, with logic to maintain API keys out of the code, and auto DEBUG/production mode (python-dotenv)
  7. A straightforward example of bespoke styling using style.css
  8. Utilises DASH Mantine Components for general styling, providing a consistent theme

The next sub-sections will explain among the features included within the framework in just a little more detail.

For those who are in search of the code please skip towards the top of the article where you will discover a link to the GitHub repository with the code and details on methods to start.

Styling with DASH Mantine Components

the main page of the Dash app using the light theme with three example plotly graphs
The precise output (light mode) showing the features of the project structure – Image by Creator – Data from GAPMINDER.ORG, CC-BY LICENSE

It is feasible to style a Dash dashboard without the help of a front end framework. Nevertheless, usually I think the priority can be to present data quickly and effectively, so it makes little sense to make life harder than it must be.

As such, the framework presented in this text utilises Dash Mantine components for styling, which is a widely used and modern styling API designed specifically to be used with Dash dashboards:

Construct feature-rich, accessible Dash apps faster than ever! Dash Mantine Components includes over 100 customizable components based on the React Mantine library, with consistent styling, theming, and full support for light and dark mode.

dash-mantine-components.com

Particularly, the layout chosen for this project structure builds on the next official layout example:

AppShell with Theme Switch Component – GitHub

Although the general look of the official layout could be very much like the one this text uses (as you’ll expect…), there is no such thing as a functionality built into the official layout, and all of the code is in a single python file.

Dark light graph switching

a video of the app changing between dark and light mode, and then between page 1 and 2 of the app

The bottom theme detailed within the previous section already includes the code to change between light and dark themes.

Nevertheless, once components are added that usually are not specifically “Mantine” components (e.g. plotly graphs), then the theme switch won’t work for those “other” components without specific integration.

The framework included in this text includes example plotly graphs, and the associated code to change the graphs between the dark and lightweight theme.

The dark/light switch is implemented to work without the necessity to reload the info displayed within the graphs, and hence won’t overload any data APIs on switching.

Multi-page

One in all the more complicated items included within the framework is the incontrovertible fact that it includes multiple page.

The implementation uses essentially the most recent approach to achieving this through Dash Pages, which was introduced in Dash 2.5.

Although the implementation of Dash Pages is comparatively simple, it becomes more complicated when the project is structured into multiple files and folders, as there are only a few examples available.

Hopefully, this framework will provide guidance on what a working example looks like.

Git and Development Ready

a git branch structure visually represented
Photo by Yancy Min on Unsplash

As this framework is meant to be a place to begin for your individual project, it’s assumed that some development will happen, and that ongoing development may include the necessity to use Git.

The next subsections detail some features of this framework that help to make this process easier.

Environmental variables

The framework utilises python-dotenv to handle environmental variables (see the “Basic Usage” section later within the article for implementation details).

What this essentially means is that certain variables may be kept local to the project, but out of the fundamental code-base. For instance:

  1. variables that change between production and development environments
  2. variables that shouldn’t appear in public repositories (i.e. GitHub)

This enables API keys to be kept secret, and seamless pushing to production through GitHub (do you have to wish to do that).

Git Ignore

A .gitignore file is included primarily to stop virtual environments, and the all necessary .env file, from being pushed to GitHub by accident.

It also includes some generic Python based exclusions which may be helpful.

Production Server Ready

To assist within the deployment of the Dash app to production, a wsgi.py file is included, which ought to be useful when the time involves push the project live.

The .env file mentioned within the previous section can be used to activate (or deactivate) DEBUG mode seamlessly between produciton and development environments. (see the “Basic Usage” section later within the article for implementation details)

API Integration

a green background with the acronym API printed in large letters. There is also a laptop at the bottom of the image with two human hands.
Image by zeeve platform from Pixabay

There are two data APIs integrated into the codebase.

Gapminder (the default)

The primary is the Gapminder API that’s included as a library inside Plotly.

This makes the API locally available, and fast, which is great for rapid development and testing.

API Ninjas

There’s also code included for example of methods to integrate an external API.

On this particular case, the included external API is API Ninjas. This could essentially allow for more realistic distant API testing do you have to need this (i.e. accounting/testing for bad or lost connections, or API errors).

API Ninjas is a business API, and as such has subscription costs beyond certain usage levels. Nevertheless, their free tier is one of the crucial generous I actually have found, which makes it great for development testing.

To make use of the API Ninjas API you will have to get your individual API key (A free use API Key may be acquired from their website). The API key then must be included within the .env file. Finally, set the EXTERNAL_API flag in utils/consts.py to True.

Disclaimer:

CSS Styling

Specific styling may be included inside the project in a CSS file. This file is situated in assets/styles.css and includes the next code:

.main-title {
    color: var(--mantine-color-gray-6);
}

[data-mantine-color-scheme="dark"] .main-title {
    color: var(--mantine-color-gray-3);
}

The instance just changes the fundamental title to a gray color, but in addition accounts for color change when switching between the dark and lightweight theme.

For those who are accustomed to CSS, extensive style changes may be created from this file if required.

More details on methods to take care of external resources like CSS or Javascript are within the Dash docs.

Necessary coding notes

the second page of the Dash app which just contains some text
The second page of the framework app – Image by Creator

Dash could be very flexible when it comes to the methods allowed to construct a dashboard/app, which keeps things easy and straightforward to make use of.

Nevertheless, within the means of constructing this framework it has develop into clear that some unwritten rules have to be followed when things develop into more complicated.

it’s essential to provide app elements with functions moderately than assigning them to a variable.

Particularly, when coping with a multi-page Dash app, with file and folder structure, it’s essential to provide app elements with functions moderately than assigning them to a variable.

For example, take the definition of the Archive page utilised on this project structure.

That is the Archive page defined with a function:

import dash
from dash import html

dash.register_page(__name__)

def layout(**kwargs) -> html.Div:
    return html.Div(
        [
            html.H1("This is our Archive page"),
            html.Div("This is our Archive page content."),
        ]
    )

…and this is identical page defined using a variable:

import dash
from dash import html

dash.register_page(__name__)

layout = html.Div(
        [
            html.H1("This is our Archive page"),
            html.Div("This is our Archive page content."),
        ]
    )

In theory they’re each valid, and will each work, as may be seen from the official documentation.

On the whole, assigning to a variable will work . Nevertheless, there are specific circumstances where passing variables between separate files/folders will fail. Whereas, using functions will at all times work.

Unfortunately, I cannot recall an example, but I actually have experienced this primary hand, which is why this framework religiously uses functions if elements are required to be passed between files/folders within the code.

Regardless, using functions is arguably a rather more transparent and accountable way of coding, and in the long term makes rather more sense.

Variable Typing

Chances are you’ll note that variable typing has been included on all functions.

Because the codebase is written in Python this will not be strictly mandatory. The hope is that it would help with transparency when persons are reading the codebase and attempting to get their head around how the several pieces fit together.

For those who find it confusing, or not helpful, then it could at all times be removed with none sick effects.

For instance, changing this:

def get_graph(index: str) -> dmc.Skeleton:

to this:

def get_graph(index):

Is perfectly OK.

The Repository

the GitHub repository that contains the code base associated with this article
The GitHub page where you may access the DASH project structure discussed in this text – Image by Creator

A completely working example Dash app, using the structure covered in this text, is on the market on my GitHub repository here:

Plotly Dash Mulit-Page App

The repository may be cloned and run on to see how things work, or used as a place to begin for your individual project.

Basic Usage

a poster with the word instructions written in bold. Mounted on a rusty metal structure
Photo by Eder Pozo Pérez on Unsplash

To run the code within the repository take the next steps.

Create your virtual environment and install packages

Create your virtual environment and activate it. You’ll be able to do that nevertheless you select. For instance:

cd project-folder 
python -m venv venv 
source venv/bin/activate

Then install the required packages:

pip install --upgrade pip
pip install -r requirements.txt

Create a “.env” file

The project uses python-dotenv to maintain things like API Keys out of the project code through the use of an area file to store sensitive data. As such, you won’t find this file included within the repository. You have to to create your individual.

In the foundation of the project folder create a file with the name: .env.
For example of what to incorporate within the file, the next is what may very well be utilized in an area development environment:

DEBUG = True 
NINJAS_API_KEY = "s0L889BwIkT2ThjHDROVGH==fkluRlLyGgfUUPgh"

Note:

Inside a live / development environment it is best to change the DEBUG value to False.

Utilising this method has the advantage of having the ability to use Git to update code between the event and production environments, without having to vary the DEBUG value within the .env file each time.

That is because of the .env not being included within the Git repository, and subsequently being exclusive to the machine/server it’s created on.

Run the Project

To run the project just execute the next line from inside the project directory:

python fundamental.py

You’ll then be told the local IP address that you would be able to open in a browser to access the project front end.

Conclusion

Hopefully this text, and the associated Github repository provide place to begin to start your journey into using Plotly Dash to create your individual dashboards, and even just get some idea of methods to move to the following stage.

If you may have any comments, or improvements, with regard to the code, please be at liberty to either comment on this text, or open a difficulty / pull request on the associated GitHub repository.

References

Plotly DASH
DASH Mantine Components
GAPMINDER.ORG, CC-BY LICENSE

ASK ANA

What are your thoughts on this topic?
Let us know in the comments below.

0 0 votes
Article Rating
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Share this article

Recent posts

0
Would love your thoughts, please comment.x
()
x