Dash: Dynamic browser based data visualizations!

Umar Khan
5 min readApr 28, 2021

--

In my last post we talked about Plotly and mentioned Dash as something I’d revisit later. Well here I am!

What is Dash exactly? In it’s own words:

“With Dash Enterprise, full-stack AI applications that used to require a team of front-end, back-end, and DevOps engineers can now be built, deployed, and hyperscaled by a single data scientist within hours.”

Quite a bold claim, right? Its totally true though! For my bootcamp capstone I was able to put up a complete webapp style, auto updating dashboard deployed to server and accesible by browser. It gathered crude oil price, supply and market daya along with relevant news articles every 15 minutes and presented them in dynamic, interactive charts. It has been by far the most fun and awesome project I have worked on to date. You can visit it at texasnalytics.org.

Awesome! And I’m not even a web dev! Luckily the dash framework is easy enough to get the hang of. It’s built on top of Flask and works in a somewhat similar fashion, mainly using callbacks. Basically, A dash app consists of a layout made up of HTML elements, and callbacks that can be used to update and modify that html layout based on user input. Easy peasy!

So lets start building this app!

The code above is essentially all of our main layout. First off, we import dash.Dash as “app”. This is how we instantiate a Dash app, much like how we instantiate a Flask app. We went ahead and gave it a title to show in the browser tabs.

Next we go ahead and outline the layout of our webapp. We do this by setting the layout property of the app object. We will define the layout using dash_html_components, which contains Dash equivalents for common HTML tags. The entirety of the layout then is basically just nested html components, pretty much how regular html works (the world exists on the back of a div and it’s divs all the way down). We then proceed to set up a document object model inthe same as html, just using the dcc interface.

In order to add child components to parent components, we simply define the child elements inside a list and pass the list into the “children” keyword argument. Other important kwargs that the components accept are ‘class’ and ‘id’. These work the same way as they do in html, allowing us to categorize out “html” takes in order to be modified using CSS (which Dash totally supports! isnt that awesome?!).

So notice above, we start the layout off with a parent html div. Inside this, we specify the “children” kwarg as being a list. Inside this list we begin to add the subcomponents. If you count the elements of this list (hopefully the indents help), you will see there are three components. There is an html.Div, a dcc.Tabs and another html.Div. The first div is going to be our title bar. The children of this has one element, a Markdown component with a string variable (trust me) containing the title we want to display.

The next component is one we got from the dash core components library (dcc) instead of html. Some components are in this library, some are in html. You will need to refer to the documentation to find the different ones. But it works the same as the html components really. We give it an id and className as usual. We also now define a new kwarg called “value”. This is basically a way of creating a kind of variable name for the contents of the component that can be referenced later on, particularly in callbacks. Take note.

And now, callbacks!

Callbacks is how you can add interactivity to your dashboard. We add callbacks to handle different events. Each callback is passed a list of Inputs and a list of Outputs. Each Input and Output is passed in two params: the name of the component and the attribute which either triggers the callback or which we wish to change using the output of the function that we will decorate using the callback.

See how in the output param we specify the component we want to modify is “tabs-content” and the property we want to modify is the children list. We passed in the input as the ‘value’ property of the main_tabs component, which tells us which tab is selected. Then, we pass the value to the function inside the decorater as ‘tab’. Dash knows that tab is the value property of the tabs-content component and will pass it in at run time.

Inside our function, we can then find out which tab has been selected by checking the value of tab. If the value is ‘main’, we know the user is on the main tab. We then go on to create the div that should be displayed when the user clicks themain tab using Dash html comonponents just as before, and simply have the function return this component. When the div is returned, Dash knows that the item returned from the function will now be the new value of the component we specified as our output, in this case the “children”. So dash will now add this component as a child element of the tabs-content component and voila!

Take note of one little quirk: we passed ‘Output’ by itself to the decorator, but we passed Input as an item inside a list. Dash requires the inputs to passed in as a list even if there is only one input. This allows us to capture multiple inputs if needed. Dash has components for Date pickers, form fields, checkboxes and other types of conventional inputs. In addition to using the change in their attirbtues as Inputs for callbacks, we can also pass in their State to the callback. This comes in handy lets say if you want a callback to be triggered when a “submit” button is clicked, but you also want to capture the values a user entered into other input fields in order to process the correct output.

There are TONS of Dash components, but they all work using these same principles. You will have to refer to to documentation to get a clear idea on how they are to be used. Feel free to look at the sourcecode for texasanalytics.org where I do some fairly complex stuff and might serve as a good example and template.

Go forth and Dash!

--

--

Umar Khan
Umar Khan

Written by Umar Khan

Just an attorney who wandered into data science and never wanted to leave.

No responses yet