Does the HoverTool still not work with images?

Hi,
In trying the script below, I’d like the hover tool to show me the x/y image coordinates and the corresponding value within the array. But I can’t seem to get that to work. Browsing at the Bokeh docs, the old versions had a line stating “Hover tool currently does not work with lines, images, or patch type glyphs.” But that is not a statement made in the latest docs (not that I could see, at least). So, has this been fixed, or am I doing something wrong?

Thanks in advance for any insight.

E

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

x, y = np.arange(10), np.arange(10)
arr1 = np.sqrt(x ** 2 + y[:, np.newaxis] ** 2)

hover = HoverTool(
    tooltips=[
        ("(x,y)", "($x, $y)"),
        # ("value", "$arr1[$x, $y]"),
    ]
)

p = figure(x_range=(0, arr1.shape[1] - 1), y_range=(0, arr1.shape[0] - 1), tools=[hover])
p.image(image=[arr1], x=0, y=0, dw=arr1.shape[1] - 1, dh=arr1.shape[0] - 1, palette="Spectral11")
output_file('heatmap.html')
show(p)

The warning is still
there

Warning

  Hover tool does not currently

work with the following glyphs:

  • annulus
  • arc
  • bezier
  • image
  • image_rgba
  • image_url
  • multi_line
  • oval
  • patch
  • quadratic
  • ray
  • segment
  • text
···

http://bokeh.pydata.org/en/latest/docs/reference/models/tools.html#bokeh.models.tools.HoverTool
On 12/2/16 3:14 PM, Eeee wrote:

Hi,
In trying the script below, I’d like the hover tool to show
me the x/y image coordinates and the corresponding value
within the array. But I can’t seem to get that to work.
Browsing at the Bokeh docs, the old
versions
had a line stating " Hover
tool currently does not work with lines, images, or patch
type glyphs. " But that is not a statement made in
the latest docs (not that I could see, at least). So, has
this been fixed, or am I doing something wrong?

Thanks in advance for any insight.

E

import numpy as np
from bokeh.charts import output_file
from bokeh.models import HoverTool
from bokeh.plotting import figure,
show
x, y = np.arange(10), np.arange(10)
arr1 = np.sqrt(x ** 2 + y[:, np.newaxis] ** 2
)
hover = HoverTool(
tooltips        =[
("(x,y)", "($x, $y)"),
        # ("value", "$arr1[$x, $y]"),

]
)
p = figure(x_range=(0, arr1.shape[1] - 1), y_range=(0, arr1.shape[0] - 1), tools=[hover])
p.image(image=[arr1], x=0, y=0, dw=arr1.shape[1] - 1, dh=arr1.shape[0] - 1, palette="Spectral11")
output_file('heatmap.html')
show(p)

  You received this message because you are subscribed to the Google

Groups “Bokeh Discussion - Public” group.

  To unsubscribe from this group and stop receiving emails from it,

