Hover disappear on dynamicmap of overlay of different type of objects

I have a callback that may return a overlay of one single Image or one single Points. But the hover only exists on the Points not the Image. Here is a minimum example:

from functools import partial
import numpy as np
import holoviews as hv
from holoviews import opts
from holoviews import streams
hv.extension('bokeh')

x = np.arange(10); y= np.arange(10); z= np.arange(10); d = np.arange(10*10).reshape(10,10)

def call_back(x_range,x,y,z,d):
    if x_range is None: x_range = (x[-1], x[0])
    images = []
    if x_range[1] - x_range[0] >5:
        images.append(hv.Image((x,y,d)))
    else:
        images.append(hv.Points((x,y)))
    return hv.Overlay(images)

def plot():
    rangex = streams.RangeX()
    return hv.DynamicMap(partial(call_back,x=x,y=y,z=z,d=d),streams=[rangex,])

plot_ = plot()
plot_.opts(opts.Image(tools=['hover']),
           opts.Points(tools=['hover'])
          )

The hover is only on Points:
dynamic_points_raster
I also notice the dynamicmap only recognize the Points:

print(plot_)
:DynamicMap   []
   :Overlay
      .Points.I :Points   [x,y]

Thanks for sharing the mrve.

This works for me:

from functools import partial
import numpy as np
import holoviews as hv
from holoviews import opts
from holoviews import streams

hv.extension("bokeh")

x = np.arange(10)
y = np.arange(10)
z = np.arange(10)
d = np.arange(10 * 10).reshape(10, 10)


def image_callback(x_range, x, y, z, d):
    if x_range is None:
        x_range = (x[-1], x[0])
    if x_range[1] - x_range[0] > 5:
        return hv.Image((x, y, d)).opts(tools=["hover"])
    else:
        return hv.Image([])


def scatter_callback(x_range, x, y):
    if x_range is None:
        x_range = (x[-1], x[0])
    if not (x_range[1] - x_range[0] > 5):
        return hv.Points((x, y)).opts(tools=["hover"])
    else:
        return hv.Points([])


def plot():
    rangex = streams.RangeX()
    image_dmap = hv.DynamicMap(
        partial(image_callback, x=x, y=y, z=z, d=d),
        streams=[rangex],
    )
    scatter_dmap = hv.DynamicMap(
        partial(scatter_callback, x=x, y=y),
        streams=[rangex],
    )
    return (
        (image_dmap * scatter_dmap)
        .opts("Scatter", tools=["hover"])
        .opts("Image", tools=["hover"])
    )


plot_ = plot()
plot_

Hi @ahuang11 ,

Thanks a lot for your reply, I really appreciate it! Your code fix the disappeared hover. But one new problem introduced (at least at my end). The returned plot_ plots the scatter first, only after I use the zoom tool, it starts to realize it should plot the image. I have no idea why.
dynamic_points_raster

I’d print and inspect the x_range on init.