holoviz / panel
1 7
import datetime as dt
2 7
from collections import OrderedDict
3

4 7
import pytest
5 7
import numpy as np
6

7 7
try:
8 7
    import holoviews as hv
9 0
except Exception:
10 0
    hv = None
11

12 7
from bokeh.models import (Row as BkRow, Column as BkColumn, GlyphRenderer,
13
                          Scatter, Line, GridBox, Select as BkSelect,
14
                          Slider as BkSlider, Spacer as BkSpacer,
15
                          ColumnDataSource)
16 7
from bokeh.plotting import Figure
17

18 7
from panel.layout import Column, Row
19 7
from panel.pane import Pane, PaneBase, HoloViews
20 7
from panel.widgets import FloatSlider, DiscreteSlider, Select
21 7
from panel.tests.util import hv_available, mpl_available
22

23

24 7
@hv_available
25 2
def test_get_holoviews_pane_type():
26 7
    curve = hv.Curve([1, 2, 3])
27 7
    assert PaneBase.get_pane_type(curve) is HoloViews
28

29

30 7
@pytest.mark.usefixtures("hv_mpl")
31 7
@mpl_available
32 7
@hv_available
33 2
def test_holoviews_pane_mpl_renderer(document, comm):
34 7
    curve = hv.Curve([1, 2, 3])
35 7
    pane = Pane(curve)
36

37
    # Create pane
38 7
    row = pane.get_root(document, comm=comm)
39 7
    assert isinstance(row, BkRow)
40 7
    assert len(row.children) == 1
41 7
    model = row.children[0]
42 7
    assert pane._models[row.ref['id']][0] is model
43 7
    assert model.text.startswith('<img src=')
44

45
    # Replace Pane.object
46 7
    scatter = hv.Scatter([1, 2, 3])
47 7
    pane.object = scatter
48 7
    new_model = row.children[0]
49 7
    assert model.text != new_model.text
50

51
    # Cleanup
52 7
    pane._cleanup(row)
53 7
    assert pane._models == {}
54

55

56 7
@pytest.mark.usefixtures("hv_mpl")
57 7
@pytest.mark.usefixtures("hv_bokeh")
58 7
@mpl_available
59 7
@hv_available
60 2
def test_holoviews_pane_switch_backend(document, comm):
61 7
    curve = hv.Curve([1, 2, 3])
62 7
    pane = Pane(curve)
63

64
    # Create pane
65 7
    row = pane.get_root(document, comm=comm)
66 7
    assert isinstance(row, BkRow)
67 7
    assert len(row.children) == 1
68 7
    model = row.children[0]
69 7
    assert pane._models[row.ref['id']][0] is model
70 7
    assert model.text.startswith('<img src=')
71

72
    # Replace Pane.object
73 7
    pane.backend = 'bokeh'
74 7
    model = row.children[0]
75 7
    assert isinstance(model, Figure)
76

77
    # Cleanup
78 7
    pane._cleanup(row)
79 7
    assert pane._models == {}
80

81

82 7
@pytest.mark.usefixtures("hv_bokeh")
83 7
@hv_available
84 2
def test_holoviews_pane_bokeh_renderer(document, comm):
85 7
    curve = hv.Curve([1, 2, 3])
86 7
    pane = Pane(curve)
87

88
    # Create pane
89 7
    row = pane.get_root(document, comm=comm)
90 7
    assert isinstance(row, BkRow)
91 7
    assert len(row.children) == 1
92 7
    model = row.children[0]
93 7
    assert isinstance(model, Figure)
94 7
    assert pane._models[row.ref['id']][0] is model
95 7
    renderers = [r for r in model.renderers if isinstance(r, GlyphRenderer)]
96 7
    assert len(renderers) == 1
97 7
    assert isinstance(renderers[0].glyph, Line)
98

99
    # Replace Pane.object
100 7
    scatter = hv.Scatter([1, 2, 3])
101 7
    pane.object = scatter
102 7
    model = row.children[0]
103 7
    assert isinstance(model, Figure)
104 7
    renderers = [r for r in model.renderers if isinstance(r, GlyphRenderer)]
105 7
    assert len(renderers) == 1
106 7
    assert isinstance(renderers[0].glyph, Scatter)
107 7
    assert pane._models[row.ref['id']][0] is model
108

109
    # Cleanup
110 7
    pane._cleanup(row)
111 7
    assert pane._models == {}
112

113

