<jupyter_start><jupyter_text>Exercise 5: Exporting and Deploying Apps<jupyter_code>import time
from itertools import cycle

import holoviews as hv
import geoviews as gv
import param
import panel as pn
import dask.dataframe as dd
import pandas as pd

from colorcet import cm_n
from holoviews import opts
from holoviews.operation.datashader import dynspread, rasterize, shade
from holoviews.streams import RangeXY

hv.extension('bokeh')

def taxi_trips_stream(source='../../data/nyc_taxi_wide.parq', frequency='H'):
    """Generate dataframes grouped by given frequency"""
    def get_group(resampler, key):
        try:
            df = resampler.get_group(key)
            df.reset_index(drop=True)
        except KeyError:
            df = pd.DataFrame()
        return df

    df = pd.read_parquet(source,
                     columns=['tpep_pickup_datetime', 'pickup_x', 'pickup_y', 'tip_amount'])
    df = df.set_index('tpep_pickup_datetime', drop=True)
    df = df.sort_index()
    r = df.resample(frequency)
    chunks = [get_group(r, g) for g in sorted(r.groups)]
    indices = cycle(range(len(chunks)))
    while True:
        yield chunks[next(indices)]

trips = taxi_trips_stream()
example = next(trips)<jupyter_output><empty_output><jupyter_text>Example 1In this example we will be doing something a bit more complex - building a full app with widgets. Below we have already outlined the basic components of this app, including a ``NYCTaxiStream`` class that takes some ``data`` and turns those into datashaded ``Points``. You should execute that cell before you change anything about it, so that you are sure it works at the start.Your task will be to add some custom widgets to this plot by adding parameters to the ``NYCTaxiStream`` class to control the NYCTaxiStream output. 1.) Begin by adding a widget that will allow us to select between the different cmaps available from ``cm_n.values()``.HintAdding a widget is as simple as adding a Parameter of the right type to the class. To select between different options use:    param.ObjectSelector(default=..., objects=...) HintThe ``shade`` operation supports streams such as the `Params` stream which can be used to subscribe to specific parameters changing.2.) Now add a parameter that filters the data based on one of the columns in the data, e.g. trips with >N passengers or the minimum tip.HintThe ``param.Number`` and ``param.NumericTuple`` parameters allow defining scalar values and ranges respectively. Ensure that you set the ``bounds`` which declare the range of valid values. Remember that you can express the dependencies of a method using the `param.depends` decorator and that the ``.select`` method on elements can be used to filter the data.    param.ObjectSelector(default=..., objects=...)<jupyter_code>tile_options = opts.WMTS(width=600,height=400,xaxis=None,yaxis=None,bgcolor='black',show_grid=False)

class NYCTaxiStream(param.Parameterized):
    
    time = param.Number(default=0, bounds=(0, 24))

    def __init__(self, **params):
        self.pipe = hv.streams.Pipe(example)
        super(NYCTaxiStream, self).__init__(**params)
    
    @param.depends('time', watch=True)
    def update(self):
        self.pipe.send(next(trips))

    def points(self, data):
        return hv.Points(data, ['pickup_x', 'pickup_y'], label=str(data.index[0]))

    def view(self):
        points = hv.DynamicMap(self.points, streams=[self.pipe])
        raster = rasterize(points, x_sampling=1, y_sampling=1, width=700, height=400)
        tiles = gv.tile_sources.Wikipedia.opts(tile_options)
        return (tiles * shade(raster)).opts(show_legend=False)

nyc_stream = NYCTaxiStream()

pn.Column(pn.Param(nyc_stream.param, widgets={'time': pn.widgets.Player}), nyc_stream.view())<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1014799154334038, 'fraction_numerical': 0.006078224101479916, 'mean_word_length': 4.2279005524861875, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '302501', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1160, 'n_tokens_neox': 1128, 'n_words': 383, 'path': 'examples/tutorial/exercises/Exercise-5-exporting-and-deploying-apps.ipynb', 'repo_name': 'rs2/pyviz', 'size': '3784'}