Skip to content Skip to sidebar Skip to footer

Filtering Bokeh LabelSet With Javascript

I'm trying to create a Bokeh scatterplot with a CheckboxGroup widget to show or hide individual points based on the corresponding checkbox state. The code snippet below works to c

Solution 1:

I found a way to do what I need. It seems ugly and inefficient, but it works. I created a second CDS for the LabelSet and then used JS to rebuild the data in that CDS from the main CDS using the CheckboxGroup states. Please still feel free to respond if you have a much cleaner and more elegant way to do this.

source = ColumnDataSource(df)
lsource = ColumnDataSource(df)
active = list(range(len(df))
filter = IndexFilter(indices=active)
view = CDSView(source=source, filters=[filter])

p=figure(.....)
p.scatter(x='x', y='y', source=source, view=view)

labels = LabelSet(x='x', y='y', text='label', source=lsource)
p.add_layout(labels)

labelList = df['label'].astype(str).to_list()
labelSel = CheckboxGroup(labels=labelList, active=active)
callback = CustomJS(args=dict(src=source, lsrc=lsource, filt=filter), code='''
    filt.indices = cb_obj.active;
    src.change.emit();

    var data=src.data;
    var l=data['label'];
    var x=data['x'];
    var y=data['y'];

    var ldata=lsrc.data;
    var a=cb_obj.active;

    var ll=[];
    var lx=[];
    var ly=[];
    for(var i=0;i<a.length;i++){
        ll.push(l[a[i]]);
        lx.push(x[a[i]]);
        ly.push(y[a[i]]);
    }

    ldata['label']=ll;
    ldata['x']=lx;
    ldata['y']=ly;
    lsrc.change.emit();
    ''')
labelSel.js_on_change('active', callback)

layout = row(p, Spacer(width=20), labelSel)
show(layout)

Post a Comment for "Filtering Bokeh LabelSet With Javascript"