How to get the values at the pixels of a bokeh image glyph in hover tool?

250 Views Asked by At

I have generated a bokeh 2d-histogram plot as mentioned in this StackOverflow answer. The code and respective image is given below. In the code, the count of data-points per bin is in the entries in H. How can I get access to an individual pixel-index to get the value at respective index in H and show it in the hover-text? I want to show count: 2 in the hover-text below x and y values, say. I tried using image_index mentioned here; probably new in Bokeh 3.0.1 but not sure how it works.

Note: It would be better to get an answer compatible with Bokeh 2.4.3 due to legacy code issues. Including holoviews tag as I know their outputs can be rendered as bokeh figure.

import numpy as np
from bokeh.plotting import figure, show
from bokeh.palettes import Turbo256
from bokeh.models import ColorBar, LinearColorMapper

a = np.array([1, 1.5, 2, 3, 4, 5])
b = np.array([15, 16, 20, 35, 45, 50])
H, xe, ye = np.histogram2d(a, b, bins=5)

data=dict(
    image=[H],
    x=[xe[0]],
    y=[ye[0]],
    dw=[xe[-1]-xe[0]],
    dh=[ye[-1]-ye[0]]
)

TOOLTIPS = [
    ("x", "$x"),
    ("y", "$y"),
#     ("image_index", "$image_index"),
]

p = figure(x_range=(min(xe),max(xe)), y_range=(min(ye),max(ye)), tools="pan,reset,hover", tooltips=TOOLTIPS)

color_map = LinearColorMapper(palette=Turbo256, low=1, high=H.max(), low_color='white')
color_bar = ColorBar(color_mapper=color_map, label_standoff=12)

p.image(source=data,image='image',x='x',y='y',dw='dw',dh='dh',color_mapper=color_map,)

p.add_layout(color_bar, 'right')

show(p)

enter image description here

1

There are 1 best solutions below

2
On BEST ANSWER

I don't know the raw Bokeh code to do this, but in HoloViews it's:

import numpy as np, holoviews as hv
hv.extension('bokeh')

a = np.array([1, 1.5, 2, 3, 4, 5])
b = np.array([15, 16, 20, 35, 45, 50])
H, xe, ye = np.histogram2d(a, b, bins=5)

img = hv.Image(H[::-1], bounds=(-1,-1,1,1), vdims=['image_index'])

img.opts(tools=['hover'], width=500, cmap="Turbo", colorbar=True, 
         clim=(1,None), clipping_colors={'min': 'white'})

Screenshot