{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "# NYC Taxi data with Datashader and Panel\n", "\n", "The [NYC Taxi trips](https://anaconda.org/jbednar/nyc_taxi/notebook) 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](http://datashader.org), then deploying it as a standalone dashboard using [Panel](http://panel.pyviz.org).\n", "\n", "Running the dashboard requires having a live Python process running (not just a static webpage or anaconda.org notebook viewer). Before you run the notebook or server, you'll need to set up a [conda](http://conda.pydata.org/miniconda.html) environment and run `conda install -c pyviz datashader panel geoviews`, and you'll need to [get the data file](https://anaconda.org/jbednar/nyc_taxi/notebook)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import holoviews as hv, geoviews as gv, param, dask.dataframe as dd, cartopy.crs as crs\n", "import panel as pn\n", "\n", "from colorcet import cm\n", "from holoviews.operation.datashader import rasterize, shade\n", "from holoviews.streams import RangeXY\n", "\n", "hv.extension('bokeh', logo=False)\n", "\n", "usecols = ['dropoff_x','dropoff_y','pickup_x','pickup_y','dropoff_hour','pickup_hour','passenger_count']\n", "df = dd.read_parquet('data/nyc_taxi_wide.parq')[usecols].persist()\n", "opts = dict(width=1000,height=600,xaxis=None,yaxis=None,bgcolor='black',show_grid=False)\n", "cmaps = ['fire','bgy','bgyw','bmy','gray','kbc']\n", "\n", "\n", "class NYCTaxiExplorer(param.Parameterized):\n", " alpha = param.Magnitude(default=0.75, doc=\"Alpha value for the map opacity\")\n", " cmap = param.ObjectSelector(cm['fire'], objects={c:cm[c] for c in cmaps})\n", " hour = param.Range(default=(0, 24), bounds=(0, 24))\n", " location = param.ObjectSelector(default='dropoff', objects=['dropoff', 'pickup'])\n", "\n", " @param.depends('location', 'hour')\n", " def points(self):\n", " points = hv.Points(df, kdims=[self.location+'_x', self.location+'_y'], vdims=['dropoff_hour'])\n", " if self.hour != (0, 24): points = points.select(dropoff_hour=self.hour)\n", " return points\n", "\n", " def view(self,**kwargs):\n", " points = hv.DynamicMap(self.points)\n", " tiles = gv.tile_sources.StamenTerrain().apply.opts(alpha=self.param.alpha, **opts)\n", " agg = rasterize(points, x_sampling=1, y_sampling=1, width=600, height=400)\n", " return tiles * shade(agg, cmap=self.param.cmap)\n", "\n", "taxi = NYCTaxiExplorer(name=\"NYC Taxi Trips\")\n", "pn.Row(taxi.param, taxi.view()).servable()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you can see, the resulting object is rendered in the notebook (above), and it's usable as long as you have Python running on this code. You can also launch this app as a standalone server outside of the notebook, because we've marked the relevant object `.servable()`. That declaration means that if someone later runs this notebook as a server process (using `panel serve --show nyc_taxi_panel.ipynb`), your browser will open a separate window with the serveable object ready to explore or share, just like the screenshot at the top of this notebook." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#! panel serve --show --port 5009 nyc_taxi_panel.ipynb" ] } ], "metadata": { "language_info": { "name": "python", "pygments_lexer": "ipython3" } }, "nbformat": 4, "nbformat_minor": 2 }