diff --git a/holoviews/plotting/bokeh/chart.py b/holoviews/plotting/bokeh/chart.py index fd877759a4..80ed4fefcd 100644 --- a/holoviews/plotting/bokeh/chart.py +++ b/holoviews/plotting/bokeh/chart.py @@ -7,7 +7,8 @@ except: BokehBoxPlot = None, None from bokeh.models import (GlyphRenderer, ColumnDataSource, DataRange1d, - CategoricalColorMapper, CustomJS, HoverTool) + Range1d, CategoricalColorMapper, CustomJS, + HoverTool) from bokeh.models.tools import BoxSelectTool from ...core import Dataset, OrderedDict @@ -653,7 +654,7 @@ def _update_chart(self, key, element, ranges): @property def current_handles(self): - return self.state.select(type=(ColumnDataSource, DataRange1d)) + return self.state.select(type=(ColumnDataSource, DataRange1d, Range1d)) class BoxPlot(ChartPlot): @@ -719,6 +720,9 @@ class BarPlot(ColorbarPlot, LegendPlot): _plot_methods = dict(single=('vbar', 'hbar'), batched=('vbar', 'hbar')) + # Declare that y-range should auto-range if not bounded + _y_range_type = DataRange1d + def get_extents(self, element, ranges): """ Make adjustments to plot extents by computing diff --git a/holoviews/plotting/bokeh/element.py b/holoviews/plotting/bokeh/element.py index 0fb635aa43..7f4daa6c5d 100644 --- a/holoviews/plotting/bokeh/element.py +++ b/holoviews/plotting/bokeh/element.py @@ -167,6 +167,10 @@ class ElementPlot(BokehPlot, GenericElementPlot): _update_handles = ['source', 'glyph', 'glyph_renderer'] _categorical = False + # Declares the default types for continuous x- and y-axes + _x_range_type = Range1d + _y_range_type = Range1d + def __init__(self, element, plot=None, **params): self.current_ranges = None super(ElementPlot, self).__init__(element, **params) @@ -341,13 +345,13 @@ def _axes_props(self, plots, subplots, element, ranges): x_axis_type = 'auto' plot_ranges['x_range'] = FactorRange() elif 'x_range' not in plot_ranges: - plot_ranges['x_range'] = DataRange1d() + plot_ranges['x_range'] = self._x_range_type() if categorical or categorical_y: y_axis_type = 'auto' plot_ranges['y_range'] = FactorRange() elif 'y_range' not in plot_ranges: - plot_ranges['y_range'] = DataRange1d() + plot_ranges['y_range'] = self._y_range_type() return (x_axis_type, y_axis_type), (xlabel, ylabel, zlabel), plot_ranges @@ -523,7 +527,7 @@ def _update_ranges(self, element, ranges): y_range = self.handles['y_range'] l, b, r, t = None, None, None, None - if any(isinstance(r, DataRange1d) for r in [x_range, y_range]): + if any(isinstance(r, (Range1d, DataRange1d)) for r in [x_range, y_range]): l, b, r, t = self.get_extents(element, ranges) if self.invert_axes: l, b, r, t = b, l, t, r @@ -539,7 +543,7 @@ def _update_ranges(self, element, ranges): def _update_range(self, axis_range, low, high, factors, invert, shared): - if isinstance(axis_range, DataRange1d) and self.apply_ranges: + if isinstance(axis_range, (Range1d, DataRange1d)) and self.apply_ranges: if (low == high and low is not None and not isinstance(high, util.datetime_types)): offset = abs(low*0.1 if low else 0.5) diff --git a/holoviews/plotting/bokeh/util.py b/holoviews/plotting/bokeh/util.py index f0c1025733..3e0b9dbab8 100644 --- a/holoviews/plotting/bokeh/util.py +++ b/holoviews/plotting/bokeh/util.py @@ -55,10 +55,9 @@ IGNORED_ATTRIBUTES = ['data', 'palette', 'image', 'x', 'y', 'factors'] # Model priority order to ensure some types are updated before others -MODEL_PRIORITY = ['DataRange1d', 'Title', 'Image', 'LinearColorMapper', - 'Plot', 'Range1d', 'FactorRange', 'CategoricalAxis', - 'LinearAxis', 'ColumnDataSource'] - +MODEL_PRIORITY = ['DataRange1d', 'Range1d', 'Title', 'Image', 'LinearColorMapper', + 'Plot', 'FactorRange', 'CategoricalAxis', 'LinearAxis', + 'ColumnDataSource'] def rgba_tuple(rgba):