Dashboards#

So far in this tutorial, we have seen how to generate plots with .plot or .hvplot, how to compose these plots together into layouts and overlays, how to link selections between these plots, and how to control visualizations with Panel widgets using .interactive. In this notebook, we will learn how to put all these pieces together to display (and serve) these components in a dashboard using Panel.

Panel pane objects#

So far we have only seen Panel used as a source of widgets, but Panel also offers pane objects that can display various types of data (including output from just about any plotting library). First let’s import Panel and load the extension:

import pathlib
import pandas as pd
import panel as pn
import xarray as xr
import holoviews as hv

pn.extension('tabulator', template='material', sizing_mode='stretch_width')

import colorcet as cc
import hvplot.xarray # noqa
import hvplot.pandas # noqa

Here, we have enabled some optional functionality from Panel, specifically the tabulator extension, and selected a default template controlling the overall look and feel of the final app. We also configured how plots should be sized by default (stretching to fit the width available). We’ll come back to the idea of a template later. Here, let’s look at a simple pane, e.g. a Markdown pane that displays Markdown-format text:

pn.pane.Markdown('## Earthquake Dashboard')
logo_path = pathlib.Path('../assets/usgs_logo.png')

The PNG pane can display PNG images:

pn.pane.PNG(logo_path, height=130)

Using pn.panel#

Instead of having to select the pane type explicitly, you can use the pn.panel function that tries to guess the appropriate representation given the input. For instance, here we generate the same two panels using pn.panel and grab handles on the resulting objects:

dashboard_title = pn.panel('## Earthquakes')
usgs_logo = pn.panel(logo_path, height=130)

Exercise#

Confirm that these two objects are of type Markdown and PNG respectively by using the type built-in. Explore using different markdown syntax such as italic, bold or adding bullet points. Finally, try displaying your own PNG image with a PNG pane, using either a local filename or URL.

Panel objects#

In addition to pane objects, Panel offers containers of type panel which allow you to position your components into various layouts. For instance, we can put a small version of our title and logo into a Panel Row layout:

header = pn.Row(dashboard_title, pn.pane.PNG(logo_path, height=40))
header

Next let us load the earthquake dataset and make a basic plot of the sort we have seen earlier on in the tutorial:

%%time
df = pd.read_parquet(pathlib.Path('../data/earthquakes-projected.parq'))
df = df.set_index('time').tz_convert(None).reset_index()
small_df = df.sample(frac=.01)
CPU times: user 5.99 s, sys: 2.72 s, total: 8.71 s
Wall time: 8.74 s
%%time
ds = xr.open_dataarray(pathlib.Path('../data/raster/gpw_v4_population_density_rev11_2010_2pt5_min.nc'))
cleaned_ds = ds.where(ds.values != ds.nodatavals).sel(band=1)
cleaned_ds.name = 'population'
CPU times: user 298 ms, sys: 133 ms, total: 431 ms
Wall time: 460 ms
sample_points = small_df.hvplot.points(x='longitude', y='latitude', c='mag', cmap=cc.CET_L4, responsive=True)
rasterized_pop = cleaned_ds.hvplot.image(rasterize=True, logz=True, clim=(1, None), responsive=True, min_height=400).opts(bgcolor='black')
earthquake_example = rasterized_pop * sample_points

Now we can combine this plot with our header in a pn.Column:

mini_dashboard = pn.Column(header, earthquake_example)
mini_dashboard