Highlighting multiple hex_tiles by hovering in bokeh

前端 未结 2 1902
野性不改
野性不改 2021-02-11 04:08

I try to visualize my data in a hex map. For this I use python bokeh and the corresponding hex_tile function in the figure class. My data belongs to one of 8 different classes,

2条回答
  •  广开言路
    2021-02-11 04:39

    Following the discussion from previous post here comes the solution targeted for the OP code (Bokeh v1.1.0). What I did is:

    1) Added a HoverTool

    2) Added a JS callback to the HoverTool which:

    • Resets the hex colors to the original ones (colors_array passed in the callback)
    • Inspects the index of currently hovered hex (hovered_index)
    • Gets the ip_class of currently hovered hex (hovered_ip_class)
    • Walks through the data_source.data['ip_class'] and finds all hexagons with the same ip_class as the hovered one and sets a new color for it (pink)
    • Send source.change.emit() signal to the BokehJS to update the model

    The code:

    from bokeh.plotting import figure, show, output_file
    from bokeh.models import ColumnDataSource, CustomJS, HoverTool
    
    colors_array = ["green", "green", "blue", "blue"]
    x_row = [0, 1, 2, 3]
    y_col = [1, 1, 1, 1]
    ipc_array = ['A', 'B', 'A', 'B']
    
    source = ColumnDataSource(data = dict(
        x = x_row,
        y = y_col,
        color = colors_array,
        ipc_class = ipc_array
    ))
    
    p = figure(plot_width = 800, plot_height = 800, title = "Ipc to Square with colors", match_aspect = True,
               tools = "wheel_zoom,reset,pan", background_fill_color = '#440154')
    p.grid.visible = False
    p.hex_tile('x', 'y', source = source, fill_color = 'color')
    
    ###################################
    code = ''' 
    for (let i in cb_data.renderer.data_source.data['color'])
        cb_data.renderer.data_source.data['color'][i] = colors[i];
    
    if (cb_data.index.indices != null) {
        const hovered_index = cb_data.index.indices[0];
        const hovered_ipc_class = cb_data.renderer.data_source.data['ipc_class'][hovered_index];
        for (let i = 0; i < cb_data.renderer.data_source.data['ipc_class'].length; i++) {
            if (cb_data.renderer.data_source.data['ipc_class'][i] == hovered_ipc_class)
                cb_data.renderer.data_source.data['color'][i] = 'pink';
        }
    }
    cb_data.renderer.data_source.change.emit();
    '''
    
    TOOLTIPS = [
        ("index", "$index"),
        ("(x,y)", "(@x, @y)"),
        ("ipc_class", "@ipc_class")
    ]
    
    callback = CustomJS(args = dict(ipc_array = ipc_array, colors = colors_array), code = code)
    hover = HoverTool(tooltips = TOOLTIPS, callback = callback)
    p.add_tools(hover)
    ########################################
    
    output_file("hexbin.html")
    
    show(p)
    

    Result:

提交回复
热议问题