Add annotations/glyphs from a server-callback

Hi all,

I’m trying to add annotations from a server callback. The callback should “wrap” a tapped point with a region on its sides.

My code looks like the following:

import numpy as np
from bokeh.models import BoxAnnotation
from bokeh.server.server import Server
from bokeh.plotting import figure


def _app(doc):
    p = figure(tools=['tap'])

    x = np.random.random(size=(1, 1000)) - .5
    x_cum = np.cumsum(x, axis=1)
    t = np.arange(len(x))

    s = p.scatter(t, x_cum)

    def handler(attr, old, new):
        print('attr: {} old: {} new: {}'.format(attr, old, new))

        new_layout = []

        for t in new:
            new_layout.append(BoxAnnotation(left=t - 5, right=t + 5, fill_color='green', fill_alpha=.3, level='underlay'))

        p.center = new_layout


    s.data_source.selected.on_change('indices', handler)

    doc.add_root(p)


server = Server({'/': _app}, num_procs=1)
server.start()

if __name__ == '__main__':
    server.io_loop.add_callback(server.show, "/")
    server.io_loop.start()

I also tried p.add_layout instead of setting p.center but nothing. I saw that for Jupyter notebooks there’s the push_notebook() function that might’ve worked here, so maybe something similar for a server will work?

What am I doing wrong?

I’ve answered at python - Bokeh: Add annotations/glyphs from server callback - Stack Overflow

In future, if you cross-post, please link questions together so that people won’t spend extra time answering a question that might’ve been already answered elsewhere.

You are correct about the cross posting. Sorry.

As I replied there, your answer wasn’t helpful, though this, of course, wasn’t a real problem as my actual code works.
However, your answer was helpful in that that I realized that it might be working for you and not for me. I checked the version for the package I have, and it turns out I have version 2.0.1 where the latest is 2.3.dev1. I updated to the latest version, and it solved this.

Thanks!