How do I link the CrossHairTool in bokeh over several plots?

后端 未结 5 1271
逝去的感伤
逝去的感伤 2020-12-30 07:34

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

5条回答
  •  滥情空心
    2020-12-30 08:12

    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:

提交回复
热议问题