{"id":22438,"date":"2020-11-12T10:29:45","date_gmt":"2020-11-12T10:29:45","guid":{"rendered":"https:\/\/www.experfy.com\/blog\/professional-dashboard-with-dash-css-bootstrap\/"},"modified":"2021-05-21T03:34:46","modified_gmt":"2021-05-21T03:34:46","slug":"professional-dashboard-with-dash-css-bootstrap","status":"publish","type":"post","link":"https:\/\/www.experfy.com\/blog\/ai-ml\/professional-dashboard-with-dash-css-bootstrap\/","title":{"rendered":"Create A Professional Dashboard With Dash And CSS Bootstrap"},"content":{"rendered":"\n<p class=\"has-normal-font-size\"><em>A step-by-step explained example available on\u00a0<a href=\"https:\/\/github.com\/gabri-al\/corporate-dashboard\" target=\"_blank\" rel=\"noreferrer noopener\">Git<\/a>\u00a0and\u00a0<a href=\"https:\/\/corporate-dash.herokuapp.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">Heroku<\/a><\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"792f\">Introduction<\/h2>\n\n\n\n<p id=\"33d1\">In this article, I am going through the steps I followed to create an interactive dashboard, using PlotlyDash, a library for Python and R, and enhancing the layout with CSS Bootstrap.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Dash library is written on top of Flask, Plotly.js, and React.js, that allows to build data visualization apps in pure Python, rendered via the web browser.<\/p><\/blockquote>\n\n\n\n<p id=\"fc5a\">The final result I produced can be displayed here:\u00a0<a href=\"https:\/\/corporate-dash.herokuapp.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/corporate-dash.herokuapp.com\/<\/a><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/www.experfy.com\/blog\/wp-content\/uploads\/2021\/05\/1_EtYl5e8ahSVRI39xavE5A.png\" alt=\"Create A Professional Dashboard With Dash And CSS Bootstrap\"\/><figcaption>Image by author<\/figcaption><\/figure><\/div>\n\n\n\n<p id=\"9147\">This is a multi-page dashboard, simulating a business scenario, where there normally are some layout guidelines to be respected (corporate colours scheme, a pre-defined font, a corporate website that can inspire us, \u2026) and some sales-related KPIs to be monitored.<\/p>\n\n\n\n<p id=\"502c\">The first page is filled with different types of charts (scatter plots, bar charts, bubble charts, heat-maps) and a recap table, with random data; the other pages are blank, but useful to show how to build a multi-page structure.<\/p>\n\n\n\n<p id=\"5e1a\">In this article, I\u2019ll cover:<\/p>\n\n\n\n<p id=\"f3a6\"><a href=\"http:\/\/medium.com\/gabri-albini\/create-a-professional-dasbhoard-with-dash-and-css-bootstrap-e1829e238fc5#ab91\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>1. Dashboard Objectives<\/strong><\/a><\/p>\n\n\n\n<p id=\"1fd3\"><a href=\"http:\/\/medium.com\/gabri-albini\/create-a-professional-dasbhoard-with-dash-and-css-bootstrap-e1829e238fc5#b13a\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>2. Getting started with Dash<\/strong><\/a><\/p>\n\n\n\n<p id=\"a83c\"><a href=\"http:\/\/medium.com\/gabri-albini\/create-a-professional-dasbhoard-with-dash-and-css-bootstrap-e1829e238fc5#059c\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>3. Configuring the folder structure for a multi-page dashboard<\/strong><\/a><\/p>\n\n\n\n<p id=\"0580\"><a href=\"http:\/\/medium.com\/gabri-albini\/create-a-professional-dasbhoard-with-dash-and-css-bootstrap-e1829e238fc5#4adb\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>4. Conceptualizing the layout with the CSS Bootstrap Grid system<\/strong><\/a><\/p>\n\n\n\n<p id=\"6dfd\"><a href=\"http:\/\/medium.com\/gabri-albini\/create-a-professional-dasbhoard-with-dash-and-css-bootstrap-e1829e238fc5#469c\" target=\"_blank\" rel=\"noreferrer noopener\"><em>4.1 Building the layout framework with CSS Bootstrap<\/em><\/a><\/p>\n\n\n\n<p id=\"2f9a\"><a href=\"http:\/\/medium.com\/gabri-albini\/create-a-professional-dasbhoard-with-dash-and-css-bootstrap-e1829e238fc5#0767\" target=\"_blank\" rel=\"noreferrer noopener\"><em>4.2 Styling Dash components accessing to their CSS classes<\/em><\/a><\/p>\n\n\n\n<p id=\"a34a\"><a href=\"http:\/\/medium.com\/gabri-albini\/create-a-professional-dasbhoard-with-dash-and-css-bootstrap-e1829e238fc5#f8c5\" target=\"_blank\" rel=\"noreferrer noopener\">5.\u00a0<strong>Callbacks &amp; Components<\/strong><\/a><\/p>\n\n\n\n<p id=\"8301\"><a href=\"http:\/\/medium.com\/gabri-albini\/create-a-professional-dasbhoard-with-dash-and-css-bootstrap-e1829e238fc5#b179\" target=\"_blank\" rel=\"noreferrer noopener\"><em>5.1 Multi dropdown filter : how to have a \u201cSelect All\u201d option<\/em><\/a><\/p>\n\n\n\n<p id=\"7836\"><a href=\"http:\/\/medium.com\/gabri-albini\/create-a-professional-dasbhoard-with-dash-and-css-bootstrap-e1829e238fc5#a4a9\" rel=\"noopener\"><em>5.2 Unveiling seasonality patterns with Heatmaps<\/em><\/a><\/p>\n\n\n\n<p id=\"7ce4\"><a href=\"http:\/\/medium.com\/gabri-albini\/create-a-professional-dasbhoard-with-dash-and-css-bootstrap-e1829e238fc5#0d77\" target=\"_blank\" rel=\"noreferrer noopener\"><em>5.3 Providing additional information when hovering on data points<\/em><\/a><\/p>\n\n\n\n<p id=\"52dd\"><a href=\"http:\/\/medium.com\/gabri-albini\/create-a-professional-dasbhoard-with-dash-and-css-bootstrap-e1829e238fc5#fd73\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>6. How to deploy and share the dashboard<\/strong><\/a><\/p>\n\n\n\n<p id=\"d48b\"><a href=\"http:\/\/medium.com\/gabri-albini\/create-a-professional-dasbhoard-with-dash-and-css-bootstrap-e1829e238fc5#9a04\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>7. Conclusions<\/strong><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ab91\">1. Dashboard Objectives<\/h2>\n\n\n\n<p id=\"5cb7\">Dashboards are intended to provide a clear and accurate view on some business-relevant KPIs, enabling the end user to understand what\u2019s presented, find the information needed, apply some filters, and hopefully derive some conclusions.<\/p>\n\n\n\n<p id=\"8864\">This dashboard is designed like a website, composed by different pages with a top navigator bar.<\/p>\n\n\n\n<p id=\"24bf\"><strong>Each page content is divided into three parts:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Some top filters that can be applied to all the charts displayed in the page<\/li><li>A recap table, also displayed at the top, which enables the user to quickly have a glance on the main KPIs. Ideally, the intention is for the user to avoid going through each and every chart on the page, but immediately spot where to focus on just by looking at the recap table. This recap table has some conditional colour formatting, as a sort of traffic light, highlighting the positive \/ negative values.<\/li><li>Finally, a grid of charts, showing different views on the main KPIs<\/li><\/ul>\n\n\n\n<p id=\"7888\">I have deliberately avoided to offer any way for the user to export the underlying data: due to the raising concerns around data privacy and data loss, the dashboard is intended to use aggregated data only. Raw data points are unreachable to the end user.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"b13a\">2. Getting started with Dash<\/h2>\n\n\n\n<p id=\"3a49\">There are plenty of user guidelines and introductions to plotly Dash.<\/p>\n\n\n\n<p id=\"196c\">I\u2019ve personally found very useful to go through these sources, which explains plenty of examples:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>The official Dash website\u00a0<a href=\"https:\/\/dash.plotly.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/dash.plotly.com\/<\/a>\u00a0is very useful, easy to read and navigate, showing all available components and their main properties<\/li><li>This article explains a very complete and detailed example inside-out:\u00a0<a href=\"https:\/\/towardsdatascience.com\/how-to-build-a-complex-reporting-dashboard-using-dash-and-plotl-4f4257c18a7f\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/towardsdatascience.com\/how-to-build-a-complex-reporting-dashboard-using-dash-and-plotl-4f4257c18a7f<\/a><\/li><li>I\u2019ve also looked for a large amount of Youtube videos that shows how to create and customise basic Dash layouts and callbacks<\/li><\/ul>\n\n\n\n<p id=\"21ca\">Despite going through all these useful sources, I\u2019ve had to face many challenges, especially in order to understand how to customise Dash components the way I wanted.<\/p>\n\n\n\n<p id=\"9954\">For this reason, I will also focus on this aspect in the steps below: the enhanced features and the layout, the visual identify of the end result is a very important aspect that can make the difference.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"059c\">3. Configuring the folder structure for a multi-page dashboard<\/h2>\n\n\n\n<p id=\"04ac\">The app source-code files should be structured as recommended by the Dash guidelines (<a href=\"https:\/\/dash.plotly.com\/urls\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/dash.plotly.com\/urls<\/a>) to enable a multi-page navigation. Based on this guide, I\u2019ve used the following approach to minimise any code change or adaptation.<\/p>\n\n\n\n<p id=\"d0b9\"><strong>My root folder contains:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><em>app.py<\/em>\u00a0: this file is very basic and will only define the app variable needed by Flask. I\u2019ve simply followed the Plotly Dash guidelines to create this file.<\/li><li><em>index.py<\/em>\u00a0: this is a sort of navigator file, helping the app managing the URLs of the different pages. Also this file is very standard: I recommend to follow the Plotly Dash guidelines for it, as we just need to customise the pathnames to have this working.<\/li><li><em>layouts.py<\/em>\u00a0: all pages html layouts will be stored in this file. Given that some components (like the header or the navbar) have to be replicated on each page, I\u2019ve created some functions to return them, avoiding many repetitions within the code<\/li><li><em>callbacks.py<\/em>\u00a0: all callbacks (the functions behind the Dash components, that define the user interactions with the <a href=\"https:\/\/www.experfy.com\/blog\/bigdata-cloud\/the-list-of-graph-visualization-libraries\/\" target=\"_blank\" rel=\"noreferrer noopener\">graphs<\/a>) will be stored in this file<\/li><\/ul>\n\n\n\n<p id=\"7f3e\"><strong>Within the root folder, Dash will look for:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>a \u201c<em>data<\/em>\u201d subfolder: containing the underlying data of the dashboard<\/li><li>an \u201c<em>assets<\/em>\u201d subfolder: containing additional files, like: images; favorite icon, used by the browser; .css files<\/li><\/ul>\n\n\n\n<p id=\"3777\">If this structure is followed for the assets subfolder, the app will automatically detect and use the favico.ico file or the .css files, with no code needed! Just name an image like \u201cfavicon.ico\u201d and place it within root\/assets and Dash will automatically use it.<\/p>\n\n\n\n<p id=\"b829\">There are some additional files within the root folder (such as the .gitgnore, README.md, Procfile, requirements.txt) : these files are needed to deploy the app on Heroku or store the code on Git Hub.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"4adb\">4. Conceptualizing the layout with the CSS Bootstrap Grid system<\/h2>\n\n\n\n<p id=\"ed2b\">With the app folder structure in place, the next thing to configure is the overall layout of our pages. We can\u2019t talk about a web application layout without mentioning .css files, which centralise almost all layout properties and that can be read by the browser.<\/p>\n\n\n\n<p id=\"89a9\">In very few words, .css files define the properties (fonts properties, sizes, colors, backgounds, \u2026) of html components, also used by Dash.<\/p>\n\n\n\n<p id=\"8e21\">The App will start applying the layout properties to the corresponding html components, reading them from the .css files stored in the \u201cassets\u201d folder of the app.<\/p>\n\n\n\n<p id=\"31e1\">It is important to note that: if the properties for the same html component (eg. a H2 html title font family) is defined in multiple .css files, the last one read by the app will be applied (let\u2019s ignore the !important css suffix for now).<\/p>\n\n\n\n<p id=\"b44f\">CSS properties can also be defined by creating some custom \u201cclass\u201d, then assigned to the html components (like a div) we want to style.<\/p>\n\n\n\n<p id=\"f723\">In my example, I\u2019ve used 3 .css files, which I\u2019ve named with some leading numbers to ensure that they are read by the app in a specific order:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>A customised font, defining a new font family used by the app (you can download font families from google, copying their .css content. Note that, within the font file, there are some URLs, that the app will download. If your app will run in an offline environment, you should download the content of these URLs and place them in a subfolder: root\/assets\/fonts, adapting the url to this pathname, within the font .css file)<\/li><li>The bootstrap .css standard file, which I\u2019ll describe just below (I basically downloaded the official CSS file from the Bootstrap\u00a0<a href=\"https:\/\/getbootstrap.com\/docs\/3.4\/getting-started\/\" target=\"_blank\" rel=\"noreferrer noopener\">website<\/a>)<\/li><li>A \u201ccorporate-style.css\u201d containing all customisation I introduced on the layout<\/li><\/ul>\n\n\n\n<p id=\"fe48\">I\u2019ve seen that many Plotly Dash examples use a basic .css template (<a href=\"https:\/\/codepen.io\/chriddyp\/pen\/bWLwgP.css\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/codepen.io\/chriddyp\/pen\/bWLwgP.css<\/a>): this is not a requirement for the app and I chose not to use it for my dashboard (I\u2019ve used the official .css Bootstrap file, instead).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"469c\">4.1 Building the layout framework with CSS Bootstrap<\/h3>\n\n\n\n<p id=\"f5d4\">CSS Boostrap provides a lot of predefined .css properties, classes and layout features we can reuse. CSS Bootstrap is famous for the known \u201cgrid systems\u201d which helps to scale websites pages depending on the device sizes used.<\/p>\n\n\n\n<p id=\"8611\">In short, we can think of our webpage as a table of rows and up to 12-columns: our html components can be placed inside this grid, which will have a dynamic size, according to the screen of the device it is displayed on.<\/p>\n\n\n\n<p id=\"3f80\">I think this helped me a lot to obtain the layout I had in mind, which looked like the following:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/www.experfy.com\/blog\/wp-content\/uploads\/2021\/05\/1_J8Jkk69GuPHFmUWs5D7yQ.jpeg\" alt=\"Create A Professional Dashboard With Dash \"\/><figcaption>Image by author<\/figcaption><\/figure><\/div>\n\n\n\n<p id=\"8685\">I\u2019ve started thinking about the layout from the different sections (the \u201crows\u201d of my page), and then picturing in my mind the different columns of the dashboard.<\/p>\n\n\n\n<p id=\"9150\">I\u2019ve assumed that, like in a business scenario, some colours are already part of the corporate visual identity (in this case a sort of green palette with some pink elements) and I\u2019ve picked a nice font-family called Dosis.<\/p>\n\n\n\n<p id=\"22e6\">After that, I\u2019ve been creating the scheme in the picture, with the different placeholders and the columns Bootstrap .css classes I\u2019ve used.<\/p>\n\n\n\n<p id=\"8993\">Within the CSS Bootstrap grid system, different .div elements are nested, each with its class, starting from a row and then one or more columns. CSS Bootstrap has different columns classes, from col-1 to col-12, meaning that we can have the dynamic column width we wish, starting from a column which will be a 1\/12 of the max width, till a column which will use the full width available (12\/12). Within each column, it is possible to nest another row-columns sequence of .Div.<\/p>\n\n\n\n<p id=\"6ee8\">All these classes can be assigned to the html.Div([]) elements, within their className property.<\/p>\n\n\n\n<p id=\"a8e4\">This system helps to keep each section of the dashboard in order, with a designated area for each Dash component that is also dynamic to the screen used.<\/p>\n\n\n\n<p id=\"034a\">For instance, the following structure has been used to style the header, the navbar and the filters.<\/p>\n\n\n\n<p id=\"6183\">The&nbsp;<strong>header<\/strong>, consists of:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>An external html.Div component, which has a .css \u201crow\u201d class, styled with a background color<\/li><li>Three html.Div components, inside the row; each represents a \u201ccol\u201d .css class (remember that the total of these columns width must be equal to 12): a className=\u201d2-col\u201d div (a column of width 2\/12), which will be kept empty, just to ensure that the title is centred; a 8-col div, hosting the main page title, and finally another 2-col div, hosting the corporate logo image<\/li><\/ul>\n\n\n<div class='gist '><br \/><\/div>\n\n\n<p class=\"has-text-align-center has-small-font-size\">Image by author<\/p>\n\n\n\n<p id=\"9bee\">The&nbsp;<strong>navbar<\/strong>, consists of:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Two empty col-3 div at the sides of the row<\/li><li>Three central col-2 div, each will contain a dcc.Link Dash component, that can be used to switch from one page to the other. The dcc.Link page for the current page is styled differently, to highlight the page the user is on<\/li><\/ul>\n\n\n<div class='gist '><br \/><\/div>\n\n\n<p class=\"has-text-align-center has-small-font-size\">Image by author<\/p>\n\n\n\n<p id=\"3023\">The&nbsp;<strong>filters<\/strong>&nbsp;section consists of the following components:<\/p>\n\n\n\n<p id=\"d467\">Externally, we have a row and column div:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>An external html.Div that has a \u201crow sticky-top\u201d class. This is a Bootstrap class that is the same as a row but that sticks at the top of the page, even when the user scroll down.<\/li><li>Inside the row, there\u2019s a 12-col Div with some styling properties<\/li><\/ul>\n\n\n\n<p id=\"1cec\">Within the 12-col Div column, we have another \u201crow\u201d div containing the following set of columns:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Two empty col-2 div at the sides of the internal row<\/li><li>Two col-4 div, internally, each containing filter components: a dcc.DatePickerRange and two dcc.Dropdown componentes<\/li><\/ul>\n\n\n<div class='gist '><br \/><\/div>\n\n\n<p class=\"has-text-align-center has-small-font-size\">Image by author<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"0767\">4.2 Styling Dash components accessing to their CSS classes<\/h2>\n\n\n\n<p id=\"12b0\">Once the layout is defined, the next challenge, from a user-interface perspective, is to properly style each Dash component, such as date ranges (dcc.DatePickerRange), dropdown filters(dcc.Dropdown), etc.<\/p>\n\n\n\n<p id=\"c69e\">All of these components have a \u201cstyle\u201d property, where we can define the css properties we want to style, such as font-size, colour, white-space, and many more. Most of the layout enhancements we want to achieve, can be achieved defining the right css property, within the \u201cstyle\u201d of the Dash component. However, I faced different challenges in styling some features of these components, which seems inaccessible from their \u201cstyle\u201d properties. I\u2019ve read similar challenges online from many different users, wondering how to style certain feature or detail of these components.<\/p>\n\n\n\n<p id=\"e5bd\">I think the main challenge here is to identify what\u2019s the right CSS property that is used by Dash. There\u2019s in fact a method to point and click, or \u201cinspect\u201d each element on the page, and unveil the CSS property it is defined by.<\/p>\n\n\n\n<p id=\"514f\">We can in-fact run the app in the browser, right-click on the page and choose \u201cInspect\u201d: this will pop-up a window, on the right-side of the page, where we can navigate through the html and css code of the page. At the top of the page, we can click on this tool<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/www.experfy.com\/blog\/wp-content\/uploads\/2021\/05\/1PSXfVJoksw5wmxWhrf7aKA.png\" alt=\"Image for post\"\/><\/figure><\/div>\n\n\n\n<p class=\"has-text-align-center has-small-font-size\">Image by author<\/p>\n\n\n\n<p id=\"6247\">We can finally hover on the element we want to style and get all its CSS classes and properties to understand what to change \/ redefine.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"e7b5\">4.2.1 Examples: style a DatePickerRange element<\/h3>\n\n\n\n<p id=\"8554\">A DatePickerRange by default look like this:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/www.experfy.com\/blog\/wp-content\/uploads\/2021\/05\/1EJtXWdEe3Q83YAbnDClZ6Q.png\" alt=\"Create A Professional Dashboard With Dash And CSS Bootstrap\"\/><figcaption>Image by author<\/figcaption><\/figure><\/div>\n\n\n\n<p id=\"017f\">We can change the component layout from the \u201cstyle\u201d property and define the font-size, add a border with some colour, etc. But how to modify that arrow that separates the start date from the end date ? How to change the green colours highlighting the selected days or around the helper icon?<\/p>\n\n\n\n<p id=\"a79b\">These elements seem unreachable from the \u201cstyle\u201d property and we have to use a different method to change their layout properties. Within the browser, if we inspect and select the arrow, we\u2019ll see something like that:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/www.experfy.com\/blog\/wp-content\/uploads\/2021\/05\/1KkVwJ8M_b5sWxUNwSWLhzA.png\" alt=\"Create A Professional Dashboard With Dash And CSS Bootstrap\"\/><figcaption>Image by author<\/figcaption><\/figure><\/div>\n\n\n\n<p id=\"f048\">This component is using some CSS classes, that we can modify by adding some code into our custom CSS file, forcing the arrow to a new size:<\/p>\n\n\n<div class='gist '><br \/><\/div>\n\n\n<p class=\"has-text-align-center has-small-font-size\">Image by author<\/p>\n\n\n\n<p id=\"7fec\">Similarly, we can unveil how the change the calendar style by inspecting the calendar selection:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/www.experfy.com\/blog\/wp-content\/uploads\/2021\/05\/1gYUAd2SRdvb4GHH53wcBCw.png\" alt=\"Create A Professional Dashboard With Dash And CSS Bootstrap\"\/><figcaption>Image by author<\/figcaption><\/figure><\/div>\n\n\n\n<p id=\"86f4\">By analysing this element, it seems that \u201c.CalendarDay__selected\u201d is the CSS class for the date extremes that are selected, while \u201c.CalendarDay__selected_span\u201d is the CSS class used for all the days in between the two extremes. It is possible to use these classes to change the background colours of the calendar (and to define some layout modifications when hovering the mouse on the different days). I\u2019ve added the code below to the custom CSS file:<\/p>\n\n\n<div class='gist '><br \/><\/div>\n\n\n<p class=\"has-text-align-center has-small-font-size\" id=\"86f4\">Image by author<\/p>\n\n\n\n<p id=\"0a67\">(\u201c!important\u201d overrides any other layout definition for the same CSS element or class).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"cb36\">4.2.2 Example: style a dash_table.DataTable element<\/h2>\n\n\n\n<p id=\"60a5\">Another element which I found difficult to style was the DataTable that I used in the recap section at the top of the dashboard.<\/p>\n\n\n\n<p id=\"8d64\">DataTables have, by default, a feature that enables to select a cell, making it appear in a pink\/red background colour. Additionally, by using the default CSS Bootstrap file, a default setting will change the background colour to white for all the table rows we hover on.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/www.experfy.com\/blog\/wp-content\/uploads\/2021\/05\/1qCnQs6E6uUD0PivkeJYFQQ.png\" alt=\"Create A Professional Dashboard With Dash And CSS Bootstrap\"\/><figcaption>Image by author<\/figcaption><\/figure><\/div>\n\n\n\n<p id=\"b376\">I wanted to really change these two default properties which were clashing with my overall layout.<\/p>\n\n\n\n<p id=\"cec9\">First of all, the selectable cell is not actually a CSS property but a component property which can be disabled: adding \u201ccell_selectable = False\u201d within the creation of the DataTable removes this functionality.<\/p>\n\n\n\n<p id=\"7a13\">In order to change the row hovering colour, with the method explained before we can see that DataTable rows are actually &lt;tr&gt; &lt;\/tr&gt; html elements, with no particular CSS class associated.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/www.experfy.com\/blog\/wp-content\/uploads\/2021\/05\/18xNSPx4urI5lgi2Af6-zhA.png\" alt=\"Create A Professional Dashboard With Dash And CSS Bootstrap\"\/><figcaption>Image by author<\/figcaption><\/figure><\/div>\n\n\n\n<p id=\"a177\">In order to customize the background colour when hovering on rows, I\u2019ve added the following on the custom CSS file:<\/p>\n\n\n<div class='gist '><br \/><\/div>\n\n\n<p class=\"has-text-align-center has-small-font-size\" id=\"a177\">Image by author<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"f8c5\">5. Callbacks &amp; Components<\/h2>\n\n\n\n<p id=\"56de\">Once the dashboard layout has been defined and the chart and filter components have been placed on the page, let\u2019s move to the callbacks.<\/p>\n\n\n\n<p id=\"4970\">I\u2019ll go through some examples of Callbacks, focusing on the most troublesome that I\u2019ve used.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"b179\">5.1 Multi dropdown filter : how to have a \u201cSelect All\u201d option<\/h2>\n\n\n\n<p id=\"f868\">Dashboards very often include one or more dropdown filters, allowing the user to select one or multiple values at the same time.<\/p>\n\n\n\n<p id=\"548a\">In very simple cases, there shouldn\u2019t be any Callback \u201cbehind\u201d the dropdown component: the user selects one or more dropdown options; the selected values are normally \u201cinputs\u201d for other callbacks that adjust what\u2019s presented on charts.<\/p>\n\n\n\n<p id=\"96b0\">However, in more complex cases, we may want to have a multi-dropdown selection, where the options of a second dropdown depend on the selections of the first dropdown. In the example that I\u2019ve created, I have a country dropdown and a city dropdown: the city dropdown options, definitely depend on the country that has already been chosen.<\/p>\n\n\n\n<p id=\"f466\">To add some more complexity, I\u2019ve noticed there is not an out-of-the-box feature, in Dash, to \u201cSelect All\u201d. Especially in those cases where the dropdown options are long lists, it is highly recommended to add a way to \u201cSelect All\u201d, otherwise we would need to enter one by one all the options every time we want to analyse all values. Additionally, I also wanted to configure the dashboard in a way that \u201cno selection\u201d (ie. leave the dropdown blank) means that all options are considered.<\/p>\n\n\n\n<p id=\"4d47\">In order to achieve all the features described here, I\u2019ve followed the steps listed right below.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"e51f\">5.1.1 Create options lists<\/h3>\n\n\n\n<p id=\"772b\">First of all, I\u2019ve created a list of options for each of the Dropdown components. The data that I randomly created has the \u201cCountry\u201d information on one column, and the \u201cCity\u201d information on another. I\u2019ve simply created two unique lists, one for all possible cities and one for all possible countries and I\u2019ve added a \u201c(Select All)\u201d entry, which I wanted to have at the top of the option list.<\/p>\n\n\n\n<p id=\"b473\">Next, I\u2019ve included the Dropdown component on the page layout, simply specifying the \u201cmulti\u201d property:<\/p>\n\n\n<div class='gist '><br \/><\/div>\n\n\n<p class=\"has-text-align-center has-small-font-size\" id=\"b473\">Image by author<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"9f02\">5.1.2 Manage option lists dynamically<\/h3>\n\n\n\n<p id=\"e7dc\">I\u2019ve then defined a callback that takes as input the list of values (selections) from the first Dropdown and returns, as output, the list of options of the second Dropdown.<\/p>\n\n\n\n<p id=\"4c1e\">Given that the list of options depends on the values, I\u2019ve generated a dictionary where each key is a possible value of the first dropdown, and each value is a list of all possible options of the second dropdown. The result looks like the following:<\/p>\n\n\n\n<p id=\"059f\"><em>{Brasil : [Fortaleza, Rio De Janiero, Sao Paulo],<\/em><\/p>\n\n\n\n<p id=\"b233\"><em>Italy : [Milan, Venice], \u2026 }<\/em><\/p>\n\n\n\n<p id=\"ae7d\">To finalize the Callback, some key considerations are:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>the \u201cvalues\u201d from the first Dropdown will be a python list<\/li><li>this list may or may not contain the \u201cAll\u201d option<\/li><li>leaving the list of values empty, will mean that we\u2019ll have [\u2018\u2019] as input of our Callback<\/li><\/ul>\n\n\n\n<p id=\"7ee9\">As a first step, I\u2019ve created a variable (isselect_all), useful to determine if the user has left the first dropdown blank, or if the user chose \u201cSelect All\u201d, or neither of these two possibilities.<\/p>\n\n\n\n<p id=\"8c45\">In the first two cases, the callbacks simply returns a sorted list of all possible cities. Otherwise, the user is picking one or more countries individually, therefore I\u2019m using the previously created dictionary (that I named repo_groups_l1_l2) to calculate a sorted list of all possible cities.<\/p>\n\n\n<div class='gist '><br \/><\/div>\n\n\n<p class=\"has-text-align-center has-small-font-size\" id=\"8c45\">Image by author<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"a4a9\">5.2 Unveiling seasonality patterns with Heatmaps<\/h2>\n\n\n\n<p id=\"bf62\">Among all possible charts, Heatmaps are ideal whenever we\u2019d like to plot 3 dimensions and show seasonality or patterns in data. For instance, I\u2019ve included a heatmap to show sales trend across the year (week number in my case) and day of the week, to see if there is any seasonality on these two dimensions.<\/p>\n\n\n\n<p id=\"f53f\">The weekdays will be on the x-axis, the calendar week numbers will be on the y-axis; each cell will be colored depending on the sale volumes. The heatmap will also need to respond to filters (based on dates and on the city and country dropdowns).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"581f\">5.2.1 Heatmap: the layout<\/h3>\n\n\n\n<p id=\"1477\">First of all, let\u2019s include a placeholder for the heatmap within the dash layout. In the below code, the headtmap will be in the last column with the id \u201csales-weekly-heatmap\u201d:<\/p>\n\n\n<div class='gist '><br \/><\/div>\n\n\n<p class=\"has-text-align-center has-small-font-size\" id=\"1477\">Image by author<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"70b4\">5.2.2 Heatmap: callback overview<\/h3>\n\n\n\n<p id=\"f79d\">Then, let\u2019s move to the callback, which will have:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>inputs: the different filters \u2014 In my case these are the start and end date from the date picker and the \u201ccountry\u201d and \u201ccity\u201d dropdown selections<\/li><li>output: the above dcc.Graph \u201cfigure\u201d element<\/li><li>1st section: data preparation. The callback will use the datasource (which consists of a single dataframe) and will filter and aggregate data by week nr. and weekday<\/li><li>2nd section: graph preparation (using Plotly: go.Heatmap). The chart will use a predefined colorscale which I custom created via a function<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"096e\">5.2.3 Heatmap: data preparation<\/h3>\n\n\n\n<p id=\"fcb1\">In the data preparation part, I had to include some statements to handle the \u201cSelect All\u201d for both the dropdown selections. In case the user has chosen this option from the dropdown, the dataframe doesn\u2019t need to be filtered by country\/city; otherwise, only the values selected by user will be considered from the initial complete dataframe:<\/p>\n\n\n<div class='gist '><br \/><\/div>\n\n\n<p class=\"has-text-align-center has-small-font-size\" id=\"fcb1\">mage by author<\/p>\n\n\n\n<p id=\"4aec\">I\u2019ve then filtered the dataframe by stard and end date and finally aggregated it by week number and weekday:<\/p>\n\n\n<div class='gist '><br \/><\/div>\n\n\n<p class=\"has-text-align-center has-small-font-size\" id=\"4aec\">Image by author<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"d4ed\">5.2.4 Heatmap: graph configuration<\/h3>\n\n\n\n<p id=\"a79d\">In order to draw some nice and consistent charts, across the dashboard, I\u2019ve created a go.Layout() variable (named corporate_layout) at the top of the callback file. This layout variable includes a lot of properties that are almost all the same across all dashboard charts (chart transparent background, font family, title font size, gridlines, zerolines, overall height, legend syle, margins, \u2026).<\/p>\n\n\n\n<p id=\"dd74\">Inside each chart callbacks, a new fig = go.Figure(data=data, layout=corporate_layout) is defined. This allows then to update the fig layout (via this command: fig.update_layout()) to adapt the corporate_layout and include the chart title and the axis titles.<\/p>\n\n\n\n<p id=\"c4ff\">With this approach, the main layout of the chart is defined only once: this helps keeping the code clean, but also flexible; i.e. in order to change all charts height, we simply need to adjust one variable in the whole code.<\/p>\n\n\n\n<p id=\"e645\">Regarding the \u201cdata\u201d component of the go.Figure, I\u2019ve used a go.Heatmap(), including a colorscale, which I\u2019ll describe right below.<\/p>\n\n\n<div class='gist '><br \/><\/div>\n\n\n<p class=\"has-text-align-center has-small-font-size\" id=\"e645\">Image by author<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"4a03\">5.2.5 Heatmap: add a custom colorscale<\/h3>\n\n\n\n<p id=\"52bc\">Plotly heatmap includes some standard colorscales we can choose from, or we can assign a custom created one.<\/p>\n\n\n\n<p id=\"ae21\">Plotly provides some instructions (<a href=\"https:\/\/plotly.com\/python\/reference\/heatmap\/#heatmap-colorscale\" target=\"_blank\" rel=\"noreferrer noopener\">available here<\/a>) to create a custom colorscale. The colorscale that I\u2019ve used look like this : a list of 11 colors that are used by the heatmap according to the percentile of each datapoint.<\/p>\n\n\n<div class='gist '><br \/><\/div>\n\n\n<p class=\"has-text-align-center has-small-font-size\" id=\"ae21\">Image by author<\/p>\n\n\n\n<p id=\"804c\">In order to generate colors in some gradient sequence, I\u2019ve created a function that takes as input the amount of colors we need to generate and the RGB values of two colors: one will be the \u201cstarting point\u201d and the other will be the \u201ctarget point\u201d. The function, for each color, increments the RGB values of the same amount, reaching the target one. It is a very simplistic approach, but this function serves the purpose:<\/p>\n\n\n<div class='gist '><br \/><\/div>\n\n\n<p class=\"has-text-align-center has-small-font-size\" id=\"804c\">Image by author<\/p>\n\n\n\n<p id=\"fa58\">We can finally add the colorscale to the Heatmap to unveil some seasonality : as we can see, sales seem to decrease between week 10 and 20; then they started to increase reaching again the same levels by week 25+. We don\u2019t have a significant seasonality within the days of the week.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/www.experfy.com\/blog\/wp-content\/uploads\/2021\/05\/11B-BOt-k65v4wtc6QIGjOQ.jpeg\" alt=\"Create A Professional Dashboard \"\/><figcaption>Image by author<\/figcaption><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"0d77\">5.3 Providing additional information when hovering on data points<\/h3>\n\n\n\n<p id=\"a0c5\">Within Dash, hovertemplates can be defined to specify what data is shown in what format, when the user hovers the mouse on the datapoints.<\/p>\n\n\n\n<p id=\"c698\">It may be useful to include additional information in the hovertemplate, besides the data which is already used by the chart (x and y value, for instance). Plotly\u00a0<a href=\"https:\/\/plotly.com\/python\/hover-text-and-formatting\/\" target=\"_blank\" rel=\"noreferrer noopener\">official documentation<\/a>\u00a0provides useful alternatives: I am going to present the one that I found most effective.<\/p>\n\n\n\n<p id=\"7cc5\">In the chart below, I\u2019ve created a stacked bar-chart, where every country is represented by each vertical bar, showing the sales as the sum of each city individual sales. When hovering, I also wanted to show the information about the total target as opposed to the sales:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/www.experfy.com\/blog\/wp-content\/uploads\/2021\/05\/1Nf-pZBP-zbLq2DzFuwObQ.png\" alt=\"Create A Professional Dashboard \"\/><figcaption>Image by author<\/figcaption><\/figure><\/div>\n\n\n\n<p id=\"c1ca\">The \u201ctarget\u201d by city is an information present in the datasource, but it is something which is not shown in the chart: where is the hover-template taking this info?<\/p>\n\n\n\n<p id=\"d844\">The approach I followed is to basically create, within the dataframe used by the chart, a new column containing all info I wanted to present in the hovertemplate:<\/p>\n\n\n<div class='gist '><br \/><\/div>\n\n\n<p class=\"has-text-align-center has-small-font-size\" id=\"d844\">Image by author<\/p>\n\n\n\n<p id=\"5036\">Plotly hovertemplate requires some html formatting: \u201c&lt;i> &lt;\/i>\u201d for instance means that the content will be italic; \u201c&lt;extra> &lt;\/extra>\u201d is used to remove the trace name of the datapoint. Values are formatted with the d3-format\u2019s syntax (as explained by Plotly\u00a0<a href=\"https:\/\/plotly.com\/python\/reference\/scatter\/#scatter-hovertemplate\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>): \u201c{:,d}\u201d is used to include thousand\u2019s separators (in case you\u2019re wondering how that would work for other value types: percentages with 2 decimals can be formatted like this: \u201c{:.2%}\u201d; dates can be formatted like: \u201c{x|%a, %d-%b-%Y}\u201d.<\/p>\n\n\n\n<p id=\"1220\">Once we have the hovertext within the data, we can use it in the chart, just by assigning the dataframe column to the chart hovertemplate.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"fd73\">6. How to deploy and share the dashboard<\/h2>\n\n\n\n<p id=\"80ba\">Dashboards created via Dash can be deployed as Flask application. Heroku is definitely one of the most effective ways to make the application available online (and for free).<\/p>\n\n\n\n<p id=\"7b0d\">The guide I used to get this app deployed is very well explained through\u00a0<a href=\"https:\/\/www.youtube.com\/watch?v=b-M2KQ6_bM4\" target=\"_blank\" rel=\"noreferrer noopener\">this video<\/a>, including a list of approx. 15 steps to get this app online.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"9a04\">7. Conclusions<\/h2>\n\n\n\n<p id=\"c201\">Plotly Dash is definitely a fun and very powerful Python library: I have been looking for a quick way to get repeatable analysis automated and very well presented and this definitely served the purpose!<\/p>\n\n\n\n<p id=\"49e0\">With Python knowledge, some html &amp; css experience, I was able to realize this dashboard during spare time in few weeks: I must say that embodying CSS Bootstrap to the layout made the difference and definitely allowed to build an underlying \u201cgrid\u201d that allows to control very easily every section of the dashboard in the way I wanted to be.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This article shows the steps to create an interactive dashboard, using PlotlyDash, a library for Python and R, and enhancing the layout with CSS Bootstrap.<\/p>\n","protected":false},"author":978,"featured_media":16854,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"content-type":"","footnotes":""},"categories":[183],"tags":[999,1000,1001,114,1002],"ppma_author":[3733],"class_list":["post-22438","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai-ml","tag-css-bootstrap","tag-dashboard","tag-plotlydash","tag-python","tag-r"],"authors":[{"term_id":3733,"user_id":978,"is_guest":0,"slug":"gabriele-albini","display_name":"Gabriele Albini","avatar_url":"https:\/\/www.experfy.com\/blog\/wp-content\/uploads\/2021\/05\/Gabriele-Albini-150x150.jpeg","user_url":"https:\/\/www.afiniti.com\/%20","last_name":"Albini","first_name":"Gabriele","job_title":"","description":"Gabriele Albini is Data Analytics Manager at Afiniti, the world\u2019s leading applied artificial intelligence and advanced analytics provider."}],"_links":{"self":[{"href":"https:\/\/www.experfy.com\/blog\/wp-json\/wp\/v2\/posts\/22438","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.experfy.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.experfy.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.experfy.com\/blog\/wp-json\/wp\/v2\/users\/978"}],"replies":[{"embeddable":true,"href":"https:\/\/www.experfy.com\/blog\/wp-json\/wp\/v2\/comments?post=22438"}],"version-history":[{"count":1,"href":"https:\/\/www.experfy.com\/blog\/wp-json\/wp\/v2\/posts\/22438\/revisions"}],"predecessor-version":[{"id":23199,"href":"https:\/\/www.experfy.com\/blog\/wp-json\/wp\/v2\/posts\/22438\/revisions\/23199"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.experfy.com\/blog\/wp-json\/wp\/v2\/media\/16854"}],"wp:attachment":[{"href":"https:\/\/www.experfy.com\/blog\/wp-json\/wp\/v2\/media?parent=22438"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.experfy.com\/blog\/wp-json\/wp\/v2\/categories?post=22438"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.experfy.com\/blog\/wp-json\/wp\/v2\/tags?post=22438"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.experfy.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=22438"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}