☰Read-only archive⌕
Looking for help with Bokeh?

This is a read-only archive. Ask questions and join the conversation on GitHub.

Visit Community Support on GitHub →
Archived discussions · Captured October 28, 2026

How to link individual buttons in a CheckboxButtonGroup to different callback functions

Community Support
webbja123
webbja123

I am trying to work through several Bokeh examples that are not covered in the tutorials as a method of learning the package. Right now I am trying to encode a simple scatter plot with circle glyphs with three buttons within a CheckboxButtonGroup. I would like to link a callback function to each button, but so far I am only able to link one Callback function to the entire group, such that depressing any of the three buttons will execute the same function, instead of a different function for each button. How can I link a Callback function to each button? My sample code is attached.
from bokeh.models import ColumnDataSource, CustomJS, Button
from bokeh.models import CheckboxButtonGroup
from bokeh.plotting import Figure, output_file, show
from bokeh.layouts import column

output_file("js_on_change.html")

x = [1.2, 2.4, 0.8, 5.6, 12.1, 8.8]
y = [3.4, 1.1, 4.2, 6.6, 1.8, 12.1]
z = ['Apple', 'Apple', 'Orange', 'Orange', 'Orange', 'Orange']

data = dict(x=x, y=y, z=z)
source = ColumnDataSource(data)

counter = [0]
counter = dict(counter=counter)
counter1 = ColumnDataSource(counter)
counter2 = ColumnDataSource(counter)
counter3 = ColumnDataSource(counter)

plot = Figure(plot_width=400, plot_height=400)
plot.circle('x', 'y', source=source, size=8, line_alpha=0.6)

callback1 = CustomJS(args=dict(source=source, counter=counter1), code="""
    var f = 3.0

    var count = counter.data;
    var c = count['counter']
    if (c[0]%2==1) f = -1*f;
    c[0]++
    counter.change.emit();
    
    var data = source.data;
    var x = data['x']
    var y = data['y']
    for (var i = 0; i < x.length; i++) {
        y[i] = y[i] + f
    }
    source.change.emit();
""")

callback2 = CustomJS(args=dict(source=source, counter=counter2), code="""
    var f = 3.0

    var count = counter2.data;
    var c = count['counter']
    if (c[0]%2==1) f = -1*f;
    c[0]++
    counter.change.emit();
    
    var data = source.data;
    var x = data['x']
    var y = data['y']
    for (var i = 0; i < x.length; i++) {
        y[i] = y[i] * f
    }
    source.change.emit();
""")

callback3 = CustomJS(args=dict(source=source, counter=counter3), code="""
    var f = 3.0

    var count = counter3.data;
    var c = count['counter']
    if (c[0]%2==1) f = -1*f;
    c[0]++
    counter.change.emit();
    
    var data = source.data;
    var x = data['x']
    var y = data['y']
    for (var i = 0; i < x.length; i++) {
        y[i] = Math.pow(x[i], f)
    }
    source.change.emit();
""")

LABELS = ["Add Subtract", "Multiply", "Power"]

checkbox_button_group = CheckboxButtonGroup(labels=LABELS, active=[0, 1, 2])

checkbox_button_group.js_on_click(callback1)
checkbox_button_group.js_on_click(callback2)

layout = column(checkbox_button_group, plot)
show(layout)
⌁   Link to post
Bryan
Bryan

This is not possible. You will have to write one callback that looks at the new value for the CheckboxButtonGroup as a whole, and reacts differently depending on the value.

⌁   Link to post
webbja123
webbja123

Bryan, that’s good information to have, thank you. However, how do I get each button to provide a specific response and how do I reference that response in the single callback function. Please forgive me, my JavaScript background is minimal.

⌁   Link to post
Bryan
Bryan

You can look at the active property of the widget in the callback, which will tell you which of the checkboxes is checked:

callback = CustomJS(args=dict(group=checkbox_button_group), code="""
   console.log(group.active)
""")
⌁   Link to post
webbja123
webbja123

Does your response imply that with the callback function provided I should see the specific response printed to my terminal or someplace on the html display when I click a button in the group? Like I mentioned, I am working on picking up javascript, but am barely a novice. It appears that the console.log command should print the active property to the terminal, but that is not the behavior I am seeing.

⌁   Link to post
Bryan
Bryan

@webbja123 console.log prints the the browser’s JavaScript console which is normally part of a browsers “dev tools”. Every browser has a different way to access the JS console and related dev tools[1], so you will have to Google for the specifics regarding whatever browser you happen to be using.


  1. E.g. on OSX/Safari it’s command-option-C to open the JS console but that obviously won’t apply to windows or even necessarily other browsers on OS X ↩︎

⌁   Link to post

End of archived discussion · Replies are disabled