A gentle intro to Dash development
By: Zane Rankin
Tags: Data Visualization, Dash, Plotly

A gentle intro to Dash development

Are you a Python programmer suffering from D3 envy?

Step 1: Drool over the D3 gallery’s sexy & interactive plots

Step 2: Fall off the steep learning curve of Javascript

Step 3: Go back to making mediocre seaborn plots

There is a better way!

A Dash interactive visualization in <150 lines of Python code, deployed to Heroku from this GitHub repo

Enter Dash, an approachable yet powerful framework for building interactive web visualizations in pure Python. Since it’s built on top of D3, you get the aesthetics you craved (here are some community examples). Dash has an excellent introductory essay, and an exemplary tutorial that will teach you to make an interactive visualization within 1–2 hours. I want to be clear that I am not writing a tutorial on Dash (seriously, theirs is excellent), nor am I debating the merits of Dash vs Altair or Bokeh (I’ll leave that to experts and their witty decision trees).

So why did I write a tutorial on Dash development? Lost in the thoroughness of the user guide is the concise picture of a common workflow — building and deploying an interactive visualization. If you’re a bit fuzzy when it comes to git features branches, Heroku, or virtual environments, it’s easy to get snagged beyond the tutorial’s simple visualizations. Before you plumb the depths of Stack Overflow, here is an effective workflow that has helped me build multiple dashboards (example) and avoid common pitfalls. I used the following workflow to develop the GitHub tutorial and above Heroku app.

Sample workflow

Project Setup

Once again, this tutorial is about building non-trivial Dash apps and deploying to Heroku, so we must use version control and GitHub. For ease of entry, I made a boilerplate branch in the tutorial repo.

Note: You may be familiar with cookiecutter, an automated tool for project setup. Plotly provides a dash component boilerplate, and there is at least one dash app boilerplate. Mine is a lightweight version that’s sufficient for this tutorial.

Github tutorial boilerplate branch

In addition to the trivial Dash app , I have included the necessary files for Heroku deployment. These files are well documented in Heroku’s Python quickstart. In short, Procfile , runtime , and setup tell the remote Heroku server how to run your app, and requirements lists the Python packages (and their specific versions) for building your app’s virtual environment.

Step 1: create your own Git repository

Step 2: Clone or download the tutorial’s boilerplate branch and manually add those files to your Git repository (this is cleaner than forking the entire Git repository).

Step 3: Create your virtual environment. I am using a conda environment with pip as the package manager. Open a terminal and run conda create -n dash_tutorial pip . (adding pip to your environment makes it easier to track packages via pip freeze later on). Note that my runtime uses Python 3.7.2.

Step 4: Install your packages. First, make sure you’re in your environment: for Windows, run activate dash_tutorial . If you’re just following the tutorial, you can copy my exact environment by running (with the environment activated and within your git repo)

(env_name) C:/path/to/dash_tutorial> pip install -r requirements.txt

If you’re using the boilerplate for your own app (and not using a cookiecutter template), you want an environment with the newest versions of packages. You can pip install the latest Dash libraries, as well as pip install jupyter pandas and any other libraries you intend to use for your app.

At this point, you may be frustrated that I promised a “gentle” introduction then burdened you with environment management. However, environment diligence is crucial to making your Heroku deployments smooth (and really, for any non-trivial Python development). If you really wanted, you could build your full Dash app before dealing with Heroku deployment, but in my experience Heroku deployment is tricky for beginners, and it’s easier to debug deployment with a toy app before you build a complex one you can’t deploy.

Deploy to Heroku

Step 5: Run the app locally.

(env_name) C:/path/to/dash_tutorial> python app.py

This launches a local server which you can access by navigating your browser to http://127.0.0.1:8050/. You should see something like

Boilerplate app running on local server

Step 6: Create your Heroku app

If you don’t have a Heroku account, refer to their Python quickstart for quick installation and configuration. Otherwise, create a Heroku app by heroku create my-app-name

(note that app names must be unique, so you can’t use e.g. dash-tutorial ) Step 7: Deploy to Heroku

Run git push heroku master

If you don’t get errors, visit your app, whose url is made from https://my-dash-name.herokuapp.com/

If all went well, you should see the exact same output as your local server.

Boilerplate app running on Heroku

Develop your Dash app (the fun part)

At this point, you have a solid framework of app development. Referring to the earlier workflow diagram, you will now develop app features on git branches using the following steps (which I labeled with letters to signify the separate and cyclic process). I will show examples from the tutorial repo’s features branches: the first of which makes a scatterplot, the second adds a choropleth map.

A) Create a git branch.

In the tutorial repo, I ran git checkout -b scatterplot to make a branch in which I will add the first interactive scatterplot.

B) Add features

The common workflow is writing code in your favorite text editor or IDE, then launching the local server. Below is the stripped-down code for the interactive scatterplot, excerpted from the first feature branch’s app.py (and shown in the above app). I usually start by copy-pasting code from simple examples like the Dash tutorial’s scatterplot (which explains layout and callbacks ).

For minor tweaks, you can iteratively write code and see updates using Dash’s autoreloader. Below, I launch the local server, then change the colorscale by adding autocolorscale=False argument to the choropleth map, and immediately see the updated map.

Tweaking Plotly code and seeing autoreloader update local app

For certain tasks, like data munging, I find that it’s worth writing code in Jupyter notebooks before adding it to app.py .

Data munging is easier in Jupyter than Dash’s autoreloader

I have found that it isn’t particularly helpful to develop Plotly code in a Jupyter notebook. It takes a few extra setup steps, and the Dash autoreloader gives decent stack traces for debugging. If you want to run Plotly in a notebook, you need to import special tools, as below:

A few extra steps to use Plotly in Jupyter notebook

C) Push to Heroku from feature branch

Once you’re happy with the version of your app running on http://127.0.0.1:8050/, it’s time to redeploy. You could merge your branch to master then push master to Heroku, but I find it more comforting to deploy from my feature branch before merging it to master. This is done via git push heroku branchname:master .

E) Push and merge your feature branch

If your deploy goes well, push your branch:

git push --set-upstream origin branchname

Go to GitHub, create a pull request (PR), then merge your PR. It’s probably best practice to git push heroku master after merging the PR, but if you have clean feature branch workflows, you can just deploy from feature branches.

Rinse & Repeat

Continue developing feature branches, and redeploying to Heroku.

Troubleshooting

My app works locally but not on Heroku

1) Double check your environment. Make sure your requirements.txt is up to date (run pip freeze > requirements.txt and make sure to commit any updates).

2) Heroku has some repo structure requirements. For example, make sure your Procfile is in your app’s root directory.

3) Occasionally, differences in operating systems between your local device and Heroku can create gnarly bugs. For example, I wrote an app that ran locally on Windows, with data.CSV read by pd.read_csv('data.csv') . It successfully deployed to Heroku, but then wouldn’t run on Heroku’s Unix system, breaking with FileNotFoundError: 'data.csv' does not exist .

Next steps