send an email to [email protected].

  To post to this group, send email to [email protected].

  To view this discussion on the web visit [https://groups.google.com/a/continuum.io/d/msgid/bokeh/360f0eb2-7c26-4d30-b31a-d7ace10c83df%40continuum.io](https://groups.google.com/a/continuum.io/d/msgid/bokeh/360f0eb2-7c26-4d30-b31a-d7ace10c83df%40continuum.io?utm_medium=email&utm_source=footer).

  For more options, visit [https://groups.google.com/a/continuum.io/d/optout](https://groups.google.com/a/continuum.io/d/optout).


Sarah Bird
Developer, Bokeh

    [
      ![Continuum Analytics](http://docs.continuum.io/_static/img/ContinuumWordmark.png)
    ](http://continuum.io)

Ah-ha - I missed it. Thanks for pointing it out.
Any advice on path forward, i.e. starting from a 2D array like the one the gets generated in my example?

Thanks so much for your quick reply!

E

···

On Friday, December 2, 2016 at 3:00:42 PM UTC-8, Sarah Bird wrote:

      The warning is still

there

The best I can
suggest is to add a series of
rectangles w hich are transparent
p.rect(alpha=0 ,
…) - the hover can th en attach to them. doing it per
pixel may prove to be inefficient. You may need to do one every 10 pi xels or so - sorry to not have a
better answer yet.

···

On 12/2/16 5:38 PM, Elias F. wrote:

Ah-ha - I missed it. Thanks for pointing it out.
Any advice on path forward, i.e. starting from a 2D array
like the one the gets generated in my example?

Thanks so much for your quick reply!

E

      On Friday, December 2, 2016 at 3:00:42 PM UTC-8, Sarah Bird

wrote:

                The warning

is still there

  You received this message because you are subscribed to the Google

Groups “Bokeh Discussion - Public” group.

  To unsubscribe from this group and stop receiving emails from it,

send an email to [email protected].

  To post to this group, send email to [email protected].

  To view this discussion on the web visit [https://groups.google.com/a/continuum.io/d/msgid/bokeh/c7da68a3-85bf-4094-96a0-eb6f8ec0bd05%40continuum.io](https://groups.google.com/a/continuum.io/d/msgid/bokeh/c7da68a3-85bf-4094-96a0-eb6f8ec0bd05%40continuum.io?utm_medium=email&utm_source=footer).

  For more options, visit [https://groups.google.com/a/continuum.io/d/optout](https://groups.google.com/a/continuum.io/d/optout).


Sarah Bird
Developer, Bokeh

    [
      ![Continuum Analytics](http://docs.continuum.io/_static/img/ContinuumWordmark.png)
    ](http://continuum.io)

It can be done with a bit of fiddling and some custom JS - see below. Hope the code comments are clear enough to explain the approach.

Marcus.

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

from bokeh.models import ColumnDataSource
from bokeh.models.callbacks import CustomJS

x, y = np.arange(10), np.arange(10)
arr1 = np.sqrt(x ** 2 + y[:, np.newaxis] ** 2)

Set up the ColumnDataSource. All variables captured as lists so they have the same length (as required by ColumnDataSource)

xp,yp and zp are the variables for the HoverTool readout (initialised to 0)

datasrc = ColumnDataSource(data={‘x’:,‘y’:[y],‘z’:[arr1],‘xp’:[0],‘yp’:[0],‘zp’:[0]})

The JS code finds the indices from the cursor geometry and stores the values needed in xp,yp and zp.

jsCode = ‘’’
var geom = cb_data[‘geometry’];
var data = datasrc.get(‘data’);

var hx = geom.x;
var hy = geom.y;

var x = data[‘x’][0];
var y = data[‘y’][0];
var z = data[‘z’][0];

var dx = x[1] - x[0]
var dy = y[1] - y[0]
var xind = Math.floor((hx + dx/2 - x[0])/dx)
var yind = Math.floor((hy + dy/2 - y[0])/dy)

if ((xind < x.length) && (yind < y.length)) {
data[‘xp’] = [x[xind]];
data[‘yp’] = [y[yind]];
data[‘zp’] = [z[xind][yind]];

datasrc.set(‘data’,data)
datasrc.trigger(‘change’)
}
‘’’

cJS = CustomJS(args = {‘datasrc’:datasrc},code = jsCode)

dx,dy = x[1]-x[0],y[1]-y[0]

p = figure(x_range=(x[0],x[-1]),y_range=(y[0],y[-1]))

Image linked to ColumnDataSource. Set up so that rectangles centered at corresponding axes values (i.e. using dx and dy…)

i = p.image(‘z’,source=datasrc,x=x[0]-dx/2,y=y[0]-dy/2,dw=x[-1]-x[0]+dx,dh=y[-1]-y[0]+dy,palette=“Spectral11”)

Create a transparent rectangle which covers the image, linked to the same ColumnDataSource

r = p.rect(source=datasrc,x=(x[0]+x[-1])/2,y=(y[0]+y[-1])/2,width=x[-1]-x[0]+dx,height=y[-1]-y[0]+dy,fill_alpha=0,line_alpha=0)

Now the ColumnDataSource data dictionary can be accessed for the HoverTool readout

hover = HoverTool(tooltips=[(‘x,y,z:’,‘@xp{0},@yp{0},@zp{0.00}’)],callback = cJS)
p.add_tools(hover)

output_file(‘heatmap.html’)
show(p)

···

On Friday, December 2, 2016 at 11:38:20 PM UTC, Elias F. wrote:

Ah-ha - I missed it. Thanks for pointing it out.
Any advice on path forward, i.e. starting from a 2D array like the one the gets generated in my example?

Thanks so much for your quick reply!

E

On Friday, December 2, 2016 at 3:00:42 PM UTC-8, Sarah Bird wrote:

      The warning is still

there

Marcus - thank you, this is perfect! I didn’t know you can inject custom JS. I need to read that section of the docs. Appreciate the working example!

···

On Tuesday, December 6, 2016 at 6:50:08 AM UTC-8, Marcus Donnelly wrote:

It can be done with a bit of fiddling and some custom JS - see below. Hope the code comments are clear enough to explain the approach.

Marcus.

No problem, glad to help! It’s worth checking out the custom JS as it’s quite powerful.

···

On Thursday, December 8, 2016 at 11:22:07 PM UTC, Elias F. wrote:

Marcus - thank you, this is perfect! I didn’t know you can inject custom JS. I need to read that section of the docs. Appreciate the working example!

On Tuesday, December 6, 2016 at 6:50:08 AM UTC-8, Marcus Donnelly wrote:

It can be done with a bit of fiddling and some custom JS - see below. Hope the code comments are clear enough to explain the approach.

Marcus.