import pandas as pd import holoviews as hv from holoviews import opts from bokeh.sampledata import stocks from holoviews.operation.timeseries import rolling, rolling_outlier_std hv.extension('bokeh') opts.defaults(opts.Curve(width=600, framewise=True)) def load_symbol(symbol, **kwargs): df = pd.DataFrame(getattr(stocks, symbol)) df['date'] = df.date.astype('datetime64[ns]') return hv.Curve(df, ('date', 'Date'), ('adj_close', 'Adjusted Close')) stock_symbols = ['AAPL', 'FB', 'GOOG', 'IBM', 'MSFT'] dmap = hv.DynamicMap(load_symbol, kdims='Symbol').redim.values(Symbol=stock_symbols) dmap smoothed = rolling(dmap, rolling_window=30) smoothed import panel as pn slider = pn.widgets.IntSlider(name='rolling_window', start=1, end=100, value=50) rolled_dmap = dmap.apply.transform(adj_close=hv.dim('adj_close').df.rolling(slider).mean()) rolled_dmap slider outliers = dmap.apply(rolling_outlier_std, rolling_window=slider.param.value) rolled_dmap * outliers.opts(color='red', marker='triangle') def residual_fn(overlay): # Get first and second Element in overlay el1, el2 = overlay.get(0), overlay.get(1) # Get x-values and y-values of curves xvals = el1.dimension_values(0) yvals = el1.dimension_values(1) yvals2 = el2.dimension_values(1) # Return new Element with subtracted y-values # and new label return el1.clone((xvals, yvals-yvals2), vdims='Residual') residual = (dmap * rolled_dmap).apply(residual_fn) residual