Python Bokeh CustomJS: Debugging a JavaScript callback for the Taping-Tool

[亡魂溺海] 提交于 2020-01-25 01:25:08

问题


I am working with Python 3.6.2 and Bokeh 1.0.4 to create a custom JavaScript callback in my plot.

By tapping on one of the points in the plot, I'd like all points sharing the same attribute in the id-column to be highlighted.

Iterating over all datapoints with JavaScript and manipulating the respective 'selected'-attribute in the ColumnDataSource-object should do the trick. Unfortunately I can not figure out how to correct this code.

# Import packages
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, CustomJS, HoverTool, TapTool


# Create the data for the points
x = [0, 1, 2, 3]
y = [0, 1, 0, 1]
ids = ['A','B','A','B']

data = {'x':x, 'y':y, 'id':ids}
source = ColumnDataSource(data)


# Add tools to the plot
tap = TapTool()
hover = HoverTool(tooltips=[("X", "@x"),
                            ("Y", "@y"),
                            ("ID", "@id")])


# Create a plotting figure
p = figure(plot_width=400, plot_height=400, tools=[tap,hover])


# Code for the callback
code = """
// Set column name to select similar glyphs
var column = 'id';

// Get data from ColumnDataSource
var data = source.data;

// Get indices array of all selected items
var selected = source.selected.indices;

// Array to store glyph-indices to highlight
var select_inds = [];


// Check if only a single glyph is selected
if(selected.length==1){

    // Get the value of the column to find similar attributes/glyphs
    attribute_value = data[column][selected[0]];

    // Iterate over all entries in the ColumnDataSource
    for (var i=0; i<data[column].length; ++i){

        // Check if items have the same attribute
        if(data[column][i]==attribute_value){

            // Add index to selected list
            select_inds.push(i);
            }
        }
    }

// Set selected glyphs in ColumnDataSource
source.selected.indices = select_inds;

// Save changes to ColumnDataSource
source.change.emit();
"""


# Create a CustomJS callback with the code and the data
callback = CustomJS(args={'source':source}, code=code)

# Add the callback to the ColumnDataSource
source.callback=callback


# Plots circles
p.circle('x', 'y', source=source, size=25, color='blue', alpha=1, hover_color='black', hover_alpha=1)

# Show plot
show(p)

An older version of this problem with Bokeh 0.13.0 could not solve my problem.


回答1:


You were almost there! The callback has to be added to the TapTool instead of the ColumnDataSource.

# Import packages
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, CustomJS, HoverTool, TapTool


# Create the data for the points
x = [0, 1, 2, 3]
y = [0, 1, 0, 1]
ids = ['A','B','A','B']

data = {'x':x, 'y':y, 'id':ids}
source = ColumnDataSource(data)


# Add tools to the plot
tap = TapTool()
hover = HoverTool(tooltips=[("X", "@x"),
                            ("Y", "@y"),
                            ("ID", "@id")])


# Create a plotting figure
p = figure(plot_width=400, plot_height=400, tools=[tap,hover])


# Code for the callback
code = """
// Set column name to select similar glyphs
var column = 'id';

// Get data from ColumnDataSource
var data = source.data;

// Get indices array of all selected items
var selected = source.selected.indices;

// Array to store glyph-indices to highlight
var select_inds = [];

// Check if only a single glyph is selected
if(selected.length==1){

    // Get the value of the column to find similar attributes/glyphs
    attribute_value = data[column][selected[0]];

    // Iterate over all entries in the ColumnDataSource
    for (var i=0; i<data[column].length; ++i){

        // Check if items have the same attribute
        if(data[column][i]==attribute_value){

            // Add index to selected list
            select_inds.push(i);
            }
        }
    }

// Set selected glyphs in ColumnDataSource
source.selected.indices = select_inds;

// Save changes to ColumnDataSource
source.change.emit();
"""


# Create a CustomJS callback with the code and the data
callback = CustomJS(args={'source':source}, code=code)

# Add the callback to the taptool
tap.callback=callback


# Plots circles
p.circle('x', 'y', source=source, size=25, color='blue', alpha=1, hover_color='black', hover_alpha=1)

# Show plot
show(p)


来源:https://stackoverflow.com/questions/54768576/python-bokeh-customjs-debugging-a-javascript-callback-for-the-taping-tool

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!