How to build an app using Dash, Plotly and Python and deploy it to AWS
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.
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):
- Flask: A web development framework for Python. Dash apps are web servers running Flask.
- Plotly.js: A JavaScript graphing library that provides Dash with a wide range of charts. Python library
plotly
is built on top of it. - 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 byplotly.express
, aplotly
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
anddash.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 fromdcc.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 figif __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 withid='dropdown'
which is the item we selected from the dropdown - gives as output the
figure
property withid=’histogram’
, which is the histogram of the featurevalue
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.
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:
- 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
- https://plotly.com/dash/
- https://dash.plotly.com/layout
- https://github.com/plotly/dash
- https://plotly.com/python/plotly-express/
- https://dash-bootstrap-components.opensource.faculty.ai/
- https://dash-bootstrap-components.opensource.faculty.ai/docs/themes/
- https://www.kaggle.com/c/titanic/data?select=train.csv
- 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
- https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Fplotly%2Fdash
- https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/GettingStarted.html
- https://medium.com/plotly/introducing-dash-5ecf7191b503