Selection1d tap

Regression selection
A linked streams example demonstrating how to the Selection1D stream to tap on a datapoint and reveal a regression plot. Highlights how custom interactivity can be used to reveal more information about a dataset.
streams, linked, tap selection
In [ ]:
import numpy as np
import holoviews as hv
from holoviews.streams import Selection1D
from scipy import stats
In [ ]:
%%opts Scatter [color_index=2 tools=['tap', 'hover'] width=600] {+framewise} (marker='triangle' cmap='Set1' size=10)
%%opts Overlay [toolbar='above' legend_position='right'] Curve (line_color='black') {+framewise}

def gen_samples(N, corr=0.8):
    xx = np.array([-0.51, 51.2])
    yy = np.array([0.33, 51.6])
    means = [xx.mean(), yy.mean()]  
    stds = [xx.std() / 3, yy.std() / 3]
    covs = [[stds[0]**2          , stds[0]*stds[1]*corr], 
            [stds[0]*stds[1]*corr,           stds[1]**2]] 

    return np.random.multivariate_normal(means, covs, N)

data = [('Week %d' % (i%10), np.random.rand(), chr(65+np.random.randint(5)), i) for i in range(100)]
sample_data = hv.NdOverlay({i: hv.Points(gen_samples(np.random.randint(1000, 5000), r2))
                            for _, r2, _, i in data})
points = hv.Scatter(data, kdims=['Date', 'r2'], vdims=['block', 'id']).redim.range(r2=(0., 1))
stream = Selection1D(source=points)
empty = (hv.Points(np.random.rand(0, 2)) * hv.Curve(np.random.rand(0, 2))).relabel('No selection')

def regression(index):
    if not index:
        return empty
    scatter = sample_data[index[0]]
    xs, ys = scatter['x'], scatter['y']
    slope, intercep, rval, pval, std = stats.linregress(xs, ys)
    xs = np.linspace(*scatter.range(0)+(2,))
    reg = slope*xs+intercep
    return (scatter * hv.Curve((xs, reg))).relabel('r2: %.3f' % slope)

reg = hv.DynamicMap(regression, kdims=[], streams=[stream])

average = hv.Curve(points, kdims=['Date'], vdims=['r2']).aggregate(function=np.mean)
points * average + reg

Download this notebook from GitHub (right-click to download).