114 7
@pytest.mark.usefixtures("hv_bokeh")
115 7
@hv_available
116 2
def test_holoviews_pane_initialize_empty(document, comm):
117 7
    pane = HoloViews()
118

119
    # Create pane
120 7
    row = pane.get_root(document, comm=comm)
121

122 7
    assert isinstance(row, BkRow)
123 7
    assert len(row.children) == 1
124 7
    model = row.children[0]
125 7
    assert isinstance(model, BkSpacer)
126

127 7
    pane.object = hv.Curve([1, 2, 3])
128 7
    model = row.children[0]
129 7
    assert isinstance(model, Figure)
130

131

132 7
@hv_available
133 2
def test_holoviews_widgets_from_dynamicmap(document, comm):
134 7
    range_dim = hv.Dimension('A', range=(0, 10.))
135 7
    range_step_dim = hv.Dimension('B', range=(0, 10.), step=0.2)
136 7
    range_default_dim = hv.Dimension('C', range=(0, 10.), default=3)
137 7
    value_dim = hv.Dimension('D', values=['a', 'b', 'c'])
138 7
    value_default_dim = hv.Dimension('E', values=['a', 'b', 'c', 'd'], default='b')
139 7
    value_numeric_dim = hv.Dimension('F', values=[1, 3, 10], default=3)
140 7
    kdims = [range_dim, range_step_dim, range_default_dim,
141
             value_dim, value_default_dim, value_numeric_dim]
142 7
    dmap = hv.DynamicMap(lambda A, B, C, D, E, F: hv.Curve([]), kdims=kdims)
143 7
    widgets, _ = HoloViews.widgets_from_dimensions(dmap)
144

145 7
    assert len(widgets) == len(kdims)
146

147 7
    assert isinstance(widgets[0], FloatSlider)
148 7
    assert widgets[0].name == 'A'
149 7
    assert widgets[0].start == range_dim.range[0]
150 7
    assert widgets[0].end == range_dim.range[1]
151 7
    assert widgets[0].value == range_dim.range[0]
152 7
    assert widgets[0].step == 0.1
153

154 7
    assert isinstance(widgets[1], FloatSlider)
155 7
    assert widgets[1].name == 'B'
156 7
    assert widgets[1].start == range_step_dim.range[0]
157 7
    assert widgets[1].end == range_step_dim.range[1]
158 7
    assert widgets[1].value == range_step_dim.range[0]
159 7
    assert widgets[1].step == range_step_dim.step
160

161 7
    assert isinstance(widgets[2], FloatSlider)
162 7
    assert widgets[2].name == 'C'
163 7
    assert widgets[2].start == range_default_dim.range[0]
164 7
    assert widgets[2].end == range_default_dim.range[1]
165 7
    assert widgets[2].value == range_default_dim.default
166 7
    assert widgets[2].step == 0.1
167

168 7
    assert isinstance(widgets[3], Select)
169 7
    assert widgets[3].name == 'D'
170 7
    assert widgets[3].options == value_dim.values
171 7
    assert widgets[3].value == value_dim.values[0]
172

173 7
    assert isinstance(widgets[4], Select)
174 7
    assert widgets[4].name == 'E'
175 7
    assert widgets[4].options == value_default_dim.values
176 7
    assert widgets[4].value == value_default_dim.default
177

178 7
    assert isinstance(widgets[5], DiscreteSlider)
179 7
    assert widgets[5].name == 'F'
180 7
    assert widgets[5].options == OrderedDict([(str(v), v) for v in value_numeric_dim.values])
181 7
    assert widgets[5].value == value_numeric_dim.default
182

183

184 7
@hv_available
185 2
def test_holoviews_with_widgets(document, comm):
186 7
    hmap = hv.HoloMap({(i, chr(65+i)): hv.Curve([i]) for i in range(3)}, kdims=['X', 'Y'])
187

188 7
    hv_pane = HoloViews(hmap)
189 7
    layout = hv_pane.get_root(document, comm)
190 7
    model = layout.children[0]
191 7
    assert len(hv_pane.widget_box.objects) == 2
192 7
    assert hv_pane.widget_box.objects[0].name == 'X'
193 7
    assert hv_pane.widget_box.objects[1].name == 'Y'
194

195 7
    assert hv_pane._models[layout.ref['id']][0] is model
196

197 7
    hmap = hv.HoloMap({(i, chr(65+i)): hv.Curve([i]) for i in range(3)}, kdims=['A', 'B'])
198 7
    hv_pane.object = hmap
