Panel dashboard#

hvplotbokehdatashaderpanelparamdask
Published: January 29, 2016 · Modified: August 20, 2024


The NYC Taxi trips dataset is a well-studied data science example. Here we show how to build a simple dashboard for exploring 10 million taxi trips in a Jupyter notebook using Datashader, then deploying it as a standalone dashboard using Panel.

Panel Dashboard
import holoviews as hv
import param
import dask.dataframe as dd
import panel as pn

from holoviews.operation.datashader import rasterize, dynspread
from holoviews.element.tiles import EsriStreet

hv.extension('bokeh')
usecols = ['dropoff_x', 'dropoff_y', 'pickup_x', 'pickup_y', 'dropoff_hour', 'pickup_hour', 'passenger_count']
df = dd.read_parquet('data/nyc_taxi_wide.parq', engine='fastparquet')[usecols].persist()
opts = dict(width=1000, height=600, xaxis=None, yaxis=None, bgcolor='black', show_grid=False)
cmaps = ['fire', 'bgy', 'bgyw', 'bmy', 'gray', 'kbc']

df.head()
dropoff_x dropoff_y pickup_x pickup_y dropoff_hour pickup_hour passenger_count
0 -8234835.5 4975627.0 -8236963.0 4975552.5 19 19 1
1 -8237020.5 4976875.0 -8237826.0 4971752.5 20 20 1
2 -8232279.0 4986477.0 -8233561.5 4983296.5 20 20 1
3 -8238124.0 4971127.0 -8238654.0 4970221.0 20 20 1
4 -8238107.5 4974457.0 -8234433.5 4977363.0 20 20 1
class NYCTaxiExplorer(pn.viewable.Viewer):
    alpha      = param.Magnitude(default=0.75, doc="Alpha value for the map opacity")
    cmap       = param.Selector(objects=cmaps)
    hour       = param.Range(default=(0, 24), bounds=(0, 24))
    location   = param.Selector(objects=['dropoff', 'pickup'])

    @param.depends('location', 'hour')
    def points(self):
        points = hv.Points(df, kdims=[self.location+'_x', self.location+'_y'], vdims=['dropoff_hour'])
        if self.hour != (0, 24):
            points = points.select(dropoff_hour=self.hour)
        return points

    def __panel__(self, **kwargs):
        points = hv.DynamicMap(self.points)
        tiles = EsriStreet().apply.opts(alpha=self.param.alpha, **opts)
        agg = rasterize(points, width=600, height=400).opts(cnorm='eq_hist', nodata=0)
        return tiles * dynspread(agg).apply.opts(cmap=self.param.cmap)
        
taxi = NYCTaxiExplorer(name="NYC Taxi Trips")
pn.Row(taxi.param, taxi).servable()