Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added BokehRenderer.app method to create bokeh apps in scripts and notebooks #1283

Merged
merged 4 commits into from
Apr 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions holoviews/plotting/bokeh/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@

Store.renderers['bokeh'] = BokehRenderer.instance()

if len(Store.renderers) == 1:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not check that the one available renderer is 'bokeh'?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guess I could but defining that renderer is literally the line above so it has to be bokeh.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is your suggestion this?

if list(Store.renderers.keys()) == ['bokeh']

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose that's fine.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You last post appeared before my reply. Either way is fine.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, I would mention that in a script-level docstring at the top of the file. Same for the crossfilter app. It only needs to be one line explaining what these examples are supposed to show.

Store.current_backend = 'bokeh'

associations = {Overlay: OverlayPlot,
NdOverlay: OverlayPlot,
GridSpace: GridPlot,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
"""
An example demonstrating how to put together a crossfilter app based
on the Auto MPG dataset. Demonstrates how to dynamically generate
bokeh plots using the HoloViews API and replacing the bokeh plot
based on the current widget selections.
"""

import numpy as np
import pandas as pd
import holoviews as hv
Expand Down Expand Up @@ -35,7 +42,6 @@
continuous = [x for x in columns if x not in discrete]
quantileable = [x for x in continuous if len(df[x].unique()) > 20]

hv.Store.current_backend = 'bokeh'
renderer = hv.Store.renderers['bokeh']
options = hv.Store.options(backend='bokeh')
options.Points = hv.Options('plot', width=800, height=600, size_index=None,)
Expand All @@ -52,7 +58,6 @@ def create_figure():
opts['scaling_factor'] = (1./df[size.value].max())*200
points = hv.Points(df, kdims=kdims, label=label)(plot=opts, style=style)
plot = renderer.get_plot(points)
plot.initialize_plot()
return plot.state

def update(attr, old, new):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# -*- coding: utf-8 -*-
"""
Example of a simple player widget demonstrating how to connnect
a simple HoloViews plot with custom widgets and combine them
into a bokeh layout.
"""
import numpy as np
from bokeh.io import curdoc
from bokeh.layouts import layout
from bokeh.models import (
ColumnDataSource, HoverTool, SingleIntervalTicker, Slider, Button, Label,
CategoricalColorMapper,
)
from bokeh.models import Slider, Button
import holoviews as hv
import holoviews.plotting.bokeh

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
"""
Example app demonstrating how to use the HoloViews API to generate
a bokeh app with complex interactivity. Uses a Selection1D stream
to compute the mean y-value of the current selection.
"""

import numpy as np
import holoviews as hv
import holoviews.plotting.bokeh
from holoviews.streams import Selection1D

hv.Store.current_backend = 'bokeh'
renderer = hv.Store.renderers['bokeh'].instance(mode='server')
renderer = hv.Store.renderers['bokeh']
hv.Store.options(backend='bokeh').Points = hv.Options('plot', tools=['box_select'])

data = np.random.multivariate_normal((0, 0), [[1, 0.1], [0.1, 1]], (1000,))
Expand All @@ -13,5 +18,6 @@
mean_sel = hv.DynamicMap(lambda index: hv.HLine(points['y'][index].mean()
if index else -10),
kdims=[], streams=[sel])
doc,_ = renderer((points * mean_sel))

doc = renderer.app((points * mean_sel))
doc.title = 'HoloViews Selection Stream'
27 changes: 26 additions & 1 deletion holoviews/plotting/bokeh/renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
import param
from param.parameterized import bothmethod


from bokeh.application.handlers import FunctionHandler
from bokeh.application import Application
from bokeh.charts import Chart
from bokeh.document import Document
from bokeh.embed import notebook_div
from bokeh.io import load_notebook, curdoc
from bokeh.io import load_notebook, curdoc, show
from bokeh.models import (Row, Column, Plot, Model, ToolbarBox,
WidgetBox, Div, DataTable, Tabs)
from bokeh.plotting import Figure
Expand Down Expand Up @@ -92,6 +95,28 @@ def get_widget(self_or_cls, plot, widget_type, **kwargs):
return super(BokehRenderer, self_or_cls).get_widget(plot, widget_type, **kwargs)


@bothmethod
def app(self_or_cls, plot, notebook=False):
"""
Creates a bokeh app from a HoloViews object or plot. By
default simply uses attaches plot to bokeh's curdoc and
returns the Document, if notebook option is supplied creates
an Application instance, displays it and returns it.
"""
renderer = self_or_cls.instance(mode='server')
if not notebook:
doc, _ = renderer(plot)
return doc

def modify_doc(doc):
renderer(plot, doc=doc)

handler = FunctionHandler(modify_doc)
app = Application(handler)
show(app)
return app


def server_doc(self, plot, doc=None):
"""
Get server document.
Expand Down
3 changes: 3 additions & 0 deletions holoviews/plotting/mpl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ def get_color_cycle():

Store.renderers['matplotlib'] = MPLRenderer.instance()

if len(Store.renderers) == 1:
Store.current_backend = 'matplotlib'

# Defines a wrapper around GridPlot and RasterGridPlot
# switching to RasterGridPlot if the plot only contains
# Raster Elements
Expand Down
3 changes: 3 additions & 0 deletions holoviews/plotting/plotly/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@

Store.renderers['plotly'] = PlotlyRenderer.instance()

if len(Store.renderers) == 1:
Store.current_backend = 'plotly'

Store.register({Points: PointPlot,
Scatter: PointPlot,
Curve: CurvePlot,
Expand Down