# Buggy code
def _merge_tools(self, subplot):
    """
    Merges tools on the overlay with those on the subplots.
    """
    if self.batched and "hover" in subplot.handles:
        self.handles["hover"] = subplot.handles["hover"]
    elif "hover" in subplot.handles and "hover_tools" in self.handles:
        hover = subplot.handles["hover"]
        # Datetime formatter may have been applied, remove _dt_strings
        # to match on the hover tooltips, then merge tool renderers
        if hover.tooltips:
            tooltips = tuple(
                (name, spec.replace("_dt_strings", "")) for name, spec in hover.tooltips
            )
        else:
            tooltips = ()
        tool = self.handles["hover_tools"].get(tooltips)
        if tool:
            tool_renderers = [] if tool.renderers == "auto" else tool.renderers
            hover_renderers = [] if hover.renderers == "auto" else hover.renderers
            renderers = tool_renderers + hover_renderers
            tool.renderers = list(util.unique_iterator(renderers))
        if "hover" not in self.handles:
            self.handles["hover"] = tool


# Traceback (ValueError)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/Users/volkerhilsenstein/anaconda3/lib/python3.6/site-packages/IPython/core/formatters.py in __call__(self, obj, include, exclude)
968                 d['include'] = include
969                 d['exclude'] = exclude
--> 970                 return method(**d)
971             return None
972         else:

