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 rx. 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 focused on Panel being used as a source of widgets and reactive pipelines, but you’ve also seen some Pane objects from Panel that can display various types of data (including output from just about any plotting library). To explore those, 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='bootstrap')

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’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)


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.layout.HSpacer(), pn.pane.PNG(logo_path, height=40, align='end'))

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

df = pd.read_parquet(pathlib.Path('../data/earthquakes-projected.parq'))
df.index = df.index.tz_localize(None)
df = df.reset_index()

small_df = df.sample(frac=.01)
CPU times: user 968 ms, sys: 139 ms, total: 1.11 s
Wall time: 625 ms
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 87.8 ms, sys: 55.9 ms, total: 144 ms
Wall time: 163 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)