Enable/disable hover_fill_alpha on multi_polygons

Hello,

i have a code where i plot a large amount of polygons using the multi_polygons glyph. If i use the hover_fill_alpha parameter, things get laggy as the whole glyph gets redrawn everythime the mouse goes to another polygon, which is acceptable. I would like to be able to enable/disable this feature.

I first thought of having two glyphs, one with it, and one without the alpha.

The glyph without the alpha runs smooth on its own, but if it has a glyph with the alpha, even though it is hidden, things are laggy. Is there a way to disable those computation when a the glyph is hidden? How would you do it?

from bokeh.plotting import figure
from bokeh.models import (
    HoverTool,
    ColumnDataSource,
)
import panel as pn


def get_shapes():
    shapes_list = []
    colors_list = []

    count_x = 230

    for i in range(count_x):
        for j in range(count_x):
            shapes_list.append(([i, i + 1, i + 1, i], [j, j, j + 1, j + 1]))
            colors_list.append(
                (
                    int(255 * i / count_x),
                    int(255 * j / count_x),
                    int(255 * i / count_x),
                    255,
                )
            )

    return shapes_list, colors_list


coords, colors = get_shapes()
xs = [c[0] for c in coords]
ys = [c[1] for c in coords]

edge_colors = [(c[0] * 0.9, c[1] * 0.9, c[2] * 0.9, c[3]) for c in colors]

TOOLTIPS = [
    ("Volume ID", "@volume_name"),
]

display_as_polygons = True

MyHover = HoverTool(tooltips=TOOLTIPS)
xs_dict = [[{"exterior": e, "holes": []}] for e in xs]

ys_dict = [[{"exterior": e, "holes": []}] for e in ys]

xs = [[[p["exterior"], *p["holes"]] for p in mp] for mp in xs_dict]
ys = [[[p["exterior"], *p["holes"]] for p in mp] for mp in ys_dict]

source_polygons = ColumnDataSource(
    {
        "xs": xs,
        "ys": ys,
        "color": colors,
        "edge_color": edge_colors,
        "volume_name": list(range(len(colors))),
    }
)

# Create a new figure with specified tools
p = figure(
    tools="pan,wheel_zoom,box_select,reset",
    width_policy="max",
    height_policy="max",
    match_aspect=True,
)
p.add_tools(MyHover)

p.multi_polygons(
    xs="xs",
    ys="ys",
    line_width=2,
    color="color",
    # hover_fill_alpha=.6,
    # hover_fill_color="edge_color",
    line_color="edge_color",
    source=source_polygons,
)
p.multi_polygons(
    xs="xs",
    ys="ys",
    line_width=2,
    color="color",
    hover_fill_alpha=.6,
    # hover_fill_color="edge_color",
    line_color="edge_color",
    source=source_polygons,
    visible=False
)

p.title.text = "Plot with polygons"

pn.pane.Bokeh(p, sizing_mode="stretch_both").show()

Thanks,
Thibault

This version is super performant for me:

r = p.multi_polygons(
    xs="xs",
    ys="ys",
    line_width=2,
    color="color",
    line_color="edge_color",
    source=source_polygons,
)

r.hover_glyph = None  # explicitly disable a hover glyph entirely

# p.multi_polygons(
#     xs="xs",
#     ys="ys",
#     line_width=2,
#     color="color",
#     hover_fill_alpha=.6,
#     hover_fill_color="edge_color",
#     line_color="edge_color",
#     source=source_polygons,
#     visible=False
# )

But if I uncomment the second block, things slow down. I suppose I might consider that a bug considering the visible=False. Please open a GitHub Issue with full details.

All that said, is this output with quads actually representative of your real use-case? If your actual need is to draw quads you will see better performance with quad or block or one of the other glyphs optiomized for drawing axis-aligned boxes.

I had thought possibly that restricting the hover tool to just the first renderer might help:

MyHover.renderers = [r]

i.e. maybe it was the inspection event that was errantly being responded to regardless of overall visibility, but this did not seem to make a difference. More investigation will be necessary.

As a brute-force workaround, you might try having two separate plots rather than separate glyphs on one plot, and toggling the visibility of the plots themselves.

Hey,

thanks for your answer,

Yes this is exactly my point it works fine without it, i just openned the issue then (Multi_polygons glyph hover alpha still computed when non visible · Issue #14678 · bokeh/bokeh · GitHub).

No the real use case actually uses the polygons eventually with holes too, so the multi_polygons does a good job here :slight_smile:

I tried editing the renderers, but my understanding on the non conclusive result is that the hover alpha feature is working with another hover tool.

I will go on the brute force solution in the mean time indeed

Thibault

1 Like