Hover tool doesn't appear when hovering over a newly created glyph renderer

Bokeh version: 2.2.3

I’ve created a heatmap (with an hover tool) using a data source that misses the data of a specific coordinate (left-bottom corner):

Under the plot, I’ve added a button that adds the missing data by adding a new glyph (I didn’t add the missing data to the existing glyph’s data source).
The issue is that the hover tool isn’t displayed when hovering over the newly created glyph.
I’ve tried to set the renderers property of the hover tool to a list of the two glyph renderers but it doesn’t have any effect. It’s worth mentioning that the structure of the new data source is similar to the initial data source so the hover tool should be able to identify the columns.
This is the code:

from bokeh.models.formatters import FuncTickFormatter
from bokeh.models.mappers import LinearColorMapper
from bokeh.models.ranges import FactorRange
from bokeh.models.sources import ColumnDataSource
from bokeh.models import HoverTool, Button
from bokeh.palettes import RdBu
from bokeh.plotting import figure
from bokeh.transform import transform
from bokeh.io import curdoc
import itertools as it
import numpy as np

factors = [("group1", "factor1"), ("group2", "factor2"), ("group2", "factor3")]
factors_num = len(factors)

# create data source
data = {
    "x": list(it.chain.from_iterable(it.repeat(factor, factors_num) for factor in factors))[1:],
    "y": (factors * factors_num)[1:],
    "value": np.random.uniform(low=-1, high=1, size=8)
}
source = ColumnDataSource(data=data)

# color mapper
mapper = LinearColorMapper(palette=RdBu[11][::-1], low=-1, high=1, nan_color='lightgray')

# add a heatmap plot
plot = figure(
    x_range=FactorRange(*factors),
    y_range=FactorRange(*factors),
    tools="hover",
    tooltips="@value",
    margin=[20, 80] * 2,
)
plot.rect(
    x="x",
    y="y",
    fill_color=transform("value", mapper),
    source=source,
    width=0.98,
    height=0.98,
)

# remove grids
plot.center = []
# format tick labels
plot.below[0].formatter = FuncTickFormatter(code="return tick.toUpperCase()")
# set group padding
plot.x_range.group_padding = 0
plot.y_range.group_padding = 0

# add a button
button = Button(label="Add Coordinate", button_type="success")


# adds another glyph renderer
def callback(event):
    # remove the glyph that was added on the previous call
    if len(plot.renderers) > 1:
        plot.renderers = [plot.renderers[0]]

    factors = [("group1", "factor1")]
    data = {
        "x": factors,
        "y": factors,
        "value": np.random.uniform(low=0.5, high=13.3, size=1)
    }

    source = ColumnDataSource(data=data)
    plot.rect(
        x="x",
        y="y",
        fill_color="black",
        source=source,
        width=0.98,
        height=0.98,
    )
    plot.select_one({"type": HoverTool}).renderers = plot.renderers


# invoke callback on click
button.on_click(callback)

curdoc().add_root(plot)
curdoc().add_root(button)

Hi @roinr,

I tried out your code in a dev branch of 2.3, and the hover showed up:

I dropped down to 2.2.3, then I saw the behavior you describe. So it looks like this will be fixed in 2.3.

Awesome… thanks @carolyn !

1 Like