December 7, 2022
Final project details: https://github.com/MUSA-550-Fall-2022/final-project
From the command line:
cd dash-folium
python app.py
to start the example
Let's modify the Altair-based Dash app for the shootings data in Philadelphia to include a dropdown that allows the user to specify which race to show data for.
Steps
Dropdown
object in Dash's core component library: https://dash.plot.ly/dash-core-components/dropdownDiv
element that contains the Dropdown elementrender()
function to accept the value of the race dropdown as an input to the function — then, you can use that value to select the appropriate subset of your data frame to plot!See this Dash app, which adds a dropdown element for race of the shooting victim.
The Dash docs contain a complete example of launching a simple Dash app to Heroku:
https://dash.plotly.com/deployment#heroku-for-sharing-public-dash-apps-for-free
Make sure you've signed up for an account and downloaded the CLI first! (see the previous slide)
Right now: Panel
Goal: a Python-based solution with server support where visualizations from different libraries can interact with each other
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
Also important: Panel provides only support for Datashader and visualizing large datasets
We'll walk through two examples that can serve as reference/templates for the final project:
The main Panel APIs are:
Reference: See the API section of the User Guide for a more detailed discussion
When using Panel, the general workflow will involve the following steps:
This is a reactive workflow.
Overall, there is layout piece and a reactive parameter/callback piece.
Reference: See the Components section of the User Guide for more info.
More info available on the docs
import hvplot.pandas
from bokeh.sampledata.autompg import autompg # cars dataset
autompg.head()
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 |
# Set up a function to plot using hvplot
def autompg_plot(x='mpg', y='hp', color='#058805'):
return autompg.hvplot.scatter(x, y, c="red", padding=0.1)
columns = list(autompg.columns[:-2])
columns
['mpg', 'cyl', 'displ', 'hp', 'weight', 'accel', 'yr']
# Load panel and enable interactive features
import panel as pn
pn.extension()
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.
type(layout)
panel.layout.base.Column
# 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
interact
API but is more explicit about widget selection and layout.pn.bind
function to select and configure widgets explicity and to lay out components explicitly.pn.bind()
function explicitly binds the values of the widgets to the arguments of a function.# Create the widgets
xSelect = pn.widgets.Select(value="mpg", options=columns, name="x")
ySelect = pn.widgets.Select(value="hp", options=columns, name="y")
color = pn.widgets.ColorPicker(name="Color", value="#AA0505")
# Create the dashboard
reactive_dashboard = pn.Column(
pn.Row(
pn.Column("## MPG Explorer", color, xSelect, ySelect), # Title and widgets
pn.bind(autompg_plot, x=xSelect, y=ySelect, color=color), # Main chart
),
)
reactive_dashboard
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:
Note: The example apps on our course Github page use the class API to define the dashboard.
Let's take a quick look at this nice tutorial
Param
libraryimport param
# Define the class
class MPGExplorer(param.Parameterized):
"""A Panel dashboard class."""
x = param.Selector(default="mpg", 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)
# 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
Note that when we change the selections above, the attributes of the explorer
object update:
explorer.x
'displ'
explorer.y
'weight'
explorer.color
'#f20d0d'
I'd encourage you to spend some time reading through their documentation...
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:
Examples:
See more: https://panel.holoviz.org/user_guide/Templates.html
app1.ipynb
and app2.ipynb
https://github.com/MUSA-550-Fall-2022/philadelphia-shootings-app
app.ipynb
https://github.com/MUSA-550-Fall-2022/datashader-nyc-taxi-app