199 7
    assert len(hv_pane.widget_box.objects) == 2
200 7
    assert hv_pane.widget_box.objects[0].name == 'A'
201 7
    assert hv_pane.widget_box.objects[1].name == 'B'
202

203

204 7
@hv_available
205 2
def test_holoviews_updates_widgets(document, comm):
206 7
    hmap = hv.HoloMap({(i, chr(65+i)): hv.Curve([i]) for i in range(3)}, kdims=['X', 'Y'])
207

208 7
    hv_pane = HoloViews(hmap)
209 7
    layout = hv_pane.get_root(document, comm)
210

211 7
    hv_pane.widgets = {'X': Select}
212 7
    assert isinstance(hv_pane.widget_box[0], Select)
213 7
    assert isinstance(layout.children[1].children[0].children[0], BkSelect)
214

215 7
    hv_pane.widgets = {'X': DiscreteSlider}
216 7
    assert isinstance(hv_pane.widget_box[0], DiscreteSlider)
217 7
    assert isinstance(layout.children[1].children[0].children[0], BkColumn)
218 7
    assert isinstance(layout.children[1].children[0].children[0].children[1], BkSlider)
219

220 7
@hv_available
221 2
def test_holoviews_widgets_update_plot(document, comm):
222 7
    hmap = hv.HoloMap({(i, chr(65+i)): hv.Curve([i]) for i in range(3)}, kdims=['X', 'Y'])
223

224 7
    hv_pane = HoloViews(hmap, backend='bokeh')
225 7
    layout = hv_pane.get_root(document, comm)
226

227 7
    cds = layout.children[0].select_one(ColumnDataSource)
228 7
    assert cds.data['y'] == np.array([0])
229 7
    hv_pane.widget_box[0].value = 1
230 7
    hv_pane.widget_box[1].value = chr(65+1)
231 7
    assert cds.data['y'] == np.array([1])
232

233

234 7
@hv_available
235 2
def test_holoviews_with_widgets_not_shown(document, comm):
236 7
    hmap = hv.HoloMap({(i, chr(65+i)): hv.Curve([i]) for i in range(3)}, kdims=['X', 'Y'])
237

238 7
    hv_pane = HoloViews(hmap, show_widgets=False)
239 7
    layout_obj = Column(hv_pane, hv_pane.widget_box)
240 7
    layout = layout_obj.get_root(document, comm)
241 7
    model = layout.children[0]
242 7
    assert len(hv_pane.widget_box.objects) == 2
243 7
    assert hv_pane.widget_box.objects[0].name == 'X'
244 7
    assert hv_pane.widget_box.objects[1].name == 'Y'
245

246 7
    assert hv_pane._models[layout.ref['id']][0] is model
247

248 7
    hmap = hv.HoloMap({(i, chr(65+i)): hv.Curve([i]) for i in range(3)}, kdims=['A', 'B'])
249 7
    hv_pane.object = hmap
250 7
    assert len(hv_pane.widget_box.objects) == 2
251 7
    assert hv_pane.widget_box.objects[0].name == 'A'
252 7
    assert hv_pane.widget_box.objects[1].name == 'B'
253

254

255 7
@hv_available
256 2
def test_holoviews_layouts(document, comm):
257 7
    hmap = hv.HoloMap({(i, chr(65+i)): hv.Curve([i]) for i in range(3)}, kdims=['X', 'Y'])
258

259 7
    hv_pane = HoloViews(hmap, backend='bokeh')
260 7
    layout = hv_pane.layout
261 7
    model = layout.get_root(document, comm)
262

263 7
    for center in (True, False):
264 7
        for loc in HoloViews.param.widget_location.objects:
265 7
            hv_pane.param.set_param(center=center, widget_location=loc)
266 7
            if center:
267 7
                if loc.startswith('left'):
268 7
                    assert len(layout) == 4
269 7
                    widgets, hv_obj = layout[0], layout[2]
270 7
                    wmodel, hv_model = model.children[0],  model.children[2]
271 7
                elif loc.startswith('right'):
272 7
                    assert len(layout) == 4
273 7
                    hv_obj, widgets = layout[1], layout[3]
274 7
                    wmodel, hv_model = model.children[3],  model.children[1]
275 7
                elif loc.startswith('top'):
276 7
                    assert len(layout) == 3
277 7
                    col = layout[1]
278 7
                    cmodel = model.children[1]
279 7
                    assert isinstance(col, Column)
280 7
                    widgets, hv_col = col
