/
renderer.py
123 lines (100 loc) · 4.39 KB
/
renderer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import uuid
from ...core import Store, HoloMap
from ..renderer import Renderer, MIME_TYPES
from .widgets import BokehScrubberWidget, BokehSelectionWidget
from .util import models_to_json
import param
from param.parameterized import bothmethod
from bokeh.embed import notebook_div
from bokeh.io import load_notebook, Document
from bokeh.resources import CDN, INLINE
try:
from bokeh.protocol import serialize_json
bokeh_lt_011 = True
except ImportError:
from bokeh.core.json_encoder import serialize_json
bokeh_lt_011 = False
class BokehRenderer(Renderer):
backend = param.String(default='bokeh', doc="The backend name.")
fig = param.ObjectSelector(default='auto', objects=['html', 'json', 'auto'], doc="""
Output render format for static figures. If None, no figure
rendering will occur. """)
# Defines the valid output formats for each mode.
mode_formats = {'fig': {'default': ['html', 'json', 'auto']},
'holomap': {'default': ['widgets', 'scrubber', 'auto', None]}}
webgl = param.Boolean(default=True, doc="""Whether to render plots with WebGL
if bokeh version >=0.10""")
widgets = {'scrubber': BokehScrubberWidget,
'widgets': BokehSelectionWidget}
backend_dependencies = {'js': CDN.js_files, 'css': CDN.css_files}
_loaded = False
def __call__(self, obj, fmt=None):
"""
Render the supplied HoloViews component using the appropriate
backend. The output is not a file format but a suitable,
in-memory byte stream together with any suitable metadata.
"""
plot, fmt = self._validate(obj, fmt)
info = {'file-ext': fmt, 'mime_type': MIME_TYPES[fmt]}
if isinstance(plot, tuple(self.widgets.values())):
return plot(), info
elif fmt == 'html':
html = self.figure_data(plot)
html = '<center>%s</center>' % html
return html, info
elif fmt == 'json':
plotobjects = [h for handles in plot.traverse(lambda x: x.current_handles)
for h in handles]
data = dict(data=[])
if not bokeh_lt_011:
data['root'] = plot.state._id
data['data'] = models_to_json(plotobjects)
return serialize_json(data), info
def figure_data(self, plot, fmt='html', **kwargs):
if not bokeh_lt_011:
doc = Document()
doc.add_root(plot.state)
comms_target = str(uuid.uuid4())
doc.last_comms_target = comms_target
div = notebook_div(plot.state, comms_target)
return div
else:
return notebook_div(plot.state)
@classmethod
def plot_options(cls, obj, percent_size):
"""
Given a holoviews object and a percentage size, apply heuristics
to compute a suitable figure size. For instance, scaling layouts
and grids linearly can result in unwieldy figure sizes when there
are a large number of elements. As ad hoc heuristics are used,
this functionality is kept separate from the plotting classes
themselves.
Used by the IPython Notebook display hooks and the save
utility. Note that this can be overridden explicitly per object
using the fig_size and size plot options.
"""
factor = percent_size / 100.0
obj = obj.last if isinstance(obj, HoloMap) else obj
plot = Store.registry[cls.backend].get(type(obj), None)
options = Store.lookup_options(cls.backend, obj, 'plot').options
if not hasattr(plot, 'width') or not hasattr(plot, 'height'):
from .plot import BokehPlot
plot = BokehPlot
width = options.get('width', plot.width) * factor
height = options.get('height', plot.height) * factor
return dict(options, **{'width':int(width), 'height': int(height)})
@bothmethod
def get_size(self_or_cls, plot):
"""
Return the display size associated with a plot before
rendering to any particular format. Used to generate
appropriate HTML display.
Returns a tuple of (width, height) in pixels.
"""
return (plot.state.height, plot.state.height)
@classmethod
def load_nb(cls, inline=True):
"""
Loads the bokeh notebook resources.
"""
load_notebook(hide_banner=True, resources=INLINE if inline else CDN)