How to build an app using Dash, Plotly and Python and deploy it to AWS

Sandy Bei
Innovation-res
Published in
8 min readJan 19, 2022

This article is a short introduction to Dash Plotly and gives a tutorial on how to build and deploy an interactive dashboard to AWS Elastic Beanstalk.

https://unsplash.com/photos/Wb63zqJ5gnE?utm_source=unsplash&utm_medium=referral&utm_content=creditShareLink
https://unsplash.com/photos/Wb63zqJ5gnE?utm_source=unsplash&utm_medium=referral&utm_content=creditShareLink

1. What is Dash?

Dash is an open-source framework for building apps with interactive features and data visualizations in Python, Julia, R and F#.

With Dash for Python, you can create an interactive dashboard online for your data using only Python. No need to know HTML, CSS, JavaScript or anything about web development like routes and requests.

Dash is built upon the following frameworks and libraries (which you don’t have to know):

  1. Flask: A web development framework for Python. Dash apps are web servers running Flask.
  2. Plotly.js: A JavaScript graphing library that provides Dash with a wide range of charts. Python library plotly is built on top of it.
  3. React.js: A JavaScript library for building user interfaces that provides components like dropdowns and sliders.

Dash Python’s extensive user guide can be found here, a quick tutorial to create a Dash app here and Dash code on GitHub here.

2. Install dependencies

Before building an app, you have to install the Python package for Dash Plotly (that also brings along plotly graphing library).

For Python installation, run the following in a command line:

pip install dash

and if you use Jupyter notebook:

pip install jupyter-dash

You should also install:

  • pandas, which is required by plotly.express, a plotly module for creating common figures you will most probably need
pip install pandas
  • dash-bootstrap-components, a library for Plotly Dash that allows you to customize your app’s layout with Bootstrap components and themes and gives your app consistent style
pip install dash-bootstrap-components

3. Build your App

In this article, we go through a simple Dash app example. The first step is to create a new directory and then add a app.py python file inside. Then add the following code inside app.py.

import dash
from dash import html
from dash import dcc
import dash_bootstrap_components as dbc
import pandas as pd
import plotly.express as px
# load data
df = pd.read_csv('train.csv')
# make plot
fig = px.histogram(df, x='Age')
# initialize app
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.UNITED])
# set app layout
app.layout = html.Div(children=[
html.H1('Test Dash App', style={'textAlign':'center'}),
html.Br(),
dcc.Dropdown(
options=[{'label': i, 'value': i} for i in df.columns],
value='Age',
id='dropdown',
style={"width": "50%", "offset":1,},
clearable=False,
),
dcc.Graph(id='histogram', figure=fig)
])
if __name__ == "__main__":
app.run_server(debug=True)

Let’s go through this code step-by-step.

3. 1 — Import Dependencies

Import all necessary libraries inside app.py:

import dash
from dash import html
from dash import dcc
import pandas as pd
import plotly.express as px
  • dash.html: a module with components for every HTML tag like <div/>, <img/>, etc.
  • dash.dcc: a module with components like buttons, dropdowns, graphs, markdown blocks, etc.

dash.html

Instead of writing HTML or using an HTML templating engine, you compose your layout using Python structures with the dash-html-components library.

For example,

html.H1('Test Dash App', style={'textAlign':'center'})

gets converted by Dash into the following HTML syntax :

<h1 style="text-align:center;">Test Dash App</h1> 

dash.dcc

A core set of components, written and maintained by the Dash team, is available in the dash-core-components library.

All plots in your app are displayed through dcc.Graph. Create a Plotly figure and then pass it to the figure argument.

dcc.Graph(id='histogram', figure=fig)

3.2 — Import Data + Make Plots

The next step is to add your data and the plots you want to be displayed on your app. For this example, we use the train.csv Titanic dataset from Kaggle. Download the file and put it inside your project’s directory. Load the data to a dataframe and make a histogram of the Age feature.

# load data
df = pd.read_csv('train.csv')
# make plot
fig = px.histogram(df, x='Age')

3. 3— Initialize App

To initialize your app, create a Dash() instance and assign it to a global variable:

app = dash.Dash(__name__)

In this tutorial, we also add argument external_stylesheets to set a specific Bootstrap theme (other themes can be found here):

app = dash.Dash(__name__, external_stylesheets=[dbc.themes.UNITED])

3.4 — Design App’s Layout

The app.layout defines what your app looks like. It is a hierarchical tree of components. In this example, we create a Div that includes all the content of our app’s page. This Div consists of a header (html.H1), a line break (html.Br), a dropdown (dcc.Dropdown) and a graph (dcc.Graph).

It is a good practice to give id to all components because you will need them when you make your app interactive.

app.layout = html.Div(children=[
html.H1('Test Dash App', style={'textAlign':'center'}),
html.Br(),
dcc.Dropdown(
options=[{'label': i, 'value': i} for i in df.columns],
value='Age',
id='dropdown',
style={"width": "50%", "offset":1,},
clearable=False,
),
dcc.Graph(id='histogram', figure=fig)
])

3.5 —Make your App Interactive

To make the app interactive you have to use callback functions, functions that are automatically invoked when an action is completed.

callbacks functions are automatically called by Dash whenever an input component’s property changes, in order to update some property in another component (the output)

