# Buggy code
def range(cls, columns, dimension):
    column = columns.data[columns.get_dimension(dimension).name]
    if column.dtype.kind == "O":
        column = np.sort(column[column.notnull()].compute())
        return column[0], column[-1]
    else:
        return dd.compute(column.min(), column.max())


# Traceback (IndexError)
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
~/dev/jungle/jungle/lib/python3.6/site-packages/ipython-6.3.1-py3.6.egg/IPython/core/formatters.py in __call__(self, obj, include, exclude)
968
969             if method is not None:
--> 970                 return method(include=include, exclude=exclude)
971             return None
972         else:

~/dev/jungle/jungle/lib/python3.6/site-packages/holoviews-1.11.0a1.post3+g103daf59-py3.6.egg/holoviews/core/dimension.py in _repr_mimebundle_(self, include, exclude)
1263         combined and returned.
1264         """
-> 1265         return Store.render(self)
1266
1267

~/dev/jungle/jungle/lib/python3.6/site-packages/holoviews-1.11.0a1.post3+g103daf59-py3.6.egg/holoviews/core/options.py in render(cls, obj)
1287         data, metadata = {}, {}
1288         for hook in hooks:
-> 1289             ret = hook(obj)
1290             if ret is None:
1291                 continue

~/dev/jungle/jungle/lib/python3.6/site-packages/holoviews-1.11.0a1.post3+g103daf59-py3.6.egg/holoviews/ipython/display_hooks.py in pprint_display(obj)
270     if not ip.display_formatter.formatters['text/plain'].pprint:
271         return None
--> 272     return display(obj, raw_output=True)
273
274

~/dev/jungle/jungle/lib/python3.6/site-packages/holoviews-1.11.0a1.post3+g103daf59-py3.6.egg/holoviews/ipython/display_hooks.py in display(obj, raw_output, **kwargs)
240     elif isinstance(obj, (CompositeOverlay, ViewableElement)):
241         with option_state(obj):
--> 242             output = element_display(obj)
243     elif isinstance(obj, (Layout, NdLayout, AdjointLayout)):
244         with option_state(obj):

~/dev/jungle/jungle/lib/python3.6/site-packages/holoviews-1.11.0a1.post3+g103daf59-py3.6.egg/holoviews/ipython/display_hooks.py in wrapped(element)
140         try:
141             max_frames = OutputSettings.options['max_frames']
--> 142             mimebundle = fn(element, max_frames=max_frames)
143             if mimebundle is None:
144                 return {}, {}

~/dev/jungle/jungle/lib/python3.6/site-packages/holoviews-1.11.0a1.post3+g103daf59-py3.6.egg/holoviews/ipython/display_hooks.py in element_display(element, max_frames)
186         return None
187
--> 188     return render(element)
189
190

~/dev/jungle/jungle/lib/python3.6/site-packages/holoviews-1.11.0a1.post3+g103daf59-py3.6.egg/holoviews/ipython/display_hooks.py in render(obj, **kwargs)
63         renderer = renderer.instance(fig='png')
64
---> 65     return renderer.components(obj, **kwargs)
66
67

~/dev/jungle/jungle/lib/python3.6/site-packages/holoviews-1.11.0a1.post3+g103daf59-py3.6.egg/holoviews/plotting/bokeh/renderer.py in components(self, obj, fmt, comm, **kwargs)
268         # Bokeh has to handle comms directly in <0.12.15
269         comm = False if bokeh_version < '0.12.15' else comm
--> 270         return super(BokehRenderer, self).components(obj,fmt, comm, **kwargs)
271
272

~/dev/jungle/jungle/lib/python3.6/site-packages/holoviews-1.11.0a1.post3+g103daf59-py3.6.egg/holoviews/plotting/renderer.py in components(self, obj, fmt, comm, **kwargs)
327             plot = obj
328         else:
--> 329             plot, fmt = self._validate(obj, fmt)
330
331         widget_id = None

~/dev/jungle/jungle/lib/python3.6/site-packages/holoviews-1.11.0a1.post3+g103daf59-py3.6.egg/holoviews/plotting/renderer.py in _validate(self, obj, fmt, **kwargs)
226         if isinstance(obj, tuple(self.widgets.values())):
227             return obj, 'html'
--> 228         plot = self.get_plot(obj, renderer=self, **kwargs)
229
230         fig_formats = self.mode_formats['fig'][self.mode]

~/dev/jungle/jungle/lib/python3.6/site-packages/holoviews-1.11.0a1.post3+g103daf59-py3.6.egg/holoviews/plotting/bokeh/renderer.py in get_plot(self_or_cls, obj, doc, renderer)
153             curdoc().theme = self_or_cls.theme
154         doc.theme = self_or_cls.theme
--> 155         plot = super(BokehRenderer, self_or_cls).get_plot(obj, renderer)
156         plot.document = doc
157         return plot

~/dev/jungle/jungle/lib/python3.6/site-packages/holoviews-1.11.0a1.post3+g103daf59-py3.6.egg/holoviews/plotting/renderer.py in get_plot(self_or_cls, obj, renderer)
209             plot_opts = self_or_cls.plot_options(obj, self_or_cls.size)
210             plot = self_or_cls.plotting_class(obj)(obj, renderer=renderer,
--> 211                                                    **plot_opts)
212             defaults = [kd.default for kd in plot.dimensions]
213             init_key = tuple(v if d is None else d for v, d in

~/dev/jungle/jungle/lib/python3.6/site-packages/holoviews-1.11.0a1.post3+g103daf59-py3.6.egg/holoviews/plotting/plot.py in __init__(self, overlay, ranges, batched, keys, group_counter, **params)
885
886         # Apply data collapse
--> 887         self.hmap = self._apply_compositor(self.hmap, ranges, self.keys)
888         self.map_lengths = Counter()
889         self.group_counter = Counter() if group_counter is None else group_counter

~/dev/jungle/jungle/lib/python3.6/site-packages/holoviews-1.11.0a1.post3+g103daf59-py3.6.egg/holoviews/plotting/plot.py in _apply_compositor(self, holomap, ranges, keys, dimensions)
914                                         for key, slckey in zip(keys, sliced_keys) if slckey in holomap.data.keys()])
915         else:
--> 916             mapwise_ranges = self.compute_ranges(holomap, None, None)
917             frame_ranges = OrderedDict([(key, self.compute_ranges(holomap, key, mapwise_ranges))
918                                         for key in holomap.data.keys()])

~/dev/jungle/jungle/lib/python3.6/site-packages/holoviews-1.11.0a1.post3+g103daf59-py3.6.egg/holoviews/plotting/plot.py in compute_ranges(self, obj, key, ranges)
378             if (not (axiswise and not isinstance(obj, HoloMap)) or
379                 (not framewise and isinstance(obj, HoloMap))):
--> 380                 self._compute_group_range(group, elements, ranges)
381         self.ranges.update(ranges)
382         return ranges

~/dev/jungle/jungle/lib/python3.6/site-packages/holoviews-1.11.0a1.post3+g103daf59-py3.6.egg/holoviews/plotting/plot.py in _compute_group_range(group, elements, ranges)
438             if isinstance(el, (Empty, Table)): continue
439             for dim in el.dimensions('ranges', label=True):
--> 440                 dim_range = el.range(dim)
441                 if dim not in group_ranges:
442                     group_ranges[dim] = []

~/dev/jungle/jungle/lib/python3.6/site-packages/holoviews-1.11.0a1.post3+g103daf59-py3.6.egg/holoviews/core/data/__init__.py in range(self, dim, data_range)
287             return dim.range
288         elif dim in self.dimensions() and data_range and len(self):
--> 289             lower, upper = self.interface.range(self, dim)
290         else:
291             lower, upper = (np.NaN, np.NaN)

~/dev/jungle/jungle/lib/python3.6/site-packages/holoviews-1.11.0a1.post3+g103daf59-py3.6.egg/holoviews/core/data/dask.py in range(cls, columns, dimension)
68         if column.dtype.kind == 'O':
69             column = np.sort(column[column.notnull()].compute())
---> 70             return column[0], column[-1]
71         else:
72             return dd.compute(column.min(), column.max())

IndexError: index 0 is out of bounds for axis 0 with size 0

# Fixed code
def range(cls, columns, dimension):
    column = columns.data[columns.get_dimension(dimension).name]
    if column.dtype.kind == "O":
        column = np.sort(column[column.notnull()].compute())
        return (column[0], column[-1]) if len(column) else (None, None)
    else:
        return dd.compute(column.min(), column.max())