281 7
                    hv_obj = hv_col[1]
282 7
                    wmodel, hv_model = cmodel.children[0],  cmodel.children[1].children[1]
283 7
                elif loc.startswith('bottom'):
284 7
                    col = layout[1]
285 7
                    cmodel = model.children[1]
286 7
                    assert isinstance(col, Column)
287 7
                    hv_col, widgets = col
288 7
                    hv_obj = hv_col[1]
289 7
                    wmodel, hv_model = cmodel.children[1],  cmodel.children[0].children[1]
290
            else:
291 7
                if loc.startswith('left'):
292 7
                    assert len(layout) == 2
293 7
                    widgets, hv_obj = layout
294 7
                    wmodel, hv_model = model.children
295 7
                elif loc.startswith('right'):
296 7
                    assert len(layout) == 2
297 7
                    hv_obj, widgets = layout
298 7
                    hv_model, wmodel = model.children
299 7
                elif loc.startswith('top'):
300 7
                    assert len(layout) == 1
301 7
                    col = layout[0]
302 7
                    cmodel = model.children[0]
303 7
                    assert isinstance(col, Column)
304 7
                    widgets, hv_obj = col
305 7
                    wmodel, hv_model = cmodel.children
306 7
                elif loc.startswith('bottom'):
307 7
                    assert len(layout) == 1
308 7
                    col = layout[0]
309 7
                    cmodel = model.children[0]
310 7
                    assert isinstance(col, Column)
311 7
                    hv_obj, widgets = col
312 7
                    hv_model, wmodel = cmodel.children
313 7
            assert hv_pane is hv_obj
314 7
            assert isinstance(hv_model, Figure)
315

316 7
            if loc in ('left', 'right', 'top', 'bottom',
317
                       'top_right', 'right_bottom', 'bottom_right',
318
                       'left_bottom'):
319 7
                box = widgets[1]
320 7
                boxmodel = wmodel.children[1]
321
            else:
322 7
                box = widgets[0]
323 7
                boxmodel = wmodel.children[0]
324 7
            assert hv_pane.widget_box is box
325 7
            assert isinstance(boxmodel, BkColumn)
326 7
            assert isinstance(boxmodel.children[0], BkColumn)
327 7
            assert isinstance(boxmodel.children[0].children[1], BkSlider)
328 7
            assert isinstance(boxmodel.children[1], BkSelect)
329

330

331 7
@hv_available
332 2
def test_holoviews_widgets_from_holomap():
333 7
    hmap = hv.HoloMap({(i, chr(65+i)): hv.Curve([i]) for i in range(3)}, kdims=['X', 'Y'])
334

335 7
    widgets, _ = HoloViews.widgets_from_dimensions(hmap)
336

337 7
    assert isinstance(widgets[0], DiscreteSlider)
338 7
    assert widgets[0].name == 'X'
339 7
    assert widgets[0].options == OrderedDict([(str(i), i) for i in range(3)])
340 7
    assert widgets[0].value == 0
341

342 7
    assert isinstance(widgets[1], Select)
343 7
    assert widgets[1].name == 'Y'
344 7
    assert widgets[1].options == ['A', 'B', 'C']
345 7
    assert widgets[1].value == 'A'
346

347

348 7
@hv_available
349 2
def test_holoviews_date_slider_widgets_from_holomap():
350 7
    hmap = hv.HoloMap({dt.datetime(2016, 1, i+1): hv.Curve([i]) for i in range(3)}, kdims=['X'])
351

352 7
    widgets, _ = HoloViews.widgets_from_dimensions(hmap)
353

354 7
    assert isinstance(widgets[0], DiscreteSlider)
355 7
    assert widgets[0].name == 'X'
356 7
    assert widgets[0].options == OrderedDict([
357
        ('2016-01-01 00:00:00', dt.datetime(2016, 1, 1)),
358
        ('2016-01-02 00:00:00', dt.datetime(2016, 1, 2)),
359
        ('2016-01-03 00:00:00', dt.datetime(2016, 1, 3))])
360 7
    assert widgets[0].value == dt.datetime(2016, 1, 1)
361

362

363 7
@hv_available
364 2
def test_holoviews_widgets_explicit_widget_type_override():
365 7
    hmap = hv.HoloMap({(i, chr(65+i)): hv.Curve([i]) for i in range(3)}, kdims=['X', 'Y'])
366

367 7
    widgets, _ = HoloViews.widgets_from_dimensions(hmap, widget_types={'X': Select})