To make the app interactive, you have to make some changes first:

  • import dash.dependencies.Input and dash.dependencies.Output which will be used in the callback definitions
  • define a callback function that changes the components you want
  • remove this line of code fig = px.histogram(df, x=’Age’) because it gets overwritten from the plot defined in the callback
  • remove figure argument from dcc.Graph, as it is no longer defined

When the Dash app starts, it automatically calls all of the callbacks with the initial values of the input components in order to populate the initial state of the output components.

With these changes, app.py looks like this:

import dash
from dash import html
from dash import dcc
import dash_bootstrap_components as dbc
import pandas as pd
import plotly.express as px
from dash.dependencies import Input, Output
# load data
df = pd.read_csv('train.csv')
# initialize app
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.UNITED])
# set app layout
app.layout = html.Div(children=[
html.H1('Test Dash App', style={'textAlign':'center'}),
html.Br(),
dcc.Dropdown(
options=[{'label': i, 'value': i} for i in df.columns],
value='Age',
id='dropdown',
style={"width": "50%", "offset":1,},
clearable=False,
),
dcc.Graph(id='histogram')
])
# callbacks
@app.callback(
Output(component_id='histogram', component_property='figure'),
Input(component_id='dropdown', component_property='value'),
)
def update_hist(feature):
fig = px.histogram(df, x=feature)
return fig
if __name__ == "__main__":
app.run_server(debug=True)

The callback has an Input and an Output , which are properties of specific components. In this example, the callback:

  • takes as input the value property of component with id='dropdown' which is the item we selected from the dropdown
  • gives as output the figure property with id=’histogram’, which is the histogram of the feature value

The properties must be passed as strings in the Input, Output properties (here ‘value’ and ‘figure’ instead of value and figure).

The variable we used in the update_hist function (which we named feature) takes the value of the input value.

Callbacks can have multiple inputs and outputs.

3.6— Run App

To run the app, add the following at the end of the code:

if __name__=='__main__':
app.run_server(debug=True)

The argument debug=True automatically refreshes the web browser when you make code changes, so you don’t have to refresh the browser each time. It is useful for development but is not recommended for production.

Run the app by running in your terminal:

python app.py

You should see something like this:

By default, Dash apps run on localhost. Open the URL where your Dash app is running (http://127.0.0.1:8050/) on a browser:

4. Deploy to AWS Elastic Beanstalk

To deploy your app to AWS, you must have a AWS account. If you don’t, sign up here.

Dash Plotly and AWS Elastic Beanstalk

4.1 — Change your app’s file name

You must name your app’s file name ‘application’ to deploy it to AWS Elastic Beanstalk. So, change your file name from app.py to application.py.

4.2 — Access Flask instance

As mentioned above, Dash apps are built upon Flask and run on localhost by default. To deploy it to a server, you have to access the Flask application instance first.

To do that, assign app.server Flask app instance to a variable, where app is your Dash application instance (e.g. server = app.server).

❗ for deploying to AWS you must name that variable ‘application’

So, just add application = app.server:

# initialize app
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.UNITED])
application = app.server

4.3 — Run app to a server

Now, you have to run that Flask instance. Replace Dash’s run_server function with Flask’s run, set host to 0.0.0.0 , set a port and remove debug=True.

if __name__=='__main__':
application.run(host='0.0.0.0', port='8080')

4.4 — Add a requirements.txt file

Add a requirements.txt file to your project’s directory that specifies the Python packages required for your application. For this example, the file is:

dash==2.0.0
dash-bootstrap-components==1.0.2
pandas==1.3.5

You can easily create requirements.txt with the following command:

pip freeze > requirements.txt

To make sure that you have included the correct packages you should test that the app runs locally first.

To do this, create a virtual environment, install there the dependencies of requirements.txt and run application.py. You can do this by running the following commands one-by-one in your terminal (if you have Anaconda installed):

conda create -n testEnv python=<python version> 
conda activate testEnv
pip install -r requirements.txt
python application.py

If everything works fine on localhost, you are ready for deployment.

4.5— Upload to AWS

Go to AWS Elastic Beanstalk and follow these steps:

  1. Give your application a name:

2. You can skip Application tags:

3. Select Python in Platform:

4. Select Upload your code and Choose file in Application code:

The file you choose must be a zip file (❗) that consists of all files in your project’s directory.

5. Select Create application

It may take a few minutes to create the application.

If your environment’s Health status is Ok, your app has been successfully deployed. Click on the URL of your environment’s application, and check if it’s running.

That’s it! Your app should be up and running on AWS!

References

  1. https://plotly.com/dash/
  2. https://dash.plotly.com/layout
  3. https://github.com/plotly/dash
  4. https://plotly.com/python/plotly-express/
  5. https://dash-bootstrap-components.opensource.faculty.ai/
  6. https://dash-bootstrap-components.opensource.faculty.ai/docs/themes/
  7. https://www.kaggle.com/c/titanic/data?select=train.csv
  8. https://signin.aws.amazon.com/signin?redirect_uri=https%3A%2F%2Fportal.aws.amazon.com%2Fbilling%2Fsignup%2Fresume&client_id=signup&code_challenge_method=SHA-256&code_challenge=ITKjqLw0UTaQf4aDkQXtrt5VFyVl8mZesdGZazoguYk
  9. https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Fplotly%2Fdash
  10. https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/GettingStarted.html
  11. https://medium.com/plotly/introducing-dash-5ecf7191b503

--

--