Interactive Dashboards and Data Apps with Plotly and Dash

By Elias Dabbas
    Advance your knowledge in tech with a Packt subscription

  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Chapter 1: Overview of the Dash Ecosystem

About this book

With Plotly's Dash framework, it is now easier than ever for Python programmers to develop complete data apps and interactive dashboards. Dash apps can be used by a non-technical audience, and this will make data analysis accessible to a much wider group of people. This book will help you to explore the functionalities of Dash for visualizing data in different ways and getting the most out of it.

The book starts with an overview of the Dash ecosystem, its main packages, and the third-party packages crucial for structuring and building different parts of your apps. You'll learn how to create a basic Dash app and add different features to it. Next, you’ll integrate controls such as dropdowns, checkboxes, sliders, date pickers, and more in the app and then link them to charts and other outputs. Depending on the data you are visualizing, you'll also add several types of charts, including scatter plots, line plots, bar charts, histograms, and maps, as well as explore the options available for customizing them.

By the end of this book, you'll have developed the skills you need to create and deploy an interactive dashboard, handle complexities and code refactoring, and understand the process of improving your application.

Publication date:
May 2021
Publisher
Packt
Pages
364
ISBN
9781800568914

 

Chapter 1: Overview of the Dash Ecosystem

One of the few constants in our work with data is the amount of change in the volume, sources, and types of data that we deal with. Being able to quickly combine data from different sources and explore them is crucial. Dash is not only for exploring data; it can be used for almost all phases of the data analysis process, from exploration to operational production environments.

In this chapter, we will get an overview of Dash's ecosystem and focus on building the layout, or the user-facing part, of the app. By the end of the chapter, you will be able to build a running app with almost any visual component you want, but without interactivity.

The following topics will be covered:

  • Setting up your environment
  • Exploring Dash and other supporting packages
  • Understanding the general structure of a Dash app
  • Creating and running the simplest app
  • Adding HTML and other components to the app
  • Learning how to structure the layout and managing themes
 

Technical requirements

Every chapter will have slightly different requirements, but there are some that you will need throughout the book.

You should have access to Python 3.6 or higher, which can be easily downloaded from https://www.python.org, as well as a text editor or an integrated development environment (IDE) so you can edit code.

For this chapter, we will be using Dash, Dash HTML Components, and Dash Bootstrap Components, which can be installed together with all other required packages by following the instructions in the following section. All code and data required for this book can be downloaded from the book's GitHub repository, which can be found athttps://github.com/PacktPublishing/Interactive-Dashboards-and-Data-Apps-with-Plotly-and-Dash. As I just mentioned, the following section will show in detail how to get started with your setup.

The code files of this chapter can be found on GitHub at https://github.com/PacktPublishing/Interactive-Dashboards-and-Data-Apps-with-Plotly-and-Dash/tree/master/chapter_01.

Check out the following video to see the Code in Action at https://bit.ly/3atXPjc.

 

Setting up your environment

With the fast pace of change in all the packages used in the book, you will most likely come across some differences in functionality, so in order to reproduce the exact outcomes described in the book, you can clone the book's repository, install the packages used (in the specified versions), and use the included dataset. From the command line, go to a folder in which you want to build the project and do the following:

  1. Create a Python virtual environment in a folder called dash_project (or any other name you want). This will also create a new folder with the name you chose:
    python3 –m venv dash_project
  2. Activate the virtual environment.

    On Unix or macOS, run this:

    source dash_project/bin/activate

    On Windows, run this:

    dash_project\Scripts\activate.bat
  3. Go to the created folder:
    cd dash_project
  4. Clone the book's GitHub repository:
    git clone   https://github.com/PacktPublishing/Interactive-Dashboards-and-Data-Apps-with-Plotly-and-Dash 
  5. You should now have a file containing the required packages and their versions called requirements.txt. You can install those packages by going to the repository's folder and running the install command as follows:
    cd Interactive-Dashboards-and-Data-Apps-with-Plotly-and-Dash/
    pip install -r requirements.txt

