# Buggy code
def ensure_ring(geom, values=None):
    """Ensure the (multi-)geometry forms a ring.

    Checks the start- and end-point of each geometry to ensure they
    form a ring, if not the start point is inserted at the end point.
    If a values array is provided (which must match the geometry in
    length) then the insertion will occur on the values instead,
    ensuring that they will match the ring geometry.

    Args:
        geom: 2-D array of geometry coordinates
        values: Optional array of values

    Returns:
        Array where values have been inserted and ring closing indexes
    """
    if values is None:
        values = geom
    breaks = np.where(np.isnan(geom).sum(axis=1))[0]
    starts = [0] + list(breaks + 1)
    ends = list(breaks - 1) + [len(geom) - 1]
    zipped = zip(geom[starts], geom[ends], ends, values[starts])
    unpacked = tuple(zip(*[(v, i + 1) for s, e, i, v in zipped if (s != e).any()]))
    if not unpacked:
        return values
    inserts, inds = unpacked
    return np.insert(values, list(inds), list(inserts), axis=0)


# Traceback (TypeError)
TypeError                                 Traceback (most recent call last)
~/.local/lib/python3.6/site-packages/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:

~/.local/lib/python3.6/site-packages/holoviews/core/dimension.py in _repr_mimebundle_(self, include, exclude)
1302         combined and returned.
1303         """
-> 1304         return Store.render(self)
1305
1306

~/.local/lib/python3.6/site-packages/holoviews/core/options.py in render(cls, obj)
1393         data, metadata = {}, {}
1394         for hook in hooks:
-> 1395             ret = hook(obj)
1396             if ret is None:
1397                 continue

~/.local/lib/python3.6/site-packages/holoviews/ipython/display_hooks.py in pprint_display(obj)
280     if not ip.display_formatter.formatters['text/plain'].pprint:
281         return None
--> 282     return display(obj, raw_output=True)
283
284

~/.local/lib/python3.6/site-packages/holoviews/ipython/display_hooks.py in display(obj, raw_output, **kwargs)
250     elif isinstance(obj, (CompositeOverlay, ViewableElement)):
251         with option_state(obj):
--> 252             output = element_display(obj)
253     elif isinstance(obj, (Layout, NdLayout, AdjointLayout)):
254         with option_state(obj):

~/.local/lib/python3.6/site-packages/holoviews/ipython/display_hooks.py in wrapped(element)
144         try:
145             max_frames = OutputSettings.options['max_frames']
--> 146             mimebundle = fn(element, max_frames=max_frames)
147             if mimebundle is None:
148                 return {}, {}

~/.local/lib/python3.6/site-packages/holoviews/ipython/display_hooks.py in element_display(element, max_frames)
190         return None
191
--> 192     return render(element)
193
194

~/.local/lib/python3.6/site-packages/holoviews/ipython/display_hooks.py in render(obj, **kwargs)
66         renderer = renderer.instance(fig='png')
67
---> 68     return renderer.components(obj, **kwargs)
69
70

~/.local/lib/python3.6/site-packages/holoviews/plotting/renderer.py in components(self, obj, fmt, comm, **kwargs)
374             doc = Document()
375             with config.set(embed=embed):
--> 376                 model = plot.layout._render_model(doc, comm)
377             if embed:
378                 return render_model(model, comm)

~/.local/lib/python3.6/site-packages/panel/viewable.py in _render_model(self, doc, comm)
415         if comm is None:
416             comm = state._comm_manager.get_server_comm()
--> 417         model = self.get_root(doc, comm)
418
419         if config.embed:

~/.local/lib/python3.6/site-packages/panel/viewable.py in get_root(self, doc, comm)
640         """
641         doc = doc or _curdoc()
--> 642         root = self._get_model(doc, comm=comm)
643         self._preprocess(root)
644         ref = root.ref['id']

~/.local/lib/python3.6/site-packages/panel/layout.py in _get_model(self, doc, root, parent, comm)
118         if root is None:
119             root = model
--> 120         objects = self._get_objects(model, [], doc, root, comm)
121         props = dict(self._init_properties(), objects=objects)
122         model.update(**self._process_param_change(props))

~/.local/lib/python3.6/site-packages/panel/layout.py in _get_objects(self, model, old_objects, doc, root, comm)
108             else:
109                 try:
--> 110                     child = pane._get_model(doc, root, model, comm)
111                 except RerenderError:
112                     return self._get_objects(model, current_objects[:i], doc, root, comm)

~/.local/lib/python3.6/site-packages/panel/pane/holoviews.py in _get_model(self, doc, root, parent, comm)
225             plot = self.object
226         else:
--> 227             plot = self._render(doc, comm, root)
228
229         plot.pane = self

~/.local/lib/python3.6/site-packages/panel/pane/holoviews.py in _render(self, doc, comm, root)
284             kwargs = {}
285
--> 286         return renderer.get_plot(self.object, **kwargs)
287
288     def _cleanup(self, root):