368

369 7
    assert isinstance(widgets[0], Select)
370 7
    assert widgets[0].name == 'X'
371 7
    assert widgets[0].options == OrderedDict([(str(i), i) for i in range(3)])
372 7
    assert widgets[0].value == 0
373

374

375 7
@hv_available
376 2
def test_holoviews_widgets_invalid_widget_type_override():
377 7
    hmap = hv.HoloMap({(i, chr(65+i)): hv.Curve([i]) for i in range(3)}, kdims=['X', 'Y'])
378

379 7
    with pytest.raises(ValueError):
380 7
        HoloViews.widgets_from_dimensions(hmap, widget_types={'X': 1})
381

382

383 7
@hv_available
384 2
def test_holoviews_widgets_explicit_widget_instance_override():
385 7
    hmap = hv.HoloMap({(i, chr(65+i)): hv.Curve([i]) for i in range(3)}, kdims=['X', 'Y'])
386

387 7
    widget = Select(options=[1, 2, 3], value=3)
388 7
    widgets, _ = HoloViews.widgets_from_dimensions(hmap, widget_types={'X': widget})
389

390 7
    assert widgets[0] is widget
391

392

393 7
@hv_available
394 2
def test_holoviews_linked_axes(document, comm):
395 7
    c1 = hv.Curve([1, 2, 3])
396 7
    c2 = hv.Curve([1, 2, 3])
397

398 7
    layout = Row(HoloViews(c1, backend='bokeh'), HoloViews(c2, backend='bokeh'))
399

400 7
    row_model = layout.get_root(document, comm=comm)
401

402 7
    p1, p2 = row_model.select({'type': Figure})
403

404 7
    assert p1.x_range is p2.x_range
405 7
    assert p1.y_range is p2.y_range
406

407

408 7
@hv_available
409 2
def test_holoviews_linked_axes_merged_ranges(document, comm):
410 7
    c1 = hv.Curve([1, 2, 3])
411 7
    c2 = hv.Curve([0, 1, 2, 3, 4])
412

413 7
    layout = Row(HoloViews(c1, backend='bokeh'), HoloViews(c2, backend='bokeh'))
414

415 7
    row_model = layout.get_root(document, comm=comm)
416

417 7
    p1, p2 = row_model.select({'type': Figure})
418

419 7
    assert p1.x_range is p2.x_range
420 7
    assert p1.y_range is p2.y_range
421 7
    assert p1.y_range.start == -0.4
422 7
    assert p1.y_range.end == 4.4
423

424

425 7
@hv_available
426 2
def test_holoviews_linked_x_axis(document, comm):
427 7
    c1 = hv.Curve([1, 2, 3])
428 7
    c2 = hv.Curve([1, 2, 3], vdims='y2')
429

430 7
    layout = Row(HoloViews(c1, backend='bokeh'), HoloViews(c2, backend='bokeh'))
431

432 7
    row_model = layout.get_root(document, comm=comm)
433

434 7
    p1, p2 = row_model.select({'type': Figure})
435

436 7
    assert p1.x_range is p2.x_range
437 7
    assert p1.y_range is not p2.y_range
438

439

440 7
@hv_available
441 2
def test_holoviews_axiswise_not_linked_axes(document, comm):
442 7
    c1 = hv.Curve([1, 2, 3])
443 7
    c2 = hv.Curve([1, 2, 3]).opts(axiswise=True, backend='bokeh')
444

445 7
    layout = Row(HoloViews(c1, backend='bokeh'), HoloViews(c2, backend='bokeh'))
446

447 7
    row_model = layout.get_root(document, comm=comm)
448

449 7
    p1, p2 = row_model.select({'type': Figure})
450

451 7
    assert p1.x_range is not p2.x_range
452 7
    assert p1.y_range is not p2.y_range
453

454

455 7
@hv_available
456 2
def test_holoviews_shared_axes_opt_not_linked_axes(document, comm):
457 7
    c1 = hv.Curve([1, 2, 3])
458 7
    c2 = hv.Curve([1, 2, 3]).opts(shared_axes=False, backend='bokeh')
459

460 7
    layout = Row(HoloViews(c1, backend='bokeh'), HoloViews(c2, backend='bokeh'))
461

462 7
    row_model = layout.get_root(document, comm=comm)
463

464 7
    p1, p2 = row_model.select({'type': Figure})
465

466 7
    assert p1.x_range is not p2.x_range
467 7
    assert p1.y_range is not p2.y_range