You should find a copy of the dataset in the data folder, which was downloaded from this link: https://datacatalog.worldbank.org/dataset/poverty-and-equity-database. You can get the latest version if you want, but as with packages, if you want to get the same results, it's better to work with the provided dataset.

In order for Plotly figures and apps to be displayed in JupyterLab, you will need to install Node.js, which can be install from https://nodejs.org.

You will also need to install the JupyterLab Plotly extension, which can be done by running the following from the command line in your virtual environment:

jupyter labextension install [email protected]

Note that the version number at the end should correspond to the version of Plotly that you are running. You can replace the preceding version numbers if you want to upgrade (making sure to upgrade the Plotly Python package as well).

Once you have run the preceding code, you should have everything you need to follow along. You will see that each chapter of this book builds on the previous one: we will be building an app that adds more and more functionality and complexity as we go through the chapters.

The main objective is to put you in a practical setting as much as possible. In general, it is straightforward to create any standalone Dash component, but it gets more challenging when you already have a few components in a running app. This becomes clear when you have to decide how to change the layout to accommodate new changes and how to refactor code, focusing on the details without losing sight of the big picture.

Now that the environment has been established, let's get an overview of Dash.

 

Exploring Dash and other supporting packages

Although not strictly necessary, it's good to know the main components that are used to make Dash and its dependencies, especially for more advanced usage, and in order to know how and where to get more information:

Figure 1.1 – What Dash is made of

Figure 1.1 – What Dash is made of

Note

One of the main advantages of using Dash is that it allows us to create fully interactive data, analytics, and web apps and interfaces, using pure Python, without having to worry about HTML, CSS, or JavaScript.

As you can see in Figure 1.1, Dash uses Flask for the backend. For producing charts, it uses Plotly, although it is not strictly required, but it is the best-supported package for data visualization. React is used for handling all components, and actually a Dash app is rendered as a single-page React app. The most important things for us are the different packages that we will be using to create our app, which we will be covering next.

Tip

For people who are familiar with or invested in learning Matplotlib, there is a special set of tools to convert Matplotlib figures to Plotly figures. Once you have created your figure in Matplotlib, you can convert it to Plotly with one command: mpl_to_plotly. As of the time of this writing, this is supported for Matplotlib<=3.0.3 only. Here is a full example:

%config InlineBackend.figure_format = 'retina'
import matplotlib.pyplot as plt
from plotly.tools import mpl_to_plotly
mpl_fig, ax = plt.subplots()
ax.scatter(x=[1, 2, 3], y=[23, 12, 34])
plotly_fig = mpl_to_plotly(mpl_fig)
plotly_fig

The different packages that Dash contains

Dash is not one big package that contains everything. Instead, it consists of several packages, each handling a certain aspect. In addition, as we will see later, there are several third-party packages that are used, and the community is encouraged to develop their own functionality by creating special Dash packages.

The following are the main packages that we will mostly be using in this chapter, and we will explore others in later chapters:

  • Dash: This is the main package, which provides the backbone of any app, through the dash.Dash object. It also provides a few other tools for managing interactivity and exceptions, which we will get into later as we build our app.
  • Dash Core Components: A package that provides a set of interactive components that can be manipulated by users. Dropdowns, date pickers, sliders, and many more components are included in this package. We will learn how to use them to manage reactivity in Chapter 2, Exploring the Structure of a Dash App, and will be focusing on how to use them in detail in Part 2 of the book.
  • Dash HTML Components: This package provides all the available HTML tags as Python classes. It simply converts Python to HTML. For example, you can write dash_html_components.H1('Hello, World') in Python, and it will be converted to <h1>Hello, World</h1> and rendered as such in the browser.
  • Dash Bootstrap Components: This is a third-party package that adds Bootstrap functionality to Dash. This package and its components take care of a lot of options related to layouts and visual signals. Laying out elements side by side or on top of one another, specifying their sizes based on the browser's screen size, and providing a set of encoded colors for better communicating with users are some of the benefits of using it.

    Tip

    The recommended way to install the main packages of Dash is to simply install Dash, and it will automatically handle installing the other packages, ensuring that they get installed with the correct versions. Simply run pip install dash from the command line. For upgrades, that would be pip install dash --upgrade.

