Week 14A: Dashboarding with Panel and the Holoviz Ecosystem

December 6, 2021

Housekeeping

  • HW #7 (including final project proposal) — due by the end of the day today
    • Feedback via email on project proposals in the next ~week or so
  • Last class on Wednesday!
  • Extra set of office hours next week, day/time will be announced soon
  • Final project due: end of day Monday December 20th

Final project details: https://github.com/MUSA-550-Fall-2021/final-project

Last two classes!

  • Interactive dashboards with the Holoviz ecosystem
  • Combine all the tools: Altair, Hvplot, Holoviews, GeoViews, Datashader, Folium
  • We'll walk through two example dashboards
  • Review final project and dashboarding options

Summary: web-based visualizations so far

Github Pages:

Today: Panel

The downside of Github Pages

  • Github Pages is static — only user interaction comes from what is built in to the chart

Goal: a Python-based solution with server support where visualizations from different libraries can interact with each other

Saving the best for last: Panel

A high-level dashboarding solution in Python

  • Relatively new, but the most promising dashboard library so far
  • Supports nearly all plotting libraries
  • Works just as well in a Jupyter notebook as on a standalone secure web server
  • Large set of interactive widgets`

Very general too...

  • Multi-page layouts via tabs: See this page
  • Can include custom CSS / Javascript as well

Crucial feature: supports live dashboarding code in a Jupyter notebook and deploying same code to a server

Only library to support entire data wrangling workflow in a Jupyter notebook

See Panel FAQ

Built on top of the HoloViz ecosystem

Also important: Panel provides only support for Datashader and visualizing large datasets

This week's plan

We'll walk through two examples that can serve as reference/templates for the final project:

  1. Visualizing recent shootings in Philadelphia using Altair, Folium, and Holoviews
  2. Visualizing NYC taxi trips with Datashader and Altair

Dashboard apps in Panel

  • Panel contains multiple different APIs to create interactive dashboards.
  • Allows you to make a dashboard from a single function, or build up more complex dashboards with many components

The main Panel APIs are:

  • Interact functions: Auto-generates a full UI (including widgets) given a function
  • Reactive functions: Linking functions or methods to widgets using pn.bind or the equivalent pn.depends decorator, declaring that the function should be re-run when those widget values change
  • Parameterized class: Declare parameters and their ranges in Parameterized classes, then get GUIs (and value checking!) for free

Reference: See the API section of the User Guide for a more detailed discussion

Dashboarding Workflow

When using Panel, the general workflow will involve the following steps:

  1. User changes some parameters via widgets
  2. The dashboard knows which charts depends on those parameters
  3. The necessary functions are executed to properly update the dashboard

This is a reactive workflow.

Panel key concepts

  1. Panes
    • A Pane wraps external viewable items like Bokeh, Plotly, Vega/Altair, or HoloViews plots, so they can be embedded in a dashboard. When the wrapped object or any parameter changes, a pane will update the view accordingly.
    • See more info on the docs
  2. Widgets
    • A wrapper for the values the user selects, which determines which Panes get updated and which data is shown in the dashboard
    • See more info on the docs
  3. Panels
    • Layout objects allow combining plots into a Row, Column, Tabs or a Grid.
    • See more info on the docs

Overall, there is layout piece and a reactive parameter/callback piece.

Reference: See the Components section of the User Guide for more info.

Quick API demo: the "cars" dataset

More info available on the docs

In [1]:
import hvplot.pandas
from bokeh.sampledata.autompg import autompg # cars dataset
In [2]:
autompg.head()
Out[2]:
mpg cyl displ hp weight accel yr origin name
0 18.0 8 307.0 130 3504 12.0 70 1 chevrolet chevelle malibu
1 15.0 8 350.0 165 3693 11.5 70 1 buick skylark 320
2 18.0 8 318.0 150 3436 11.0 70 1 plymouth satellite
3 16.0 8 304.0 150 3433 12.0 70 1 amc rebel sst
4 17.0 8 302.0 140 3449 10.5 70 1 ford torino
In [5]:
# Set up a function to plot using hvplot
def autompg_plot(x='mpg', y='hp', color='#058805'):
    return autompg.hvplot.scatter(x, y, c=color, padding=0.1)

columns = list(autompg.columns[:-2])
columns
Out[5]:
['mpg', 'cyl', 'displ', 'hp', 'weight', 'accel', 'yr']

The default panel import

In [6]:
# Load panel and enable interactive features
import panel as pn
pn.extension()

1. Interact Functions

The interact function will magically generate a UI (including widgets) automatically by inspecting the arguments of the function given to it.

In the case below, we give the autompg_plot() the allowed options for its 3 arguments x, y, and color, and it auto-generates a Panel dashboard.

In [11]:
# Create a widget to select the color of the scatter points
color = pn.widgets.ColorPicker(name='Color', value='#4f4fdf')

# Auto-generate the layout
layout = pn.interact(autompg_plot, x=columns, y=columns, color=color)

# Create the dashboard with a Row and Column
interact_dashboard = pn.Row(pn.Column('## MPG Explorer', layout[0]), layout[1])
interact_dashboard
Out[11]:

2. Reactive Functions

  • Very similar to the interact API but is more explicit about widget selection and layout.
  • You must use the pn.bind function to select and configure widgets explicity and to lay out components explicitly.
  • The pn.bind() function explicitly binds the values of the widgets to the arguments of a function.
In [14]:
# Create the widgets
x = pn.widgets.Select(value="mpg", options=columns, name="x")
y = pn.widgets.Select(value="hp", options=columns, name="y")
color = pn.widgets.ColorPicker(name="Color", value="#AA0505")

# Create the dashboard
reactive_dashboard = pn.Row(
    pn.Column("## MPG Explorer", x, y, color), # Title and widgets
    pn.bind(autompg.hvplot.scatter, x, y, c=color), # Main chart
)

reactive_dashboard
Out[14]:

3. Parametrized Classes

You are welcome to use any of the APIs to create dashboards for the final project. However, this is the recommended approach (although I recognize it's a bit more complex than options #1 and #2).

We'll define our app in a declarative fashion using a custom Python class that defines the various components of our dashboard, which include:

  • The parameters we want the user to be able to change.
  • Reactive functions to generate the various charts/maps in our dashboard, based on those input parameters.
  • The dependencies between our chart functions and parameters.

Note: The example apps on our course Github page use the class API to define the dashboard.

First some quick background: an introduction to Python classes

Let's take a quick look at this nice tutorial

The Param library

  • Widgets in Panel depend on the Param library
  • These widgets allow you to declare the parameters of a dashboard in a declarative manner.
  • Declare the type of parameter you need and get the corresponding widget in your dashboard for free!
  • Many many examples: https://panel.holoviz.org/user_guide/Param.html
In [15]:
import param
In [19]:
# Define the class
class MPGExplorer(param.Parameterized):
    """A Panel dashboard class."""

    x = param.Selector(objects=columns)
    y = param.Selector(default='hp', objects=columns)
    color = param.Color(default='#0f0f0f')
    
    @param.depends('x', 'y', 'color') # This is a Python "decorator"!
    def make_autompg_plot(self):
        return autompg_plot(self.x, self.y, self.color)
In [20]:
# Initialize the dashboard class object
explorer = MPGExplorer()

# Create the dashboard layout
# Note: widgets are stored in the 'param' attribute by default
class_dashboard = pn.Row(explorer.param, explorer.make_autompg_plot)

class_dashboard
Out[20]:

Great examples on their documentation

I'd encourage you to spend some time reading through their documentation...

Note: Dashboard Templates

Panel has recently added default layout templates to provide a simple, well-designed layout for the dashboard. They are all very similar and break the layout into various pieces, including the:

  • Title
  • Sidebar
  • Main content

Examples:

See more: https://panel.holoviz.org/user_guide/Templates.html

Two example repositories on the course's Github

Example 1: Philadelphia shootings

  • Tools: Panel, Hvplot/Holoviews, Altair, Folium
  • This includes two separate apps: app1.ipynb and app2.ipynb

https://github.com/MUSA-550-Fall-2021/philadelphia-shootings-app

Example 2: NYC Taxi Trips

  • Tools: Panel, Hvplot/Holoviews, Altair, Datashader
  • This includes a single app: app.ipynb

https://github.com/MUSA-550-Fall-2021/datashader-nyc-taxi-app

In [ ]: