Is it possible to bind a Python callback to a BoxZoomTool event

Hi list,

I am very new to Bokeh, so please be kind to me if my question does not make sense :slight_smile:

My question is if it is possible to construct a BoxZoomTool that will trigger a callback to Python when an area is selected. Something along the following lines:

def my_bzt_callback(attrname, old, new):

# Update data

pass

bzt = BoxZoomTool()

bzt.on_change(“some_event_indicating_selection_is_made”, my_bzt_callback)

tools = [bzt]

f = figure(tools=tools)

I want this behaviour as I am visualizing time series data of a certain, very high frequency, and based on the range of the selection, want to do a frequenzy conversion server side to minimize the data sendt to the client side.

I am not able to find out if this is even possible in a simple way, and if it is, what kind of event I would use as first arg to the on_change method.

Best,

Ola Skavhaug

Hi,

Yes, just to be clear up front: only when using a Bokeh server app. Browsers have no ability to run python code, so if you want real python code run in response to some event (e.g. a selection) then there has to be a place for that python code to run. The bokeh server is that place.

Selections are stored on data sources, so you'd add an .on_change to a data source object. There is a deployed demo example that shows python code responding to a selection here:

  https://demo.bokehplots.com/apps/selection_histogram

Make a selection and see the histograms on the side be updated. The code for that example is here:

  https://github.com/bokeh/bokeh/blob/master/examples/app/selection_histogram.py

Note hat link is to GitHub "master" branch, so if you are using and older version of Bokeh you might have to check out a tag corresponding to your version.

Thanks,

Bryan

···

On Dec 13, 2016, at 10:06 AM, Ola Skavhaug <[email protected]> wrote:

Hi list,

I am very new to Bokeh, so please be kind to me if my question does not make sense :slight_smile:

My question is if it is possible to construct a BoxZoomTool that will trigger a callback to Python when an area is selected. Something along the following lines:

def my_bzt_callback(attrname, old, new):
    # Update data
    pass

bzt = BoxZoomTool()
bzt.on_change("some_event_indicating_selection_is_made", my_bzt_callback)
tools = [bzt]
f = figure(tools=tools)

I want this behaviour as I am visualizing time series data of a certain, very high frequency, and based on the range of the selection, want to do a frequenzy conversion server side to minimize the data sendt to the client side.

I am not able to find out if this is even possible in a simple way, and if it is, what kind of event I would use as first arg to the on_change method.

Best,
Ola Skavhaug