We will now take a brief look at the general structure of a typical Dash app, after which we will start coding.

 

Understanding the general structure of a Dash app

The following diagram shows what generally goes into creating a Dash app. We typically have a file called app.py, although you can name it whatever you want. The file is shown as the column on the right, with the different parts split by lines, just to visually distinguish between them, while on the left is the name of each part:

Figure 1.2 – The structure of a Dash app

Figure 1.2 – The structure of a Dash app

Let's look at each app part in detail:

  • Imports (boilerplate): Like any Python module, we begin by importing the required packages, using their usual aliases.
  • App instantiation: A straightforward way to create the app, by creating the app variable in this case. The __name__ value for the name parameter is used to make it easy for Dash to locate static assets to be used in the app.
  • App layout: The subject of this chapter, which we will focus on in detail. This is where we set the user-facing elements, or the frontend. We usually define a container element, html.Div in the figure, that takes a list of components for its children parameter. These components will be displayed in order when the app renders, each placed below the previous element. In the following section, we will create a simple app with a minimal layout.
  • Callback functions: This is the subject of Chapter 2, Exploring the Structure of a Dash App, where we will go through how interactivity works in detail; this won't be covered in this chapter. For now, it's enough to know that this is where we define as many functions as needed to link the visible elements of the app to each other, defining the functionality that we want. Typically, functions are independent, they don't need to be defined within a container, and their order does not matter in the module.
  • Running the app: Using the Python idiom for running modules as scripts, we run the app.

As I promised, we are now ready to start coding.

 

Creating and running the simplest app

Using the structure that we just discussed, and excluding callback functions, let's now build our first simple app!

Create a file and name it app.py, and write the following code:

  1. Import the required packages using their usual aliases:
    import dash
    import dash_html_components as html
  2. Create (instantiate) the app:
    app = dash.Dash(__name__)
  3. Create the app's layout:
    app.layout = html.Div([
        html.H1('Hello, World!')
    ])
  4. Run the app:
    if __name__ == '__main__':
        app.run_server(debug=True)

A few points before running the app. First, I strongly suggest that you don't copy and paste code. It's important to make sure you remember what you coded. It's also useful to explore the possibilities provided by each component, class, or function. Most IDEs provide hints on what is possible.

This app's layout contains one element, which is the list passed to html.Div, corresponding to its children parameter. This will produce an H1 element on the page. Finally, note that I set debug=True in the app.run_server method. This activates several developer tools that are really useful while developing and debugging.

You are now ready to run your first app. From the command line, in the same folder where you saved your app file, run this:

python app.py 

You might need to run the preceding command using python3 if your system is not configured to use version three by default:

python3 app.py

You should now see an output like that shown in Figure 1.3, indicating that the app is running:

Figure 1.3 – Command-line output while running the app

Figure 1.3 – Command-line output while running the app

Congratulations on running your very first Dash app! Now, if you point your browser to the URL shown in the output, http://127.0.0.1:8050, you should see the "Hello, World!" message in H1 on the page. As you can see, it shows that it is serving a Flask app called "app," with a warning that this server is not designed for production use. We will cover deployment in a later chapter, but this server is good enough for developing and testing your apps. You can also see that we are in debug mode:

Figure 1.4 – App rendered in the browser

Figure 1.4 – App rendered in the browser

As specified, we see the text in H1, and we can also see the blue button as well. Clicking on this button will open some options in the browser, and it will be more useful once there are callback functions and/or errors while running the app. We wouldn't have gotten the blue button if we had run the app with debug=False, which is the default.

Now that we have established a good-enough understanding of the main elements that go into creating a Dash app, and we have run a minimal one, we are ready to explore two packages that are used for adding and managing visible elements: first, Dash HTML Components, and after that, we will explore how to use Dash Bootstrap Components.

 

