def range(cls, dataset, dim): dim = dataset.get_dimension_index(dim) if dim in [0, 1]: ranges = [] arr = geom_to_array(dataset.data.geometry.iloc[0]) ds = dataset.clone(arr, datatype=cls.subtypes, vdims=[]) for d in dataset.data.geometry: ds.data = geom_to_array(d) ranges.append(ds.interface.range(ds, dim)) return max_range(ranges) else: dim = dataset.get_dimension(dim) vals = dataset.data[dim.name] return vals.min(), vals.max()
def get_extents(self, element, ranges, range_type='combined'): """ Use first two key dimensions to set names, and all four to set the data range. """ kdims = element.kdims # loop over start and end points of segments # simultaneously in each dimension for kdim0, kdim1 in zip([kdims[i].name for i in range(2)], [kdims[i].name for i in range(2, 4)]): new_range = {} for kdim in [kdim0, kdim1]: # for good measure, update ranges for both start and end kdim for r in ranges[kdim]: # combine (x0, x1) and (y0, y1) in range calculation new_range[r] = max_range( [ranges[kd][r] for kd in [kdim0, kdim1]]) ranges[kdim0] = new_range ranges[kdim1] = new_range return super(SegmentPlot, self).get_extents(element, ranges, range_type)
def link_axes(root_view, root_model): """ Pre-processing hook to allow linking axes across HoloViews bokeh plots. """ panes = root_view.select(HoloViews) if not panes: return from holoviews.core.options import Store from holoviews.core.util import unique_iterator, max_range from holoviews.plotting.bokeh.element import ElementPlot ref = root_model.ref['id'] range_map = defaultdict(list) for pane in panes: if ref not in pane._plots: continue plot = pane._plots[ref][0] if (not pane.linked_axes or plot.renderer.backend != 'bokeh' or not getattr(plot, 'shared_axes', False)): continue for p in plot.traverse(specs=[ElementPlot]): if p.current_frame is None: continue axiswise = Store.lookup_options('bokeh', p.current_frame, 'norm').kwargs.get('axiswise') if not p.shared_axes or axiswise: continue fig = p.state if fig.x_range.tags: range_map[fig.x_range.tags[0]].append((fig, p, fig.xaxis[0], fig.x_range)) if fig.y_range.tags: range_map[fig.y_range.tags[0]].append((fig, p, fig.yaxis[0], fig.y_range)) for (tag), axes in range_map.items(): fig, p, ax, axis = axes[0] if isinstance(axis, Range1d): start, end = max_range([ (ax[-1].start, ax[-1].end) for ax in axes if isinstance(ax[-1], Range1d) ]) axis.start = start axis.end = end for fig, p, pax, _ in axes[1:]: changed = [] if type(ax) is not type(pax): continue if tag in fig.x_range.tags and not axis is fig.x_range: if hasattr(axis, 'factors'): axis.factors = list(unique_iterator(axis.factors+fig.x_range.factors)) fig.x_range = axis p.handles['x_range'] = axis changed.append('x_range') if tag in fig.y_range.tags and not axis is fig.y_range: if hasattr(axis, 'factors'): axis.factors = list(unique_iterator(axis.factors+fig.y_range.factors)) fig.y_range = axis p.handles['y_range'] = axis changed.append('y_range') # Reinitialize callbacks linked to replaced axes subplots = getattr(p, 'subplots') if subplots: plots = subplots.values() else: plots = [p] for sp in plots: for callback in sp.callbacks: if not any(c in callback.models or c in callback.extra_models for c in changed): continue if 'x_range' in changed: sp.handles['x_range'] = p.handles['x_range'] if 'y_range' in changed: sp.handles['y_range'] = p.handles['y_range'] callback.reset() callback.initialize(plot_id=p.id)
def test_max_range2(self): lower, upper = max_range(self.ranges2) self.assertTrue(math.isnan(lower)) self.assertTrue(math.isnan(upper))
def test_max_range1(self): self.assertEqual(max_range(self.ranges1), (-0.37, 1.02))