--
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 [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/16004570-8594-4fcb-8bea-2c761deaa207%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Hi, thanks for your quick reply.

I absolutely understand the difference between the javascript running in the browser, and the bokeh server communicating with bokeh.js, so in order to get this to work, I need to run the server.

I have tried to follow the example you provided, but I am still not able to figure out what kind of event that is triggered by the BoxZoomTool. At least, after using the zoom tool, a don’t get a “selected” event.

What I’m doing is:

f = figure()

l1 = f.line(“x”, “y”, data_source)

def my_callback(attrname, old, new):

print(attrname, old, new)

l1.data_source.on_change(“selected”, my_callback)

Using the BoxZoomTool does not give me any printouts. Changing the data, however, does (through the use of a Select widget with a corresponding on_change(“value”, select_callback) callback handler).

Best,

···

On Tue, Dec 13, 2016 at 5:13 PM, Bryan Van de Ven [email protected] wrote:

Hi,

Yes, just to be clear up front: only when using a Bokeh server app. Browsers have no ability to run python code, so if you want real python code run in response to some event (e.g. a selection) then there has to be a place for that python code to run. The bokeh server is that place.

Selections are stored on data sources, so you’d add an .on_change to a data source object. There is a deployed demo example that shows python code responding to a selection here:

    [https://demo.bokehplots.com/apps/selection_histogram](https://demo.bokehplots.com/apps/selection_histogram)

Make a selection and see the histograms on the side be updated. The code for that example is here:

    [https://github.com/bokeh/bokeh/blob/master/examples/app/selection_histogram.py](https://github.com/bokeh/bokeh/blob/master/examples/app/selection_histogram.py)

Note hat link is to GitHub “master” branch, so if you are using and older version of Bokeh you might have to check out a tag corresponding to your version.

Thanks,

Bryan

On Dec 13, 2016, at 10:06 AM, Ola Skavhaug [email protected] wrote:

Hi list,

I am very new to Bokeh, so please be kind to me if my question does not make sense :slight_smile:

My question is if it is possible to construct a BoxZoomTool that will trigger a callback to Python when an area is selected. Something along the following lines:

def my_bzt_callback(attrname, old, new):

# Update data
pass

bzt = BoxZoomTool()

bzt.on_change(“some_event_indicating_selection_is_made”, my_bzt_callback)

tools = [bzt]

f = figure(tools=tools)

I want this behaviour as I am visualizing time series data of a certain, very high frequency, and based on the range of the selection, want to do a frequenzy conversion server side to minimize the data sendt to the client side.

I am not able to find out if this is even possible in a simple way, and if it is, what kind of event I would use as first arg to the on_change method.

Best,

Ola Skavhaug

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 [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/16004570-8594-4fcb-8bea-2c761deaa207%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

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 [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/A8DD3338-B6C2-49C0-ADDB-0E68A5B7AF73%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Ola Skavhaug

My apologies, I read too quickly, and answered about a BoxSelectionTool instead of a BoxZoomTool (the general questions support burden is growing larger than I can keep up with by myself). No, The BoxZoomTool does not currently set any properties that could be reacted to from python via on_change.

There are some possibilities:

* watch the plot's range start/end properties instead. This will trigger events due to panning, and not just zooming. Also all the x and y start/end events will come in independently (i.e. a single box zoom could trigger multiple events) which might be problematic

* Make a custom extension that thinly wraps the current BoxZoomTool. It could define and set a single new property every time the zoom fires, then from python you could use on_change to watch this property. Documentation on extending Bokeh is here:

  http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html

We would certainly also consider a Pull Request that added a property like that directly to BoxZoomTool, it's just not something the core team would be able to prioritize right now (we are stretched very thin)

Thanks,

Bryan

···

On Dec 14, 2016, at 5:12 AM, Ola Skavhaug <[email protected]> wrote:

Hi, thanks for your quick reply.

I absolutely understand the difference between the javascript running in the browser, and the bokeh server communicating with bokeh.js, so in order to get this to work, I need to run the server.

I have tried to follow the example you provided, but I am still not able to figure out what kind of event that is triggered by the BoxZoomTool. At least, after using the zoom tool, a don't get a "selected" event.

What I'm doing is:

f = figure()
l1 = f.line("x", "y", data_source)

def my_callback(attrname, old, new):
    print(attrname, old, new)

l1.data_source.on_change("selected", my_callback)

Using the BoxZoomTool does not give me any printouts. Changing the data, however, does (through the use of a Select widget with a corresponding on_change("value", select_callback) callback handler).

Best,

Ola Skavhaug

On Tue, Dec 13, 2016 at 5:13 PM, Bryan Van de Ven <[email protected]> wrote:
Hi,

Yes, just to be clear up front: only when using a Bokeh server app. Browsers have no ability to run python code, so if you want real python code run in response to some event (e.g. a selection) then there has to be a place for that python code to run. The bokeh server is that place.

Selections are stored on data sources, so you'd add an .on_change to a data source object. There is a deployed demo example that shows python code responding to a selection here:

        https://demo.bokehplots.com/apps/selection_histogram

Make a selection and see the histograms on the side be updated. The code for that example is here:

        https://github.com/bokeh/bokeh/blob/master/examples/app/selection_histogram.py

Note hat link is to GitHub "master" branch, so if you are using and older version of Bokeh you might have to check out a tag corresponding to your version.

Thanks,

Bryan

> On Dec 13, 2016, at 10:06 AM, Ola Skavhaug <[email protected]> wrote:
>
> Hi list,
>
> I am very new to Bokeh, so please be kind to me if my question does not make sense :slight_smile:
>
> My question is if it is possible to construct a BoxZoomTool that will trigger a callback to Python when an area is selected. Something along the following lines:
>
> def my_bzt_callback(attrname, old, new):
> # Update data
> pass
>
> bzt = BoxZoomTool()
> bzt.on_change("some_event_indicating_selection_is_made", my_bzt_callback)
> tools = [bzt]
> f = figure(tools=tools)
>
> I want this behaviour as I am visualizing time series data of a certain, very high frequency, and based on the range of the selection, want to do a frequenzy conversion server side to minimize the data sendt to the client side.
>
> I am not able to find out if this is even possible in a simple way, and if it is, what kind of event I would use as first arg to the on_change method.
>
> Best,
> Ola Skavhaug
>
> --
> 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 [email protected].
> To post to this group, send email to [email protected].
> To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/16004570-8594-4fcb-8bea-2c761deaa207%40continuum.io.
> For more options, visit https://groups.google.com/a/continuum.io/d/optout.

--
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 [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/A8DD3338-B6C2-49C0-ADDB-0E68A5B7AF73%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

--
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 [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/CAOS-rS78odxE9fwrat%2BhGPQ9fLiiuBzVM9eaK-OrmJJKv6JRBA%40mail.gmail.com.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Great Bryan,

thanks for this information! I will consider the extension, or even a pull request, on the BoxZoomTool, as this will give me more insights into the core concepts and code of Bokeh. However, as my use case is really to use the plot xrange to dynamically change the time series frequency for server side data reduction, watching the range start/end properties is actually better for me for this particular issue. Just a final question regarding this. I guess I could bind a callback directly to the figure, using:

f = figure()

f.on_change(“some_event”, fig_callback)

What kind of event would be sendt when the ranges update?

Thanks a lot for your help, I really appreciate it. Keep up the great work on Bokeh!

Ola

···

On Wed, Dec 14, 2016 at 4:30 PM, Bryan Van de Ven [email protected] wrote:

My apologies, I read too quickly, and answered about a BoxSelectionTool instead of a BoxZoomTool (the general questions support burden is growing larger than I can keep up with by myself). No, The BoxZoomTool does not currently set any properties that could be reacted to from python via on_change.

There are some possibilities:

  • watch the plot’s range start/end properties instead. This will trigger events due to panning, and not just zooming. Also all the x and y start/end events will come in independently (i.e. a single box zoom could trigger multiple events) which might be problematic

  • Make a custom extension that thinly wraps the current BoxZoomTool. It could define and set a single new property every time the zoom fires, then from python you could use on_change to watch this property. Documentation on extending Bokeh is here:

      [http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html](http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html)
    

We would certainly also consider a Pull Request that added a property like that directly to BoxZoomTool, it’s just not something the core team would be able to prioritize right now (we are stretched very thin)

Thanks,

Bryan

On Dec 14, 2016, at 5:12 AM, Ola Skavhaug [email protected] wrote:

Hi, thanks for your quick reply.

I absolutely understand the difference between the javascript running in the browser, and the bokeh server communicating with bokeh.js, so in order to get this to work, I need to run the server.

I have tried to follow the example you provided, but I am still not able to figure out what kind of event that is triggered by the BoxZoomTool. At least, after using the zoom tool, a don’t get a “selected” event.

What I’m doing is:

f = figure()

l1 = f.line(“x”, “y”, data_source)

def my_callback(attrname, old, new):

print(attrname, old, new)

l1.data_source.on_change(“selected”, my_callback)

Using the BoxZoomTool does not give me any printouts. Changing the data, however, does (through the use of a Select widget with a corresponding on_change(“value”, select_callback) callback handler).

Best,

Ola Skavhaug

On Tue, Dec 13, 2016 at 5:13 PM, Bryan Van de Ven [email protected] wrote:

Hi,

Yes, just to be clear up front: only when using a Bokeh server app. Browsers have no ability to run python code, so if you want real python code run in response to some event (e.g. a selection) then there has to be a place for that python code to run. The bokeh server is that place.

Selections are stored on data sources, so you’d add an .on_change to a data source object. There is a deployed demo example that shows python code responding to a selection here:

    [https://demo.bokehplots.com/apps/selection_histogram](https://demo.bokehplots.com/apps/selection_histogram)

Make a selection and see the histograms on the side be updated. The code for that example is here:

    [https://github.com/bokeh/bokeh/blob/master/examples/app/selection_histogram.py](https://github.com/bokeh/bokeh/blob/master/examples/app/selection_histogram.py)

Note hat link is to GitHub “master” branch, so if you are using and older version of Bokeh you might have to check out a tag corresponding to your version.

Thanks,

Bryan

On Dec 13, 2016, at 10:06 AM, Ola Skavhaug [email protected] wrote:

Hi list,

I am very new to Bokeh, so please be kind to me if my question does not make sense :slight_smile:

My question is if it is possible to construct a BoxZoomTool that will trigger a callback to Python when an area is selected. Something along the following lines:

def my_bzt_callback(attrname, old, new):

# Update data
pass

bzt = BoxZoomTool()

bzt.on_change(“some_event_indicating_selection_is_made”, my_bzt_callback)

tools = [bzt]

f = figure(tools=tools)

I want this behaviour as I am visualizing time series data of a certain, very high frequency, and based on the range of the selection, want to do a frequenzy conversion server side to minimize the data sendt to the client side.

I am not able to find out if this is even possible in a simple way, and if it is, what kind of event I would use as first arg to the on_change method.

Best,

Ola Skavhaug

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 [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/16004570-8594-4fcb-8bea-2c761deaa207%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

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 [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/A8DD3338-B6C2-49C0-ADDB-0E68A5B7AF73%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

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 [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/CAOS-rS78odxE9fwrat%2BhGPQ9fLiiuBzVM9eaK-OrmJJKv6JRBA%40mail.gmail.com.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

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 [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/758D8082-FEDC-4A3B-B46E-EB8333F3C165%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Ola Skavhaug, PhD
Founder, Expert Analytics AS

Ok, I did a little googling, and found out that one way of doing this is:

f = figure()

f.x_range.on_change(“end”, range_cb)

does the job. It does communicate a lot of values, though, and since each value possibly would require quite some calculations, I am still not quite there. The PanTool does not have a “select_every_mousemove”, or similar, to only send the event when user has stopped panning. This is something I guess I will have to solve on the server side for now, e.g. to only update the data when the range has changed “enough”.

Thanks again,

Ola

···

On Thu, Dec 15, 2016 at 9:04 AM, Ola Skavhaug [email protected] wrote:

Great Bryan,

thanks for this information! I will consider the extension, or even a pull request, on the BoxZoomTool, as this will give me more insights into the core concepts and code of Bokeh. However, as my use case is really to use the plot xrange to dynamically change the time series frequency for server side data reduction, watching the range start/end properties is actually better for me for this particular issue. Just a final question regarding this. I guess I could bind a callback directly to the figure, using:

f = figure()

f.on_change(“some_event”, fig_callback)

What kind of event would be sendt when the ranges update?

Thanks a lot for your help, I really appreciate it. Keep up the great work on Bokeh!

Ola

Ola Skavhaug, PhD
Founder, Expert Analytics AS

Ola Skavhaug, PhD
Founder, Expert Analytics AS

On Wed, Dec 14, 2016 at 4:30 PM, Bryan Van de Ven [email protected] wrote:

My apologies, I read too quickly, and answered about a BoxSelectionTool instead of a BoxZoomTool (the general questions support burden is growing larger than I can keep up with by myself). No, The BoxZoomTool does not currently set any properties that could be reacted to from python via on_change.

There are some possibilities:

  • watch the plot’s range start/end properties instead. This will trigger events due to panning, and not just zooming. Also all the x and y start/end events will come in independently (i.e. a single box zoom could trigger multiple events) which might be problematic

  • Make a custom extension that thinly wraps the current BoxZoomTool. It could define and set a single new property every time the zoom fires, then from python you could use on_change to watch this property. Documentation on extending Bokeh is here:

      [http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html](http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html)
    

We would certainly also consider a Pull Request that added a property like that directly to BoxZoomTool, it’s just not something the core team would be able to prioritize right now (we are stretched very thin)

Thanks,

Bryan

On Dec 14, 2016, at 5:12 AM, Ola Skavhaug [email protected] wrote:

Hi, thanks for your quick reply.

I absolutely understand the difference between the javascript running in the browser, and the bokeh server communicating with bokeh.js, so in order to get this to work, I need to run the server.

I have tried to follow the example you provided, but I am still not able to figure out what kind of event that is triggered by the BoxZoomTool. At least, after using the zoom tool, a don’t get a “selected” event.

What I’m doing is:

f = figure()

l1 = f.line(“x”, “y”, data_source)

def my_callback(attrname, old, new):

print(attrname, old, new)

l1.data_source.on_change(“selected”, my_callback)

Using the BoxZoomTool does not give me any printouts. Changing the data, however, does (through the use of a Select widget with a corresponding on_change(“value”, select_callback) callback handler).

Best,

Ola Skavhaug

On Tue, Dec 13, 2016 at 5:13 PM, Bryan Van de Ven [email protected] wrote:

Hi,

Yes, just to be clear up front: only when using a Bokeh server app. Browsers have no ability to run python code, so if you want real python code run in response to some event (e.g. a selection) then there has to be a place for that python code to run. The bokeh server is that place.

Selections are stored on data sources, so you’d add an .on_change to a data source object. There is a deployed demo example that shows python code responding to a selection here:

    [https://demo.bokehplots.com/apps/selection_histogram](https://demo.bokehplots.com/apps/selection_histogram)

Make a selection and see the histograms on the side be updated. The code for that example is here:

    [https://github.com/bokeh/bokeh/blob/master/examples/app/selection_histogram.py](https://github.com/bokeh/bokeh/blob/master/examples/app/selection_histogram.py)

Note hat link is to GitHub “master” branch, so if you are using and older version of Bokeh you might have to check out a tag corresponding to your version.

Thanks,

Bryan

On Dec 13, 2016, at 10:06 AM, Ola Skavhaug [email protected] wrote:

Hi list,

I am very new to Bokeh, so please be kind to me if my question does not make sense :slight_smile:

My question is if it is possible to construct a BoxZoomTool that will trigger a callback to Python when an area is selected. Something along the following lines:

def my_bzt_callback(attrname, old, new):

# Update data
pass

bzt = BoxZoomTool()

bzt.on_change(“some_event_indicating_selection_is_made”, my_bzt_callback)

tools = [bzt]

f = figure(tools=tools)

I want this behaviour as I am visualizing time series data of a certain, very high frequency, and based on the range of the selection, want to do a frequenzy conversion server side to minimize the data sendt to the client side.

I am not able to find out if this is even possible in a simple way, and if it is, what kind of event I would use as first arg to the on_change method.

Best,

Ola Skavhaug

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 [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/16004570-8594-4fcb-8bea-2c761deaa207%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

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 [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/A8DD3338-B6C2-49C0-ADDB-0E68A5B7AF73%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

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 [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/CAOS-rS78odxE9fwrat%2BhGPQ9fLiiuBzVM9eaK-OrmJJKv6JRBA%40mail.gmail.com.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

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 [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/758D8082-FEDC-4A3B-B46E-EB8333F3C165%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.