Adding HTML and other components to the app

From now until the end of this chapter, we will mainly be focusing on the app.layout attribute of our app and making changes to it. It's straightforward to do so; we simply add elements to the top-level html.Div element's list (the children parameter):

html.Div(children=[component_1, component_2, component_3, …])

Adding HTML components to a Dash app

Since the available components in the package correspond to actual HTML tags, it is the most stable package. Let's quickly explore the parameters that are common to all its components.

At the time of this writing, Dash HTML Components has 131 components, and there are 20 parameters that are common to all of them.

Let's go over some of the most important ones that we will frequently be using:

  • children: This is typically the main (and first) container of the content of the component. It can take a list of items, or a single item.
  • className: This is the same as the class attribute, only renamed as such.
  • id: While we won't be covering this parameter in this chapter, it is the crucial one in making interactivity work, and we will be using it extensively while building the app. For now, it's enough to know that you can set arbitrary IDs to your components so you can identify them and later use them for managing interactivity.
  • style: This is similar to the HTML attribute of the same name, but with a few differences. First, its attributes are set using camelCase. So, say you wanted to set the following attributes in Dash HTML Components:
    <h1 style="color:blue; font-size: 40px; margin-left: 20%">A Blue Heading</h1>

    You would specify them this way:

    import dash_html_components as html
    html.H1(children='A Blue Heading',
            style={'color': 'blue',
                   'fontSize': '40px',
                   'marginLeft': '20%'})

    As you have most likely noticed, the style attribute is set using a Python dictionary.

The other parameters have different uses and rules, depending on the respective component that they belong to. Let's now practice adding a few HTML elements to our app. Going back to the same app.py file, let's experiment with adding a few more HTML elements and run the app one more time, as we just did. I kept the top and bottom parts the same, and I mainly edited app.layout:

…
app = dash.Dash(__name__)
app.layout = html.Div([
    html.H1('Poverty And Equity Database',
            style={'color': 'blue',
                   'fontSize': '40px'}),
    html.H2('The World Bank'),
    html.P('Key Facts:'),
    html.Ul([
        html.Li('Number of Economies: 170'),
        html.Li('Temporal Coverage: 1974 - 2019'),
        html.Li('Update Frequency: Quarterly'),
        html.Li('Last Updated: March 18, 2020'),
        html.Li([
            'Source: ',
          html.A('https://datacatalog.worldbank.org/dataset/poverty-and-equity-database',         href='https://datacatalog.worldbank.org/dataset/poverty-and-equity-database')
        ])
    ])
])
…
python app.py

That should produce the following screen:

Figure 1.5 – Updated app rendered in the browser

Figure 1.5 – Updated app rendered in the browser

Tip

If you are familiar with HTML, this should look straightforward. If not, please check out a basic tutorial online. A great source to start would be W3Schools: https://www.w3schools.com/html/.

In the updated part, we just added a <p> element and an unordered list, <ul>, within which we added a few list items, <li> (using a Python list), the last of which contained a link using the <a> element.

Note that since these components are implemented as Python classes, they follow Python's conventions of capitalizing class names: html.P, html.Ul, html.Li, html.A, and so on.

Feel free to experiment with other options: adding new HTML components, changing the order, trying to set other attributes, and so on.

 

Learning how to structure the layout and managing themes

So far, we have discussed the basic structure of a Dash app and gone through a brief overview of its main elements: the imports, app instantiation, app layout, callbacks (which we will cover in the next chapter), and running the app. We created a bare-bones app, and then we learned how to add a few HTML elements to it. We are now ready to take our app to the next level—from a layout perspective. We will keep working with the app.layout attribute and control it in a more powerful and flexible way using the Dash Bootstrap Components package.

