Another Stage Of Visualization: Be Reactive with Dash | by Jiwon Jeong | Towards Data Science

Dash is an open source python library which enables us to create web applications with Plotly. It makes it easy to build an interactive visualization with simple reactive decorators like a dropdown, a slider bar, and markdown text data. We can even update the plots according to the input data with callbacks, and all these functions are available without Javascript or HTML directly. Plotly is a very powerful tool that enables us to make an informative and effective plot in a handy way and Dash can be considered as a stage for showcasing awesome visualization.
Today I’m going to show you how to create a dashboard with Plotly. And we’ll make a time series line plot and add a dropdown and a slider bar interacting with the plot. There is nice documentation on how to use this library, but I find it could be hard to read the example codes and utilize them at first. So this could be a kind bridge for you to understand how to use Dash with Plotly.
To build a dashboard, we need to install some packages as follows.
pip install plotly==2.5.1pip install dash==0.21.0pip install dash-core-components==0.22.1pip install dash-html-components==0.10.0pip install dash-renderer==0.12.1
As I said above, dash-core-components allows us to build not only graphs but also a dropdown and a text box so that we can update the components accordingly. dash-html-components enables us to use HTML & CSS with Python. It helps us to place HTML components such as Div, H1, and H2 on our dashboard.
If this is your first time using Dash and HTML syntax, it can be a bit complex and hard to read. Therefore I’d recommend you to take the following script as a skeleton guide to Dash. From now on, what we’re going to do is filling this out step by step.
First things first, we import the libraries. You can add other libraries as you need. And then we initialize Dash by calling the Dash class. This is like putting a blank whiteboard on our table and what we are doing is building up additional applications on that board.
# Step 1. Launch the applicationapp = dash.Dash()# Step 2. Import the datasetdf = pd.read_csv('finance-charts-apple.csv')
Now let’s bring some ingredients from the CSV file with pandas. The dataset we’re going to use is the Apple stock price data which is available here.
I won’t cover the details on Plotly itself, but you can find a nice tutorial for Plotly from this video if it’s necessary. You can also learn how to make a 3D plot or Choropleth Map in the series of the video. Here we’ll make a line plot which shows fluctuations in the stock price.
# Step 3. Create a plotly figuretrace_1 = go.Scatter(x = st.Date, y = st['AAPL.High'],                    name = 'AAPL HIGH',                    line = dict(width = 2,                                color = 'rgb(229, 151, 50)'))layout = go.Layout(title = 'Time Series Plot',                   hovermode = 'closest')fig = go.Figure(data = [trace_1], layout = layout)
Now, it’s time for dash-html-components to come into play. We first put a division and then bring the graph inside it. id is giving a name to this component so that we can call it by its name. You’ll understand what this is for later. And then we make a server to run in step 6. If we set the debug mode equals true, we can easily change and update the app while the server is running.
# Step 4. Create a Dash layoutapp.layout = html.Div([                dcc.Graph(id = 'plot', figure = fig)                      ])# Step 6. Add the server clauseif __name__ == '__main__':    app.run_server(debug = True)
Let’s save this script with the name of app.py and import it on the terminal (or anaconda prompt). Note that the working directory should be the same with where you saved the file.
C:\Users\jjone\Dash> python app.py
If there is no typo or syntax error, you’ll see the localhost address. You can copy and paste it or you can just type localhost:8050 on a new web tab.
We can also have additional components such as putting text data just like HTML. You can find what kind of elements are available here. Let’s put a simple heading and a paragraph on our page.
# Step 4. Create a Dash layoutapp.layout = html.Div([                # adding a header and a paragraph                html.Div([                    html.H1("This is my first dashboard"),                    html.P("Learning Dash is so interesting!!")                         ],                     style = {'padding' : '50px' ,                              'backgroundColor' : '#3aaab2'}),# adding a plot                        dcc.Graph(id = 'plot', figure = fig)                      ])
On top of the graph, I’m going to put one more division and add a header and a paragraph inside it. We have two major components, html.Div and dcc.Graph. Inside html.Div, there are two additional components, header ( html.H1 ) and a paragraph ( html.P ). We can change the margin of the components or the background color with the style attribute. It should be designated in a dictionary format supporting CSS properties.
Please pay extra care where the parenthesis starts and ends. It’s important to understand the range of the paragraph for each component. As there are so many parenthesizes and square brackets, it can be confusing at first. And It’s so easy to make a syntax mistake as well.
Put this code at step 4 in our template and see the result. We can simply check the outcome by pressing F5 if the server isn’t shut down.
Now I hope you get the idea of what the dash components and the HTML components are. How to put multiple components and how they go along with together.
Let’s try making a dropdown on our dashboard this time. We’re going to make another plot which changes its y-axis according to the given option. By the documentation of dash components, we can putDropdown as follows.
As you can see, the options should be in the format of a dictionary. In our case, the options will be the columns only with the continuous variables, from the 2nd column to the 10th. With the list comprehension, we can make the option dictionary in just one line.
features = st.columns[1:-1]opts = [{'label' : i, 'value' : i} for i in features]
Now instead of the HTML components, we’re going to put the dropdown component at the bottom of the plot. Take a look at the bold font first because others are just for decorating the major two applications.value is the default value of the dropdown.
# Step 4. Create a Dash layoutapp.layout = html.Div([                # adding a plot                dcc.Graph(id = 'plot', figure = fig),                # dropdown                html.P([                    html.Label("Choose a feature"),                    dcc.Dropdown(id = 'opt',                                  options = opts,                                 value = opts[0])                        ], style = {'width': '400px',                                    'fontSize' : '20px',                                    'padding-left' : '100px',                                    'display': 'inline-block'})                      ])
And just as what we did before, we can replace this code at step 4 in our template and check the outcome.
To update the graph according to the choice of the dropdown, we need to make a connection between input data (the dropdown) and output data (the graph). This will be done by adding a callback function in step 5.
# Step 5. Add callback functions@app.callback(Output('plot', 'figure'),             [Input('opt', 'value')])
Do you remember what id we gave to each component? plot and opt. Therefore we can call them with their name as shown above. We take the input data from the options by the name of opt and give the output to the line plot by the name of plot.
def update_figure(X):    trace_2 = go.Scatter(x = st.Date, y = st[X],                        name = X,                        line = dict(width = 2,                                    color = 'rgb(106, 181, 135)'))    fig = go.Figure(data = [trace_1, trace_2], layout = layout)    return fig
So we take the input data and then return the output as we want by creating an update function. What is our input data here? It’s the name of the feature variable selected from the dropdown, and we are to make it as the y-axis of our second line plot. As there is nothing to be changed with the trace_1, we can simply add trace_2 to the data list. Now if we put this code at step 5 and rerun app.py, the result will be is shown below.
I’d like to briefly talk about a callback before we move on to the next section. Because it’s one of the most frequently used functions while programming any kind of applications. In a nutshell, a callback is a function that is executed later when it gets the real execution command and it’s usually for the purpose of updating. Callback functions don’t work right after they get the command. These people are kind of lazy. They will do their work after the other command lines are executed and we call them back again with the real execution command.
See how our update_figure() works. This function does his work not right after we import this app but when we give the actual input signal to it by “calling back.” This is what a callback function is. It’s totally fine you use this without understanding but I hope you get the rough idea here. You can also find more details from this article.
Lastly, let’s try a range slider. We’ll add a year range slider to the plot, and it’s very similar to dropdowns. Let’s check the documentation of dash components first.
I think you can easily get the idea by this time. The key point here is how to make a mark dictionary. As the date period starts from (Feb 17 2015) to (Feb 17 2017), I’d like to add 7 marks between the period as follows.
st['Date'] = pd.to_datetime(st.Date)dates = ['2015-02-17', '2015-05-17', '2015-08-17', '2015-11-17',         '2016-02-17', '2016-05-17', '2016-08-17', '2016-11-17',           '2017-02-17']date_mark = {i : dates[i] for i in range(0, 9)}
Now we can simply put the range slider at the dropdown place. I’ll name it as slider this time. min and max are the minimum and the maximum of the slider and value is the default setting of the slider. Again, all the other parts are designing the HTML components with CSS style.
# Step 4. Create a Dash layoutapp.layout = html.Div([                # adding a plot                dcc.Graph(id = 'plot', figure = fig),                # range slider                html.P([                    html.Label("Time Period"),                    dcc.RangeSlider(id = 'slider',                                    marks = date_mark,                                    min = 0,                                    max = 8,                                    value = [3, 4])                         ], style = {'width' : '80%',                                    'fontSize' : '20px',                                    'padding-left' : '100px',                                    'display': 'inline-block'})                      ])
After making a slider, what will be the next step? Connecting it to the plot! Again we’ll take the input data from the slider and return the output to the plot. But this time, there is a small trick here. Did you notice that the default value of the slider is a list with two values? Please check the code box above again. value = [3, 4] Different from the dropdown component, the range slider takes two values in a list. Therefore when we get the input data from the slider, there will be two values of the starting and ending value (X[0] , X[1])
# Step 5. Add callback functions@app.callback(Output('plot', 'figure'),             [Input('slider', 'value')])def update_figure(X):    st2 = st[(st.Date > dates[X[0]]) & (st.Date < dates[X[1]])]    trace_1 = go.Scatter(x = st2.Date, y = st2['AAPL.High'],                        name = 'AAPL HIGH',                        line = dict(width = 2,                                    color = 'rgb(229, 151, 50)'))    fig = go.Figure(data = [trace_1], layout = layout)    return fig
Now we’ll filter the data and update the plot with the given period. If you reload the web page again, you’ll see the same result with me.
I think we covered quite a lot of things so far. From putting a graph to adding a callback. Now why don’t we bring it all together? I’d recommend you to review the script below step by step. You can combine all the components of the graph, the dropdown and the slider at step 4 just like replacing and changing modules.
Are you ready to see how our first dashboard looks like? 😃😃🙌🙌 BOOM!!
Great work! Did you enjoy building a dashboard? I hope now you become comfortable reading and understanding other Dash code examples. Dash provides such a nice guide so feel free to explore the sites on your own. You can also check other stuff available in Dash by Plotly.
medium.com
So far our application is locally hosted on your machine. To make it available to other people, we need to deploy it on the web. There are two choices you can take, App authorization and deploying it to Heroku. The first one requires us to install the dash-auth package an there are two different types of authentication, HTTP Basic Auth or Plotly OAuth. You can follow this tutorial.
Another way is by using the hosting platforms such as Heroku, AWS, Google Cloud Platform and so on. Heroku is the easiest way for deploying and you can follow this tutorial. The other platforms are just the same with Heroku.
Beside dropdown, we can also add other components such as text area or uploading data. I recommend you to explore what kind of dash components are available. You can also add as many HTML components as you want and design your board in a much fancier way with CSS properties. If you need to learn some basics of HTML & CSS, you can find a great tutorial from this video.
Thank you for reading and I hope you found this post interesting. If there’s anything need to be corrected, please share your insight with us. I’m always open to talk so feel free to leave comments below and share your thoughts. I also share interesting and useful resources on LinkedIn so feel free to follow and reach me out. I’ll be back again with another interesting story next time!