When moving the crosshair (dimensions=width) in one plot I want to see the same position in the other plot(s). My plots share the same x-axis.
Here is the plot setup
More compact example for arbitrary number of plots and for both CrossHair dimensions (updated for Bokeh v1.0.4):
from bokeh.models import CustomJS, CrosshairTool
from bokeh.plotting import figure, show, curdoc
from bokeh.layouts import gridplot
import numpy as np
def addLinkedCrosshairs(plots):
js_move = ''' start = fig.x_range.start, end = fig.x_range.end
if(cb_obj.x>=start && cb_obj.x<=end && cb_obj.y>=start && cb_obj.y<=end)
{ cross.spans.height.computed_location=cb_obj.sx }
else { cross.spans.height.computed_location = null }
if(cb_obj.y>=start && cb_obj.y<=end && cb_obj.x>=start && cb_obj.x<=end)
{ cross.spans.width.computed_location=cb_obj.sy }
else { cross.spans.width.computed_location=null }'''
js_leave = '''cross.spans.height.computed_location=null; cross.spans.width.computed_location=null'''
figures = plots[:]
for plot in plots:
crosshair = CrosshairTool(dimensions = 'both')
plot.add_tools(crosshair)
for figure in figures:
if figure != plot:
args = {'cross': crosshair, 'fig': figure}
figure.js_on_event('mousemove', CustomJS(args = args, code = js_move))
figure.js_on_event('mouseleave', CustomJS(args = args, code = js_leave))
plots = [figure(plot_width = 200, plot_height = 200, tools = '') for i in range(9)]
[plot.line(np.arange(10), np.random.random(10)) for plot in plots]
addLinkedCrosshairs(plots)
show(gridplot(children = [plot for plot in plots], ncols = 3))
To reduce to just one dimension (vertical or horizontal) remove the corresponding "if / else" part of the callback
Result: