Step-by-step guide to your first interactive dash app — Part III

Paolo Molignini, PhD
10 min readOct 26, 2022

--

This is the third part of my guide to writing and deploying a dash app for data visualization. If you haven’t read parts I & II, you can find them here and here, respectively. This will also tell you which Python packages need to be installed on your system. The repository for the monkeypox-tracking app that we are using as an example can be found here.

So far, we have talked about the data and folder structure for our app and its main module app.py. We have learned the sequence of commands that need to be executed to initialize the app, define its layout and callbacks, and launch it. Today, we will look in more detail at the structure of the layout, which forms the skeleton of our app. The layout is just a sequence of nested components that determine the look of your app from top to bottom. Some components are just simple wrappers of HTML tags like <div>, <p>, <a> etc. but you can have more complex functionalities in the dash core components or dash bootstrap components.

There are numerous components that you can choose from, depending on your needs. I like to divide them roughly in “action” components, i.e. those ones that receive an input from the user, and “reaction” components, i.e. those ones that change once an action is performed. In the “action” category we find buttons (all kinds: single-click, radio buttons, multiple choice…), sliders, range pickers (such as date and time pickers), input fields etc. In the “reaction” category we find displayed text, figures, panels, graphs, etc. Of course this distinction is not sharp. You can for instance code a button that generates other buttons, a clickable figure etc. But I think it’s neat to have at least a conceptual distinction of components that you want to use as “knobs” and components that you want to use as displays.

Let’s go through the layout of the monkeypox app and see what components we encounter and what their function is. The layout is generated by the function get_layout in module layout, which directly returns a massive layout object.

Dash HTML components

As mentioned, there are numerous HTML wrappers in Dash. A comprehensive list can be found here. The “outermost” component of a layout is typically a html.Div component, which is just a wrapper of the <div> HTML tag used to create different blocks of content in the page. The list of tag wrappers is very long: <div>, <p>, <H1> and all other headers, <a>, <br>, <center>, … All of those tags have Dash wrappers.

The general syntax for an HTML component in Dash is

html.Component(options, children=[list])

where in options you can specify style elements for the component, such as background color, font size etc., and children is everything else contained in the component (you don’t have to specify the variable name “children” if it’s the first thing appearing in your component). In our first Div component (see below), for instance, children is a list of other components that will appear in sequence throughout the page. This list starts with a break component (html.Br()), a wrapper for the HTML <br> tag that just leaves an empty line. It is then followed by a html.Center component that in turn contains an html.H2 component. These are respectively a wrapper for the center tag (to center the text that follows) and a wrapper for a header of type H2 (just text). Note that the text is written as f”Confirmed monkeypox cases as of {current_date_str}”, i.e. in the format

f”some text {some_variable}”

which allows us to print the string of the current date directly in the text.

The first components in the layout.

In the html.H2 component we encounter one more variable which is at the core of our app’s dynamical behavior: id. The purpose of the id is to identify the component uniquely with a string, such that we can refer to it with our callbacks. Not all components in the monkeypox app have an id. For instance, the html.Br components don’t have an id, because they never appear in any callback. However, when components do have an id, it should be unique, otherwise the callback function will not know which component it needs to refer to. Therefore, it’s always good to give them a very clear and meaningful name. In the case above, the id of the html.H2 component is ‘first-text’ because it is literally the first text that appears on top of the page. We will see later on how the text can be modified via a callback whenever we change the reference date.

dbc.Row and dbc.Col

The first dbc.Row and dbc.Col components

After the components that wrap the first text on top of the page, we encounter two very useful dash bootstrap components wrapped in the next division: dbc.Row and dbc.Col. These components are used to create a table structure in how the components are displayed. In our app, we have a first row (starting at line 28) containing two columns, and then later on (line 57) another row containing three columns. Each column contains a different component. As you can see the syntax for dbc.Row is

dbc.Row(children=[list of Cols], options)

That means that the Col components should always be used as immediate children of Row. Options tells us how to position the row. In our case, we align it in the center of the window with justify=”center”.

Let’s examine the content of our dbc.Col a bit closer. In the first row, we have first a simple header displayed, with the text “Choose a date”, followed by a dash core component, dcc.DatePickerSingle. This is a very useful component that displays a calendar from which the user can choose a particular date. In our case, the chosen date will be used to display the number of confirmed monkeypox cases recorded worldwide until that given date.

Apart from the id, needed for the callback, we can recognise several different options in the date picker. Here is a quick explanation of each (the date variables must be datetime.date objects):

  • min_date_allowed: the oldest date that can be selected .
  • max_date_allowed: the most recent date that can be selected.
  • initial_visible_month: the first month that is displayed in the picker.
  • date: the initially selected date.
  • disabled_days: a list of non-clickable dates. For our monkeypox app, these are dates for which no data was available.
  • style: a dictionary containing information about how the picker will look like.

dcc.Graph

The graph component display the choropleth map.

