Hello I’m working with Bokeh 3.0.2 and I am trying to understand callbacks, specially for tools. My main goal right now is to be able to list and modify only points inside a region selected with bokeh tools like lasso, or box or poly. And my second goal is to understand CustomJS.
I have now explored a lot with the example of js-on-event-callback-triggers but I would like to know more about cb_obj and cb_data, are there any more internal objects that I can use?
Whenever a select method is used, it highlights the points inside such region, so there is already a default callback somewhere that does this for me.
With this code I can plot my scatter and any selection highlights points and the polygon/lasso/box points appear written in a div on the right, so I can see the attributes of a cb_obj:
from bokeh import events
from bokeh.layouts import column, row
from bokeh.models import Button, CustomJS, Div
from bokeh.plotting import figure, show
from bokeh.io import push_notebook, show, output_notebook
output_notebook()
def display_event(div, attributes=[]):
"""
Function to build a suitable CustomJS to display the current event
in the div model.
"""
style = 'float: left; clear: left; font-size: 13px'
return CustomJS(args=dict(div=div), code="""
const attrs = %s;
const args = [];
for (let i = 0; i < attrs.length; i++) {
const val = JSON.stringify(cb_obj[attrs[i]], function(key, val) {
return val.toFixed ? Number(val.toFixed(2)) : val;
})
args.push(attrs[i] + '=' + val)
}
const line = "<span style=%r><b>" + cb_obj.event_name + "</b>(" + args.join(", ") + ")</span>\\n";
const text = div.text.concat(line);
const lines = text.split("\\n")
if (lines.length > 35)
lines.shift();
div.text = lines.join("\\n");
""" % (attributes, style))
x=df["u_x"].values
y=df["u_y"].values
colors=list(df["color_hour"].values)
p = figure(tools="pan,wheel_zoom,zoom_in,zoom_out,reset,lasso_select,box_select")
p.scatter(x,y,line_width=0, fill_color=colors)
div = Div(width=1000)
button = Button(label="Button", button_type="success", width=300)
layout = column(button, row(p, div))
p.js_on_event(events.SelectionGeometry, display_event(div, attributes=['geometry', 'final']))
show(layout)
I know I can use a ColumnDataSource instead of a pandas df but then the p.scatter wasn’t working properly when I tried.
Can anyone tell me how it knows which points are inside and how to get them? either via python or js or both? or using a notebook preferably? but if no then a server is ok. I am basically learning by playing around. There are some things that is a bit tough to learn with no documentation other than examples that change a lot between bokeh versions and solutions out there are outdated.