Bootstrap is basically a set of tools that abstract away many details for handling the layout of web pages. Here are some of the most important benefits of using it:

  • Themes: As we will see in a moment, changing the app's theme is as simple as providing an additional argument while instantiating the app. Dash Bootstrap Components ships with a set of themes that you can select from and/or edit.
  • Grid system: Bootstrap provides a powerful grid system, so we can think about our pages more from a user perspective (rows and columns) and not have to focus on the screen attributes (pixels and percentages), although we still have access to those low-level details whenever we need to.
  • Responsiveness: Having a large number of possible screen sizes makes it almost impossible to properly design page layouts. This is handled for us, and we can also fine-tune the behavior of page elements to control how their sizes change as the screen size changes.
  • Prebuilt components: A set of prebuilt components is also provided, which we will be using. Alerts, buttons, drop-down menus, and tabs are some of the components that Bootstrap provides.
  • Encoded colors: We also get a set of colors for easy communication with users, in case we have a warning, an error, simple information, and so on.

Let's explore these features one by one.

Themes

First, let's see how easy it is to change the theme of an app. In the same app.py file, add the following import and the new argument to the app creation call:

import dash_bootstrap_components as dbc
…
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
…

Running the app again, you should see that the theme has changed. As shown in Figure 1.6, you can also see other sample themes, and I also added their names and how to set them at the bottom of each page:

Figure 1.6 – Theme samples and how to set them

Figure 1.6 – Theme samples and how to set them

You can see how easy it is to completely change the look and feel of the app, simply by changing one argument. Note also that the color and font size of the <h1> element were overridden in the style argument. We specifically set the color to "blue" and the size to "40px". Usually, this is not advisable; for example, in the two dark themes in the figure it is very difficult to read the blue text. So, be careful when you make such changes.

Grid system and responsiveness

Another powerful benefit that we get from Bootstrap is its grid system. When adding Dash HTML Components, we saw that we can do so by appending items to the children parameter of the main html.Div element. In this case, every added item occupies the full width of the screen and takes as much screen height as it needs to display its contents. The order of the elements in the list determines their order of display on the screen as well.

Displaying elements side by side in columns

While it's possible to do this by editing the style parameter of any HTML element, it is a bit tedious and can be brittle. You have to worry about too many details, and it might break in unexpected ways. With Bootstrap, you simply define a column, and that in turn behaves as an independent screen, displaying its elements on top of one another, with each element occupying the full width of this mini screen. Columns' widths can also be specified in powerful and flexible ways. The grid system divides the screen into 12 columns, and the width of a column can be specified by using a number from 1 to 12 inclusive. Figure 1.7 shows how the columns can be defined, and how they would change for screens of different size:

Figure 1.7 – The same column layout on two screen sizes

Figure 1.7 – The same column layout on two screen sizes

As you can see, the two screens are identical, and the resizing happens automatically, while maintaining the proportions.

In many cases, this might not be exactly what you want. When the screen width becomes smaller, it might make more sense to expand the columns to be more easily readable by the users. For this, we have the option of specifying the width of columns for each of five possible screen widths: xs (extra-small), sm (small), md (medium), lg (large), and xl (extra-large). These are also the names of the parameters that you can set:

Figure 1.8 – Granular control of column width based on screen size

Figure 1.8 – Granular control of column width based on screen size

Figure 1.8 shows how this is achieved by setting two arguments for the column. The way to set these values is simple, as indicated in the figure. The full code would be something like this:

import dash_boostrap_components as dbc
dbc.Col(children=[child1, child2, …], lg=6, md=12)

The lg=6, md=12 arguments simply mean that we want this column to have a width of six when the screen is large (lg), which means 6 ÷ 12, or half the screen's width. On screens of medium size (md), set the column width to 12, which means the full width of the screen (12 ÷ 12).

You might be wondering how we can have the columns in the middle of the page, and not starting from the left, as is the case in Figures 1.7 and 1.8. The width and the different size parameters can also take a dictionary, one of the keys of which can be offset, and this is how you set its horizontal location on the screen:

dbc.Col(children=[child1, child2, …], lg={'size': 6, 'offset': 4}, md=12)

As you can see, lg became a dictionary where we indicated that we want that column to skip the first four columns from the left, and be displayed after that, in the specified size.