After this series of rows and columns, we encounter a new dash core component encased in a html.Center component: dcc.Graph. This is a very important component that allows you to display any plotly-powered graphical elements such as plots, charts, diagrams, figures, and more. In our monkeypox app, the figure displayed will be the choropleth worldmap that highlights the monkeypox cases, which we will discuss in more detail in part V. For now, the most important thing to remember about the Graph component is its syntax:

dcc.Graph(id=’your_chosen_id’, figure=your_chosen_figure, options)

The figure that should be passed to the Graph component should be a plotly-compatible graphical object (go). For instance, in the monkeypox app we use go.Figure here and go.Scatter for another graph below. For a detailed list of options, see here.

Dropdown menus and Buttons

The first dbc.Col components of the second dbc.Row component.

To have any “reactive” functionality as mentioned above, it’s very useful to build selectors and buttons in your app. We have seen a date picker already. In the next component we will discuss two more useful components: dropdown menus and buttons. In principle, one can build callbacks that react already when some data in a picker or dropdown menu (or any menu) is selected. However, this is not very practical when you want to change many parameters at once to tune your app. Instead, it might be more efficient to just activate the callbacks upon clicking a single button, after the state of the various menus has been changed. We will discuss this in part VI when we go over the details of our callbacks. For now let’s just examine the structure of these “reactive” components.

In the monkeypox app, these components are arranged into rows and columns via the dbc.Col and dbc.Row components that we’ve seen before. In the second column of the first row, buried in a list of nested Div components, we encounter our first dbc.DropdownMenu component (note that there exists also a dcc.Dropdown component, but I prefer the dbc version here because it’s somewhat more flexible).

DropdownMenu will create a button that displays the menu itself upon clicking. This is pretty neat, because this action doesn’t require any extra callbacks! The style of the button can be overridden with custom CSS, and the behavior of the toggle can be modified with many options, see here. For instance, you can use “direction” argument to control where the menu is rendered relative to the button. The children of this component should be a single dash component or a list of components. One common possibility is

children = [dbc.DropdownMenuItem(“Item 1”), dbc.DropdownMenuItem(“Item 2”), …]

In our app, instead, we include an additional functionality to the DropdownMenu, namely we make all entries in the list clickable by passing a dbc.Checklist component as children (lines 70–82). The aim of this combination of dbc.DropdownMenu and dcc.Checklist is to select a few of the countries with available data to display their historic data in the second graph that will appear below. Here is a brief breakdown of the arguments of dcc.Checklist that we use in the app:

- options: this is the list of all possible (clickable) elements in the checklist. We pass the list of all available countries.
- value: this is a list of those elements listed in options that will appear as selected the first time we open the dropdown menu.
- labelStyle: a dictionary to control the appearance of the labels.
- style: another dictionary that controls the appearance of the dropdown menu box itself, e.g. its size, whether the list will scroll or not, etc.
- id: the component’s id.

Note that the width this latest dbc.Col component containing the dropdown menu is different than the ones we used so far, namely it has width=3. This argument is used to modify the horizontal space occupied by the column. The documentation of the dash bootstrap components explains in detail how width argument controls the width of the columns. In a nutshell:

  • “True” is the default and will make the column expand to fill all available space.
  • With “auto”, the column will take as much space as the natural width of its content.
  • You can also pass an integer “1,…,12”, like in our case. Then the column will span this many of a 12-column grid. In other words, width=6 will span half the available space, width=3 will span a quarter, etc.
The second dbc.Col components containing a dropdown menu and a button.

Another variable that we want to have some input for is the days after which we start the exponential fit, which we will discuss in part IV. This comes in the form of another, simpler dcc.Dropdown component in the next column (line 100–104), which contains only the list [0, 10, 20, 30].

Finally, we want to be able to “activate” all the changes to the variables we have made when we want to refresh our app. This is what buttons are made for! A button, in this case a simple wrapper of the html button component, appears in the final dbc.Col component of this row (line 108). The children argument of this button component is just the text that will appear in the button (“Update”). The id is necessary because we will need to dynamically monitor the activity of this button via our callback. The argument that we will monitor is n_clicks, which counts the number of times the button has been clicked (and that’s why it’s initialized with zero).

If you are confused about all the different components and their arguments you have encountered in the layout so far, don’t worry. We will revisit everything again once we discuss the callback in more detail, and understand how all these components are related to each other via actions and reactions.

Sources

After this series of buttons, we have another dcc.Graph component (the figure showing the plot that we configured with the buttons!), always sandwiched by break components, and finally, we arrive at the end of the layout, where we list the sources used to gather the data presented in the app. The layout terminates with a very big Div component that contains just text and links, separated by breaks. The text is rendered with the html.P wrapper, while the links are given by the html.A wrappers.

A long Div component containing a series of text and links.

This concludes the third part of this guide. Of course I didn’t go through all the possible functionalities that a Dash layout can offer, but the components I discussed should hopefully be enough to build a first app with basic active and reactive features. I encourage you to browse the catalog of the numerous dcc and dbc components to take a look at which components are best suited for your needs!

Thanks for reading!

--

--

Paolo Molignini, PhD

Researcher in theoretical quantum physics at Stockholm University with a passion for programming, data science, and probability & statistics.