~/.local/lib/python3.6/site-packages/holoviews/plotting/bokeh/renderer.py in get_plot(self_or_cls, obj, doc, renderer, **kwargs)
71         combining the bokeh model with another plot.
72         """
---> 73         plot = super(BokehRenderer, self_or_cls).get_plot(obj, doc, renderer, **kwargs)
74         if plot.document is None:
75             plot.document = Document() if self_or_cls.notebook_context else curdoc()

~/.local/lib/python3.6/site-packages/holoviews/plotting/renderer.py in get_plot(self_or_cls, obj, doc, renderer, comm, **kwargs)
230             init_key = tuple(v if d is None else d for v, d in
231                              zip(plot.keys[0], defaults))
--> 232             plot.update(init_key)
233         else:
234             plot = obj

~/.local/lib/python3.6/site-packages/holoviews/plotting/plot.py in update(self, key)
876     def update(self, key):
877         if len(self) == 1 and ((key == 0) or (key == self.keys[0])) and not self.drawn:
--> 878             return self.initialize_plot()
879         item = self.__getitem__(key)
880         self.traverse(lambda x: setattr(x, '_updated', True))

~/.local/lib/python3.6/site-packages/holoviews/plotting/bokeh/element.py in initialize_plot(self, ranges, plot, plots, source)
1315         self.handles['plot'] = plot
1316
-> 1317         self._init_glyphs(plot, element, ranges, source)
1318         if not self.overlaid:
1319             self._update_plot(key, plot, style_element)

~/.local/lib/python3.6/site-packages/holoviews/plotting/bokeh/element.py in _init_glyphs(self, plot, element, ranges, source)
1262         else:
1263             style = self.style[self.cyclic_index]
-> 1264             data, mapping, style = self.get_data(element, ranges, style)
1265             current_id = element._plot_id
1266

~/.local/lib/python3.6/site-packages/holoviews/plotting/bokeh/path.py in get_data(self, element, ranges, style)
225         else:
226             if has_holes:
--> 227                 xs, ys = multi_polygons_data(element)
228             else:
229                 xs, ys = (list(element.dimension_values(kd, expanded=False))

~/.local/lib/python3.6/site-packages/holoviews/plotting/bokeh/util.py in multi_polygons_data(element)
902     correct list of holes is assigned to each sub-polygon.
903     """
--> 904     xs, ys = (element.dimension_values(kd, expanded=False) for kd in element.kdims)
905     holes = element.holes()
906     xsh, ysh = [], []

~/.local/lib/python3.6/site-packages/holoviews/plotting/bokeh/util.py in <genexpr>(.0)
902     correct list of holes is assigned to each sub-polygon.
903     """
--> 904     xs, ys = (element.dimension_values(kd, expanded=False) for kd in element.kdims)
905     holes = element.holes()
906     xsh, ysh = [], []

~/.local/lib/python3.6/site-packages/holoviews/core/data/__init__.py in pipelined_fn(*args, **kwargs)
212
213             try:
--> 214                 result = method_fn(*args, **kwargs)
215
216                 op = method_op.instance(

~/.local/lib/python3.6/site-packages/holoviews/element/path.py in dimension_values(self, dim, expanded, flat)
279                 return np.full(len(self), self.level)
280             return np.array([self.level])
--> 281         return super(Contours, self).dimension_values(dim, expanded, flat)
282
283

~/.local/lib/python3.6/site-packages/holoviews/core/data/__init__.py in pipelined_fn(*args, **kwargs)
212
213             try:
--> 214                 result = method_fn(*args, **kwargs)
215
216                 op = method_op.instance(

~/.local/lib/python3.6/site-packages/holoviews/core/data/__init__.py in dimension_values(self, dimension, expanded, flat)
1046         """
1047         dim = self.get_dimension(dimension, strict=True)
-> 1048         return self.interface.values(self, dim, expanded, flat)
1049
1050

~/.local/lib/python3.6/site-packages/holoviews/core/data/multipath.py in values(cls, dataset, dimension, expanded, flat, compute, keep_index)
402                 not geom_type == 'Points'):
403                 gvals = ds.array([0, 1])
--> 404                 dvals = ensure_ring(gvals, dvals)
405             if scalar and not expanded:
406                 dvals = dvals[:1]

~/.local/lib/python3.6/site-packages/holoviews/core/data/multipath.py in ensure_ring(geom, values)
552     if values is None:
553         values = geom
--> 554     breaks = np.where(np.isnan(geom).sum(axis=1))[0]
555     starts = [0] + list(breaks+1)
556     ends = list(breaks-1) + [len(geom)-1]

TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

# Fixed code
def ensure_ring(geom, values=None):
    """Ensure the (multi-)geometry forms a ring.

    Checks the start- and end-point of each geometry to ensure they
    form a ring, if not the start point is inserted at the end point.
    If a values array is provided (which must match the geometry in
    length) then the insertion will occur on the values instead,
    ensuring that they will match the ring geometry.

    Args:
        geom: 2-D array of geometry coordinates
        values: Optional array of values

    Returns:
        Array where values have been inserted and ring closing indexes
    """
    if values is None:
        values = geom

    breaks = np.where(np.isnan(geom.astype("float")).sum(axis=1))[0]
    starts = [0] + list(breaks + 1)
    ends = list(breaks - 1) + [len(geom) - 1]
    zipped = zip(geom[starts], geom[ends], ends, values[starts])
    unpacked = tuple(zip(*[(v, i + 1) for s, e, i, v in zipped if (s != e).any()]))
    if not unpacked:
        return values
    inserts, inds = unpacked
    return np.insert(values, list(inds), list(inserts), axis=0)