468

469

470 7
@hv_available
471 2
def test_holoviews_not_linked_axes(document, comm):
472 7
    c1 = hv.Curve([1, 2, 3])
473 7
    c2 = hv.Curve([1, 2, 3])
474

475 7
    layout = Row(
476
        HoloViews(c1, backend='bokeh'),
477
        HoloViews(c2, backend='bokeh', linked_axes=False)
478
    )
479

480 7
    row_model = layout.get_root(document, comm=comm)
481

482 7
    p1, p2 = row_model.select({'type': Figure})
483

484 7
    assert p1.x_range is not p2.x_range
485 7
    assert p1.y_range is not p2.y_range
486

487

488 7
@hv_available
489 2
def test_holoviews_link_across_panes(document, comm):
490 7
    from bokeh.models.tools import RangeTool
491 7
    from holoviews.plotting.links import RangeToolLink
492

493 7
    c1 = hv.Curve([])
494 7
    c2 = hv.Curve([])
495

496 7
    RangeToolLink(c1, c2)
497

498 7
    layout = Row(Pane(c1, backend='bokeh'), Pane(c2, backend='bokeh'))
499 7
    row = layout.get_root(document, comm=comm)
500

501 7
    assert len(row.children) == 2
502 7
    p1, p2 = row.children
503

504 7
    assert isinstance(p1, Figure)
505 7
    assert isinstance(p2, Figure)
506

507 7
    range_tool = row.select_one({'type': RangeTool})
508 7
    assert isinstance(range_tool, RangeTool)
509 7
    assert range_tool.x_range == p2.x_range
510

511

512 7
@hv_available
513 2
def test_holoviews_link_after_adding_item(document, comm):
514 7
    from bokeh.models.tools import RangeTool
515 7
    from holoviews.plotting.links import RangeToolLink
516

517 7
    c1 = hv.Curve([])
518 7
    c2 = hv.Curve([])
519

520 7
    RangeToolLink(c1, c2)
521

522 7
    layout = Row(Pane(c1, backend='bokeh'))
523 7
    row = layout.get_root(document, comm=comm)
524

525 7
    assert len(row.children) == 1
526 7
    p1, = row.children
527

528 7
    assert isinstance(p1, Figure)
529 7
    range_tool = row.select_one({'type': RangeTool})
530 7
    assert range_tool is None
531

532 7
    layout.append(Pane(c2, backend='bokeh'))
533 7
    _, p2 = row.children
534 7
    assert isinstance(p2, Figure)
535 7
    range_tool = row.select_one({'type': RangeTool})
536 7
    assert isinstance(range_tool, RangeTool)
537 7
    assert range_tool.x_range == p2.x_range
538

539

540 7
@hv_available
541 2
def test_holoviews_link_within_pane(document, comm):
542 7
    from bokeh.models.tools import RangeTool
543 7
    from holoviews.plotting.links import RangeToolLink
544

545 7
    c1 = hv.Curve([])
546 7
    c2 = hv.Curve([])
547

548 7
    RangeToolLink(c1, c2)
549

550 7
    pane = Pane(Pane(hv.Layout([c1, c2]), backend='bokeh'))
551 7
    column = pane.get_root(document, comm=comm)
552

553 7
    assert len(column.children) == 1
554 7
    subcolumn = column.children[0]
555 7
    assert isinstance(subcolumn, BkColumn)
556 7
    assert len(subcolumn.children) == 2
557 7
    toolbar, subsubcolumn = subcolumn.children
558 7
    assert isinstance(subsubcolumn, GridBox)
559 7
    assert len(subsubcolumn.children) == 2
560 7
    (p1, _, _), (p2, _, _) = subsubcolumn.children
561

562 7
    assert isinstance(p1, Figure)
563 7
    assert isinstance(p2, Figure)
564

565 7
    range_tool = subsubcolumn.select_one({'type': RangeTool})
566 7
    assert isinstance(range_tool, RangeTool)
567 7
    assert range_tool.x_range == p2.x_range
568

569

570 7
@hv_available
571 2
def test_holoviews_property_override(document, comm):
572 7
    c1 = hv.Curve([])
573

574 7
    pane = Pane(c1, backend='bokeh', background='red',
575
                css_classes=['test_class'])
576 7
    model = pane.get_root(document, comm=comm)
577

578 7
    assert model.background == 'red'
579 7
    assert model.css_classes == ['test_class']

Read our documentation on viewing source code .

Loading