Bokeh: Link Hover tooltips geometrically to subplots

Viewed 1630

I have multiple categorical heatmap plots that are in a single display that have identical shapes and x,y coordinates. When hovering on any of the subplots I would like the inspection on one plot to trigger a new inspection on all other plots in the grid and display multiple tooltips simultaneously.

I have researched this topic and found similar posts such as:

Bokeh: Synchronizing hover tooltips in linked plots

Takeaway from link above: There are 2 suggested answers to this question, which attempt to mimic hover tooltips with text glyphs, however these implementations are not successful when I copy and run the code on my own computer (the graphs display correctly but the hover text glyphs don't appear). I assume this could be because of Bokeh API updates, but I am unsure. My reputation doesn't allow comments or I'd address this issue there.

Coordinate tooltips across multiple plots #1547

Takeaway from link above: There is no reproducible data so I am not able to recreate the plot listed here, however bryevdv summarizes what I am trying to do quite efficiently which I'll quote below:

Link on geometry. You might want the geometry of the inspection on one plot to trigger a completely new inspection (using that same geometry) on another plot. So if the cursor is at (10.5, 7) on one plot, then the additional plots do a hit test at (10.5, 7) and if there are glyphs that have any hovers a that point, then a hover gets drawn there.

I have created some generalized data to illustrate my problem:

from bokeh.io import show, output_notebook
from bokeh.layouts import gridplot
from bokeh.models import LinearColorMapper, HoverTool
from bokeh.plotting import figure, show, output_file
from bokeh.transform import transform

import numpy as np
import pandas as pd

data1 = [['A','A',100], ['A','B',175], ['B','A',75], ['B','B',200]]
data2 = [['A','A',25], ['A','B',100], ['B','A',50], ['B','B',75]]
data3 = [['A','A',150], ['A','B',75], ['B','A',25], ['B','B',125]]
df1 = pd.DataFrame(data1, columns = ['Left','Right','Value'])
df2 = pd.DataFrame(data2, columns = ['Left','Right','Value'])
df3 = pd.DataFrame(data3, columns = ['Left','Right','Value'])

def heatmap(df, title):
    letters = ['A','B']
    mapper = LinearColorMapper(palette=['#225ea8', '#41b6c4', '#a1dab4', '#ffffcc'], low=0, high=200)
    TOOLS = 'reset'

    p = figure(plot_width=255, plot_height=250, title=title,
               x_range=letters, 
               y_range=list(reversed(letters)), x_axis_location='above',
               tools=TOOLS, toolbar_location='below')

    p.grid.grid_line_color = None
    p.grid.grid_line_width = 0.5
    p.axis.axis_line_color = None
    p.axis.major_tick_line_color = None
    p.axis.major_label_text_font_size = '9pt'
    p.axis.major_label_standoff = 0
    p.xaxis.major_label_orientation = 0

    hover = HoverTool()

    p.rect(x='Right', y='Left', width=1, height=1, line_color=None, source=df,
               fill_color={'field': 'Value', 'transform': mapper})

    hover.tooltips = [('Group','@Left @Right'), ('Value','@Value')]

    p.tools.append(hover)

    return p

output_notebook() 

p1 = heatmap(df1, 'Plot 1')
p2 = heatmap(df2, 'Plot 2')
p3 = heatmap(df3, 'Plot 3')
grid = gridplot([[p1,p2,p3]])
show(grid)

Output:

enter image description here

My goal is to be able to observe the values across multiple plots at one time without having to be directed to another page or source, so I am open to alternative ways of doing this that doesn't involve hover tooltips. Thanks!

0 Answers
Related