/Users/volkerhilsenstein/anaconda3/lib/python3.6/site-packages/holoviews/core/dimension.py in _repr_mimebundle_(self, include, exclude)
1226         combined and returned.
1227         """
-> 1228         return Store.render(self)
1229
1230

/Users/volkerhilsenstein/anaconda3/lib/python3.6/site-packages/holoviews/core/options.py in render(cls, obj)
1287         data, metadata = {}, {}
1288         for hook in hooks:
-> 1289             d, md = hook(obj)
1290             data.update(d)
1291             metadata.update(md)

/Users/volkerhilsenstein/anaconda3/lib/python3.6/site-packages/holoviews/ipython/display_hooks.py in pprint_display(obj)
276     if not ip.display_formatter.formatters['text/plain'].pprint:
277         return None
--> 278     return display(obj, raw=True)
279
280

/Users/volkerhilsenstein/anaconda3/lib/python3.6/site-packages/holoviews/ipython/display_hooks.py in display(obj, raw, **kwargs)
253     elif isinstance(obj, (HoloMap, DynamicMap)):
254         with option_state(obj):
--> 255             output = map_display(obj)
256     elif isinstance(obj, Plot):
257         output = render(obj)

/Users/volkerhilsenstein/anaconda3/lib/python3.6/site-packages/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 {}, {}

/Users/volkerhilsenstein/anaconda3/lib/python3.6/site-packages/holoviews/ipython/display_hooks.py in map_display(vmap, max_frames)
208         return None
209
--> 210     return render(vmap)
211
212

/Users/volkerhilsenstein/anaconda3/lib/python3.6/site-packages/holoviews/ipython/display_hooks.py in render(obj, **kwargs)
63         renderer = renderer.instance(fig='png')
64
---> 65     return renderer.components(obj, **kwargs)
66
67

/Users/volkerhilsenstein/anaconda3/lib/python3.6/site-packages/holoviews/plotting/bokeh/renderer.py in components(self, obj, fmt, comm, **kwargs)
248         # Bokeh has to handle comms directly in <0.12.15
249         comm = False if bokeh_version < '0.12.15' else comm
--> 250         return super(BokehRenderer, self).components(obj,fmt, comm, **kwargs)
251
252

/Users/volkerhilsenstein/anaconda3/lib/python3.6/site-packages/holoviews/plotting/renderer.py in components(self, obj, fmt, comm, **kwargs)
319             plot = obj
320         else:
--> 321             plot, fmt = self._validate(obj, fmt)
322
323         widget_id = None

/Users/volkerhilsenstein/anaconda3/lib/python3.6/site-packages/holoviews/plotting/renderer.py in _validate(self, obj, fmt, **kwargs)
218         if isinstance(obj, tuple(self.widgets.values())):
219             return obj, 'html'
--> 220         plot = self.get_plot(obj, renderer=self, **kwargs)
221
222         fig_formats = self.mode_formats['fig'][self.mode]

/Users/volkerhilsenstein/anaconda3/lib/python3.6/site-packages/holoviews/plotting/bokeh/renderer.py in get_plot(self_or_cls, obj, doc, renderer)
149             doc = Document() if self_or_cls.notebook_context else curdoc()
150         doc.theme = self_or_cls.theme
--> 151         plot = super(BokehRenderer, self_or_cls).get_plot(obj, renderer)
152         plot.document = doc
153         return plot

/Users/volkerhilsenstein/anaconda3/lib/python3.6/site-packages/holoviews/plotting/renderer.py in get_plot(self_or_cls, obj, renderer)
205             init_key = tuple(v if d is None else d for v, d in
206                              zip(plot.keys[0], defaults))
--> 207             plot.update(init_key)
208         else:
209             plot = obj

/Users/volkerhilsenstein/anaconda3/lib/python3.6/site-packages/holoviews/plotting/plot.py in update(self, key)
507         if len(self) == 1 and ((key == 0) or (key == self.keys[0])) and not self.drawn:
508             return self.initialize_plot()
--> 509         item = self.__getitem__(key)
510         self.traverse(lambda x: setattr(x, '_updated', True))
511         return item

/Users/volkerhilsenstein/anaconda3/lib/python3.6/site-packages/holoviews/plotting/plot.py in __getitem__(self, frame)
242         if isinstance(frame, int) and frame > len(self):
243             self.warning("Showing last frame available: %d" % len(self))
--> 244         if not self.drawn: self.handles['fig'] = self.initialize_plot()
245         if not isinstance(frame, tuple):
246             frame = self.keys[frame]

/Users/volkerhilsenstein/anaconda3/lib/python3.6/site-packages/holoviews/plotting/bokeh/element.py in initialize_plot(self, ranges, plot, plots)
1396                     title = get_tab_title(key, frame, self.hmap.last)
1397                 panels.append(Panel(child=child, title=title))
-> 1398             self._merge_tools(subplot)
1399
1400         if self.tabs:

/Users/volkerhilsenstein/anaconda3/lib/python3.6/site-packages/holoviews/plotting/bokeh/element.py in _merge_tools(self, subplot)
1339             if hover.tooltips:
1340                 tooltips = tuple((name, spec.replace('_dt_strings', ''))
-> 1341                                   for name, spec in hover.tooltips)
1342             else:
1343                 tooltips = ()

/Users/volkerhilsenstein/anaconda3/lib/python3.6/site-packages/holoviews/plotting/bokeh/element.py in <genexpr>(.0)
1339             if hover.tooltips:
1340                 tooltips = tuple((name, spec.replace('_dt_strings', ''))
-> 1341                                   for name, spec in hover.tooltips)
1342             else:
1343                 tooltips = ()

ValueError: not enough values to unpack (expected 2, got 1)

:DynamicMap   [Platename,Column,cmap,lower_percentile,upper_percentile]
:Overlay
.HeatMap.I :HeatMap   [col,row]   (value1,giffile,value2,Platename,well)
.Labels.I  :Labels   [col,row]   (well)

# Fixed code
def _merge_tools(self, subplot):
    """
    Merges tools on the overlay with those on the subplots.
    """
    if self.batched and "hover" in subplot.handles:
        self.handles["hover"] = subplot.handles["hover"]
    elif "hover" in subplot.handles and "hover_tools" in self.handles:
        hover = subplot.handles["hover"]
        # Datetime formatter may have been applied, remove _dt_strings
        # to match on the hover tooltips, then merge tool renderers
        if hover.tooltips and not isinstance(hover.tooltips, util.basestring):
            tooltips = tuple(
                (name, spec.replace("_dt_strings", "")) for name, spec in hover.tooltips
            )
        else:
            tooltips = ()
        tool = self.handles["hover_tools"].get(tooltips)
        if tool:
            tool_renderers = [] if tool.renderers == "auto" else tool.renderers
            hover_renderers = [] if hover.renderers == "auto" else hover.renderers
            renderers = tool_renderers + hover_renderers
            tool.renderers = list(util.unique_iterator(renderers))
        if "hover" not in self.handles:
            self.handles["hover"] = tool