Finally, if you want to place multiple columns next to each other, you simply have to place them in a row (with Row), and they will be placed next to each other:

Figure 1.9 – Columns side by side in a row

Figure 1.9 – Columns side by side in a row

In order to produce the layout in Figure 1.9, we can simply place the three columns in a list and pass it as the children parameter to a row element:

dbc.Row([
    dbc.Col('Column 1', width=2),
    dbc.Col('Column 2', width=5),
    dbc.Col('Column 3', width=4),
])

Prebuilt components

While we won't cover them all, we will be using several of those components, and they are generally straightforward to create. Please check the documentation for ideas and details of each component: https://dash-bootstrap-components.opensource.faculty.ai/. We will shortly modify the app to include some prebuilt components.

Encoded colors

Although you can set any color you want for text, background colors, and many other elements using its hexadecimal representation, Bootstrap provides a set of named colors based on the type of information you are trying to convey. This can be set as the color parameter in several components, and it would have a visual meaning to users. For example, setting color="danger" would cause the component to appear in red, and color="warning" as yellow. The available color names are primary, secondary, success, warning, danger, info, light, and dark.

Adding Dash Bootstrap components to our app

We will now add two new related components to the app: Tabs and Tab. As you might have guessed, Tabs is simply a container of Tab components. The result we are aiming for is adding a little more information to the page, and organizing it under new tabs, as you can see in Figure 1.10:

Figure 1.10 – Adding tabs to the app

Figure 1.10 – Adding tabs to the app

Tip

One of the most important skills to develop while learning Dash is code refactoring. While the latest version of the app is still very simple, it is a very good idea to make sure you know how to manually refactor the code from the previous version to the new one. The more components you have in your app, the more attention you will need to give to the refactoring details. I suggest you always do this manually and do not simply copy and paste the latest version of the app.

In order to create the tabs, and get the new content in the form you see in Figure 1.10, you will need to make the following changes:

html.H2('The World Bank'),
dbc.Tabs([
    dbc.Tab([
        html.Ul([
            # same code to define the unordered list
        ]),
    ], label='Key Facts'),
    dbc.Tab([
        html.Ul([
            html.Br(),
            html.Li('Book title: Interactive Dashboards and Data Apps with Plotly and Dash'),
            html.Li(['GitHub repo: ',
                     html.A('https://github.com/PacktPublishing/Interactive-Dashboards-and-Data-Apps-with-Plotly-and-Dash',
                            href='https://github.com/PacktPublishing/Interactive-Dashboards-and-Data-Apps-with-Plotly-and-Dash')])
        ])
    ], label='Project Info')

As you can see, we have added one Tabs element, within which we added two Tab elements. In the first one, we simply used the same code that went into defining our ordered list. In the second, we added a similar unordered list with new content. OK, you can copy this part if you want! You can also see how to specify the labels of the tabs, by setting a value for the label parameter.

Now you can run your updated app again, and make sure that the new content went to the right place, and that the tabs work as expected.

We are now ready to add some interactivity to our app.

 

Summary

We have learned how to create a minimal app and saw indeed how simple the process is. We then explored the main Dash packages used to create visual elements on a web page. With what we covered in this chapter, you have enough information to create almost any layout, with any elements you want on a page. The discussion and examples were not comprehensive, however. We will be using and discussing those components and many others, so you can master their use.

In the next chapter, we will turn our attention to the mechanism of adding interactivity to our app. We will set up the app such that the user will be able to explore different options by selecting what exactly they would like to analyze from our dataset.

About the Author

  • Elias Dabbas

    Elias Dabbas is an Online marketing expert who owns the company, The Media Supermarket. He has experience in Python open-source development, data visualization, data manipulation, building interactive data apps, and dashboards. He works in Online marketing, SEO, SEM, data science fields. He has experience in building custom dashboards as well as data-driven strategies and implementations for companies in different industries.

    Browse publications by this author
Book Title
Unlock this book and the full library for only $5/m
Access now