Bokeh - how to make HoverTool tooltips stick to points on click?

后端 未结 1 710
伪装坚强ぢ
伪装坚强ぢ 2021-02-10 06:30

The code below comes from a jupyter notebook:

from bokeh.io import show, output_notebook
from bokeh.plotting import ColumnDataSource, figure
from bokeh.models im         


        
相关标签:
1条回答
  • 2021-02-10 06:44

    This is a workaround creating your own Hover text using models.Label inside the 'callback' function of models.HoverTool . Also models.TapTool is used for toggle updating the Label text. You can't edit the text in the glyph models.Label, but an TextInput widget has been added where the text is updated as one hover the graph glyphs.

    import bokeh
    import bokeh.plotting
    fig = bokeh.plotting.figure()
    
    d_source = bokeh.models.ColumnDataSource({"left": [1,3,1],
                    "bottom": [1,3,3],"right": [2,4,2],"top": [2,4,4]})
    h_source = bokeh.models.ColumnDataSource({"do_hover":[True,True]  })
    fig.quad(left="left", top="top", bottom="bottom", right="right",
             source=d_source)
    
    myToolTip = bokeh.models.Label(x=2.5,y=2.5, text="",
                                   background_fill_color = "#ffffff")
    
    HoverCallback = bokeh.models.CustomJS(args=dict(d_source=d_source,
                        myToolTip=myToolTip,h_source=h_source),code="""
            function findWhereIam(x,y,s){
                // To find where the cursor is. 
                selection = -1;
                for (i = 0; i < s.data.left.length; i++) {
                    x0 = s.data.left[i];
                    x1 = s.data.right[i];
                    y0 = s.data.bottom[i];
                    y1 = s.data.top[i];
                    if (x>x0 && x<x1 && y>y0 && y<y1){
                        // It's inside rectangle!!!
                        selection = i;
                    }
                }
                return selection
            }
            if (h_source.data.do_hover[0]){
                x_data = cb_data['geometry'].x;
                y_data = cb_data['geometry'].y;
                var selection = findWhereIam(x_data,y_data,d_source)
                if (selection>=0){
                    x0 = d_source.data.left[selection];
                    x1 = d_source.data.right[selection];
                    y0 = d_source.data.bottom[selection];
                    y1 = d_source.data.top[selection];
                    myToolTip.x = 0.5 * (x0+x1);
                    myToolTip.y = 0.5 * (y0+y1);
                    myToolTip.text = "on:"+selection;
                    myToolTip.text_font_size = "24pt";
                    myToolTip.background_fill_color = "#ffffff";
                    myToolTip.border_line_color = "#000000";
                    myToolTip.text_align = "center";
                    myToolTip.trigger('change');
    
                    current_selection.value = myToolTip.text;
                    current_selection.trigger('change');
                }else{
                    myToolTip.text = ""; //erase
                    myToolTip.trigger('change');
                    current_selection.value = myToolTip.text;
                    current_selection.trigger('change');
                }
            }
        """)
    
    TapCallback = bokeh.models.CustomJS(args=dict(h_source=h_source), code="""
            h_source.data.do_hover[0] = !h_source.data.do_hover[0];
        """)
    
    current_selection = bokeh.models.widgets.TextInput(value="",
                                                       title="Selection")
    
    HoverCallback.args.update(dict(current_selection=current_selection))
    
    fig.add_tools(bokeh.models.HoverTool(tooltips=None,callback=HoverCallback))
    fig.add_tools(bokeh.models.TapTool(callback=TapCallback))
    fig.add_layout(myToolTip)
    page = bokeh.plotting.gridplot([[fig],[current_selection]])
    bokeh.io.output_notebook()
    bokeh.io.show(page)
    

    0 讨论(0)
提交回复
热议问题