Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Custom hover tooltip on image plot shows all the image data. #14054

Open
mixstam1821 opened this issue Sep 7, 2024 · 2 comments
Open

Comments

@mixstam1821
Copy link

mixstam1821 commented Sep 7, 2024

Software versions

Python version 3.11.4| Bokeh version 3.5.2

Browser name and version

No response

Jupyter notebook / Jupyter Lab version

No response

Expected behavior

When I hover over an image plot (heatmap) using custom tooltip, I expect to get a tooltip like that I get with the code below (without custom tooltip):

import numpy as np
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource,HoverTool

x = np.linspace(0, 10, 300)
y = np.linspace(0, 10, 300)
xx, yy = np.meshgrid(x, y)
d = np.sin(xx) * np.cos(yy)

s1 = ColumnDataSource(data=dict(x=[xx], y=[yy], image=[d]))
p = figure(width=400, height=400)
p.x_range.range_padding = p.y_range.range_padding = 0
p.image(image='image',source=s1, x=0, y=0, dw=10, dh=10, palette="Sunset11", level="image")
hover = HoverTool(tooltips=[
    ("index", "$index"),
    ("(x,y)", "($x, $y)"),
    ("Temperature", "@image"),],
    mode='mouse',)
p.add_tools(hover)
show(p)

Screenshot_20240907_042606

Observed behavior

However, the custom tooltip for @image shows all the data instead of a specific number. The code with the custom tooltip is below.
Screenshot_20240907_042305

Example code

import numpy as np
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource,HoverTool

x = np.linspace(0, 10, 300)
y = np.linspace(0, 10, 300)
xx, yy = np.meshgrid(x, y)
d = np.sin(xx) * np.cos(yy)

s1 = ColumnDataSource(data=dict(x=[xx], y=[yy], image=[d]))
p = figure(width=400, height=400)
p.x_range.range_padding = p.y_range.range_padding = 0
p.image(image='image',source=s1, x=0, y=0, dw=10, dh=10, palette="Sunset11", level="image")
p.add_tools(HoverTool(tooltips="""<div style="background-color: #f0f0f0; padding: 5px; border-radius: 5px; box-shadow: 0px 0px 5px rgba(0,0,0,0.3);">        <font size="5" style="background-color: #f0f0f0; padding: 5px; border-radius: 5px;">
            <i>x:</i> <b>$x</b> <br> 
            <i>y:</i> <b>$y</b> <br>
            <i>image:</i> <b>@image</b> <br>
        </font> </div> <style> :host { --tooltip-border: transparent;  /* Same border color used everywhere */ --tooltip-color: transparent; --tooltip-text: #2f2f2f;} </style> """,
    ))
show(p)

Stack traceback or browser console output

The issue reported initially here: https://discourse.bokeh.org/t/custom-hover-tooltip-over-image-plot-not-work-as-expected/11802.

I would appreciate it if you could give me any idea how to increase the font size of the default tooltip.

Screenshots

No response

@bryevdv bryevdv added this to the 3.6 milestone Sep 7, 2024
@bryevdv bryevdv self-assigned this Sep 7, 2024
@bryevdv
Copy link
Member

bryevdv commented Sep 16, 2024

I would appreciate it if you could give me any idea how to increase the font size of the default tooltip.

@mattpap can you comment on this? I don't see offhand how to apply custom CSS styles to the built-in hovertool tooltip.

@bryevdv
Copy link
Member

bryevdv commented Sep 16, 2024

This diff, which just copies the check from _render_template, fixes:

diff --git a/bokehjs/src/lib/models/tools/inspectors/hover_tool.ts b/bokehjs/src/lib/models/tools/inspectors/hover_tool.ts
index d8b404a5ad..bc8a9221d1 100644
--- a/bokehjs/src/lib/models/tools/inspectors/hover_tool.ts
+++ b/bokehjs/src/lib/models/tools/inspectors/hover_tool.ts
@@ -618,6 +618,8 @@ export class HoverToolView extends InspectToolView {
     const i = vars.index

     if (isString(tooltips)) {
+      // if we have an image_index, that is what replace_placeholders needs
+      const i = is_undefined(vars.image_index) ? vars.index : vars.image_index
       const content = replace_placeholders({html: tooltips}, ds, i, this.model.formatters, vars)
       return div(content)
     } else if (isFunction(tooltips)) {
Screenshot 2024-09-16 at 13 07 51

I think this is probably fine and appropriate (though I have not given it too much thought) but I will try to see about consolidating these codepaths to avoid this duplication in multiple places.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants