import numpy as np import holoviews as hv hv.extension('bokeh') %%opts Points [tools=['box_select', 'lasso_select']] # Declare some points points = hv.Points(np.random.randn(1000,2 )) # Declare points as source of selection stream selection = hv.streams.Selection1D(source=points) # Write function that uses the selection indices to slice points and compute stats def selected_info(index): arr = points.array()[index] if index: label = 'Mean x, y: %.3f, %.3f' % tuple(arr.mean(axis=0)) else: label = 'No selection' return points.clone(arr, label=label).options(color='red') # Combine points and DynamicMap layout = points + hv.DynamicMap(selected_info, streams=[selection]) layout renderer = hv.renderer('bokeh') print(renderer) renderer = renderer.instance(mode='server') hvplot = renderer.get_plot(layout) print(hvplot) hvplot.state html = renderer._figure_data(hvplot) renderer(layout) doc = renderer.server_doc(layout) doc.title = 'HoloViews App' def sine(frequency, phase, amplitude): xs = np.linspace(0, np.pi*4) return hv.Curve((xs, np.sin(frequency*xs+phase)*amplitude)).options(width=800) ranges = dict(frequency=(1, 5), phase=(-np.pi, np.pi), amplitude=(-2, 2), y=(-2, 2)) dmap = hv.DynamicMap(sine, kdims=['frequency', 'phase', 'amplitude']).redim.range(**ranges) app = renderer.app(dmap) print(app) from bokeh.server.server import Server server = Server({'/': app}, port=0) server.start() server.show('/') # Outside the notebook ioloop needs to be started # from tornado.ioloop import IOLoop # loop = IOLoop.current() # loop.start() server.stop() server = renderer.app(dmap, show=True, new_window=True) server.stop() renderer.app(dmap, show=True, websocket_origin='localhost:8888') def sine(counter): phase = counter*0.1%np.pi*2 xs = np.linspace(0, np.pi*4) return hv.Curve((xs, np.sin(xs+phase))).options(width=800) dmap = hv.DynamicMap(sine, streams=[hv.streams.Counter()]) app = renderer.app(dmap, show=True, websocket_origin='localhost:8888') dmap.periodic(0.1, 100) import numpy as np import holoviews as hv from bokeh.io import show from bokeh.layouts import layout from bokeh.models import Slider, Button renderer = hv.renderer('bokeh').instance(mode='server') # Create the holoviews app again def sine(phase): xs = np.linspace(0, np.pi*4) return hv.Curve((xs, np.sin(xs+phase))).options(width=800) stream = hv.streams.Stream.define('Phase', phase=0.)() dmap = hv.DynamicMap(sine, streams=[stream]) # Define valid function for FunctionHandler # when deploying as script, simply attach to curdoc def modify_doc(doc): # Create HoloViews plot and attach the document hvplot = renderer.get_plot(dmap, doc) # Create a slider and play buttons def animate_update(): year = slider.value + 0.2 if year > end: year = start slider.value = year def slider_update(attrname, old, new): # Notify the HoloViews stream of the slider update stream.event(phase=new) start, end = 0, np.pi*2 slider = Slider(start=start, end=end, value=start, step=0.2, title="Phase") slider.on_change('value', slider_update) callback_id = None def animate(): global callback_id if button.label == '► Play': button.label = '❚❚ Pause' callback_id = doc.add_periodic_callback(animate_update, 50) else: button.label = '► Play' doc.remove_periodic_callback(callback_id) button = Button(label='► Play', width=60) button.on_click(animate) # Combine the holoviews plot and widgets in a layout plot = layout([ [hvplot.state], [slider, button]], sizing_mode='fixed') doc.add_root(plot) return doc # To display in the notebook show(modify_doc, notebook_url='localhost:8888') # To display in a script # doc = modify_doc(curdoc())