Lecture 13B: From Notebooks to the Web: Github Pages, Web Servers, and Dash

December 1, 2020

Housekeeping

Web-based Data Viz

We'll discuss ways to translate our analysis results to the Web in a meaningful way. We'll cover three methods to do so, each with their own pros and cons:

Last lecture

  1. Embedding interactive charts on the Web via Github Pages

This lecture

  1. Creating Web apps & dashboards using the Python library Dash

Next week

  1. Creating Web apps & dashboards using the Python library Panel

Quick recap:

Last time, we covered:

  1. Quick review of how to saving interactive charts so they can be embedded on the web
  2. Using Github Pages to set up a blog-like website to embed data visualizations

Part 1: Embedding Interactive Charts on the Web

We reviewed examples of how to save interactive charts using the following packages:

Part 2: Template Github Pages with Examples

Where we left off: Setup your own Github Pages project page

Steps:

Notes

On to new content...Dashboards with Dash

Part 3: Web Servers

A few quick basics before we move on to interactive Web apps with Dash...

Some (oversimplified) basics

Two main types:

Static and dynamic

Static Web Servers

Dynamic Web Servers

For more information: Mozilla documentation

CARTO: a dynamic web server

Anatomy of a request

Flask: a micro web framework in Python

A very lightweight package for framework for dynamic web apps

Flask documentation

Example 1: your first Flask app

Running Python scripts from the command line

To start up our Flask app, we'll need to execute the Python script from the command line. We have two options for that...

Option A: Launch a terminal in Jupyer notebook

Kapture%202020-11-22%20at%2016.30.27.gif

Steps:

From within the Jupyter Notebook Dashboard:

Flask code: hello.py

Important: this won't work on Binder, it needs to be running on your local machine

Option B: Use the Terminal (MacOS) or Anaconda Prompt (Windows)

To start a local server

Run the following commands from within the Terminal window in Jupyter notebook:

cd hello-flask
python hello.py

The "python" command

StackOverflow answer about the if-name-main syntax in Python.

Note

There are sometimes Anaconda-related issues where "python" will point to the wrong version of Python. You can double check by running:

which python

from the Jupyter Terminal interface. This should print out a path name that includes the name of our Python environment (musa-550-fall-2020)

Take a look at hello.py

View your application!

Navigate in the browser to: http://0.0.0.0:5000

You should see the text: "Hello, World!"

Important: Windows Users

You will likely need to navigate to localhost:5000 instead of http://0.0.0.0:5000

Note: the web address http://0.0.0.0 is an alias for "localhost" — this means the web server is running locally on your computer.

Editing your app with a running server

Try editing the hello.py file in your editor, saving, and re-loading the application page. You should see the app update to reflect the changes!

Example 2: using templates

Flask code: hello-template.py

From the terminal window

python hello-template.py

The main page ("/") renders the same thing as the previous app ("Hello, World!").

Navigate to the "/hello/" route and you should see:

Example 3: setting up an API with request parameters

hello-api.py: a more sophisticated example using request parameters

Run:

python hello-api.py

Flask code: hello-api.py

This uses default request parameters: days = 90 and fatal = 0

Now pass "days" and "fatal" parameters

This returns the number of fatal/nonfatal shootings in the past X "days"

Getting closer to a more realistic use case...

Steps:

  1. Get request parameters from the browser (input by the user)
  2. Query CARTO database for data based on that input
  3. Perform an operation on that data (in this case, count number of shootings)
  4. Return computed result back to the browser

Note: If you receive a "OSError: Address already in use"

Now, that we have the basics on to a more advanced library...

Part 4: Dash

The result of Python programmers asking the question: can we build a dashboard just in Python?

The answer is yes...for the most part.

You still need to use some CSS styling and know about different HTML elements. But everything is coded in Python.

Dash

Benefits

Downsides

The general workflow

In your Python Dash app, there are two main steps:

  1. Define the HTML layout, e.g., "div" elements, slider elements, etc.
  2. Define functions that take inputs from the interactive widgets from Step 1. and return the output for other HTML elements.
    • When the user changes a slider, dropdown, etc, the function will run, and return the updated output

Dash HTML components = "the app layout"

See: https://dash.plot.ly/dash-html-components

Dash HTML Example

html.Div([
    html.H1('Hello Dash'),
    html.Div([
        html.P('Dash converts Python classes into HTML'),
        html.P('This conversion happens behind the scenes by Dash's JavaScript front-end')
    ])
])

This gets converted automatically to the following HTML in your web app:

<div>
    <h1>Hello Dash</h1>
    <div>
        <p>Dash converts Python classes into HTML</p>
        <p>This conversion happens behind the scenes by Dash's JavaScript front-end</p>
    </div>
</div>

Dash core components = "widgets"

See: https://dash.plot.ly/dash-core-components

Note: Markdown is also supported!

Use the dcc.Markdown() object to automatically convert Markdown into HTML in your web apps!

Reference: HTML and CSS tutorials

The core components and HTML components in Dash remove most of the direct HTML/CSS, but still good to know some of the basics:

Useful to keep these references handy if you are unsure about syntax for HTML and/or CSS

The Dash Getting Started Guide

https://dash.plot.ly/getting-started

Combining Dash with Altair and Folium

Key: any valid ".html" block can be embedded within an "IFrame" element

Two key elements of Dash apps

Steps:

  1. Define a IFrame() element as part of the layout
  2. Given some user input, generate our Altair charts and save them as HTML
  3. Assign the chart HTML to the IFrame on our page

Let's see some Dash + Altair examples...

Two examples in the "dash-altair/" folder...

Visualizing the "penguins" dataset

Just like with Flask, we can run from the Jupyter terminal:

python dash_altair_penguins.py

Dash app

Translating the shootings app to Dash

We can run from the Jupyter terminal:

python dash_altair_shootings.py

Dash app

More information: Dash user guide