☰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

TapTool callback not updating CDS

Community Support
Marcus_Donnelly
Marcus_Donnelly

Hi Bryan et al,

I’m trying to get a CustomJS callback in a TapTool to update a ColumnDataSource but it doesn’t seem to be working. Code below. In the browser console log I can see the list of x coordinates being updated when I tap on the line, but the server console readout doesn’t show the same data - the CDS list remains empty. Am I missing something or is this a bug? I’m running v0.12.6 on Ubuntu MATE 16.04.2, Firefox 54.0.

Thanks,
Marcus.

from bokeh.models.sources import ColumnDataSource
from bokeh.models.tools import TapTool
from bokeh.models.callbacks import CustomJS
from bokeh.plotting import Figure
from bokeh.io import curdoc

src = ColumnDataSource(data={‘x’: })

js = ‘’’
var geom = cb_data[‘geometries’];
var data = source.get(‘data’);
var tx = geom[0].x;
var x = data[‘x’];
x.push(tx);
data[‘x’] = x;
source.trigger(‘change’);
console.log(source.get(‘data’)[‘x’]);
‘’’

cjs = CustomJS(args={‘source’: src}, code=js)
tap_tool = TapTool(callback=cjs)

plot = Figure(x_axis_label=‘x’, y_axis_label=‘y’,
plot_width=400, plot_height=400,
x_range=[0, 1], y_range=[0, 1],
tools=[tap_tool])
plot.line([0, 1], [0, 1], line_width=2)

def update():
print(src.data[‘x’])

curdoc().add_root(plot)
curdoc().add_periodic_callback(update, 1000)

⌁   Link to post
Bryan
Bryan

Hi,

Are you expecting the tap tool callback to fire on all mouse taps? It only fires when the tap "hits" glyph and makes a selection. If you want events on arbitrary mouse taps, you would be much better off the recent new bokeh.events module. See, e.g.:

  https://github.com/bokeh/bokeh/blob/master/examples/howto/js_events.py

Or:

  https://github.com/bokeh/bokeh/blob/master/examples/howto/events_app.py

Here is a code snippet from the release blog post that adds new points on every mouse tap:

  from bokeh.events import Tap

  p = figure(x_range=(0,10), y_range=(0,10))
  s1 = ColumnDataSource(data=dict(x=, y=, c=))
  p.circle('x', 'y', size=20, alpha=0.4, source=s1)

  p.js_on_event(Tap, CustomJS(args=dict(s=s1), code="""
                # cb_obj is the "event"
    s.data.x.push(cb_obj.x)
    s.data.y.push(cb_obj.y)
    s.trigger('change')
  """))

Thanks,

Bryan

···

On Jun 27, 2017, at 10:53, Marcus Donnelly <marcus.k.donnelly@gmail.com> wrote:

I'm still stuck on this - any ideas anyone?

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bokeh+unsubscribe@continuum.io.
To post to this group, send email to bokeh@continuum.io.
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/c8ca0e29-bc99-4c98-a024-4815cb333271%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

⌁   Link to post
Marcus_Donnelly
Marcus_Donnelly

Hi Bryan,

Thanks for that. I understand that the callback only fires on glpyh selection, but thought it would still work provided I clicked on the line. That said, the bokeh.events module looks like just what I need. However, I tried adapting the code using that - see below - and it still doesn’t work: I can see x and y being appended in the browser console but they remain empty at the python console periodic readout. Perhaps I’m missing something obvious but any help would be appreciated!

Thanks,
Marcus.

from bokeh.models.sources import ColumnDataSource
from bokeh.events import Tap
from bokeh.models.callbacks import CustomJS
from bokeh.plotting import Figure
from bokeh.io import curdoc

src = ColumnDataSource(data={‘x’: , ‘y’: })

js = ‘’’
source.data.x.push(cb_obj.x);
source.data.y.push(cb_obj.y);
source.trigger(‘change’);
console.log(source.data.x)
console.log(source.data.y)
‘’’

cjs = CustomJS(args={‘source’: src}, code=js)

plot = Figure(x_axis_label=‘x’, y_axis_label=‘y’,
plot_width=400, plot_height=400,
x_range=[0, 1], y_range=[0, 1])

plot.circle(‘x’, ‘y’, source=src, size=10, color=‘blue’)
plot.js_on_event(Tap, cjs)

def update():
print(‘x:’, src.data[‘x’], ‘y:’, src.data[‘y’])

curdoc().add_root(plot)
curdoc().add_periodic_callback(update, 1000)

``

⌁   Link to post
Marcus_Donnelly
Marcus_Donnelly

Hi Bryan,

I hadn’t looked closely enough at the examples - apologies - working version below. The bokeh.events module is another great addition!

Thanks again for the help,
Marcus.

from bokeh.models.sources import ColumnDataSource
from bokeh.models.callbacks import CustomJS
from bokeh.plotting import Figure
from bokeh.io import curdoc
from bokeh import events

src = ColumnDataSource(data={‘x’: , ‘y’: })

js = ‘’’
source.data.x.push(cb_obj.x);
source.data.y.push(cb_obj.y);
source.trigger(‘change’);
console.log(‘x coords:’, source.data.x);
console.log(‘y coords:’, source.data.y);
‘’’

cjs = CustomJS(args={‘source’: src}, code=js)

plot = Figure(x_axis_label=‘x’, y_axis_label=‘y’,
plot_width=400, plot_height=400,
x_range=[0, 1], y_range=[0, 1])

plot.circle(‘x’, ‘y’, source=src, size=10, color=‘blue’)
plot.js_on_event(events.Tap, cjs)

def update(event):
src.data[‘x’].append(event.x)
src.data[‘y’].append(event.y)
taps = [*zip(src.data[‘x’], src.data[‘y’])]
print(‘Tap locations…’)
for tap in taps:
print(‘x = {x}, y = {y}’.format(x=tap[0], y=tap[1]))

plot.on_event(events.Tap, update)
curdoc().add_root(plot)

``

⌁   Link to post

End of archived discussion · Replies are disabled