Define Custom Callback Function Bokeh TapTool

SO: http://stackoverflow.com/questions/34693892/define-custom-callback-function-bokeh-taptool

Hello,

I have a BarPlot (Not Chart but built from figure) that I am embedding in a Flask app. I want to execute some function every time a bar is clicked upon (via TapTool). May I know how do I do that ?

One way I see is to use TapTool’s callback function like the one shown in docs. But how do I use a custom defined function (Not CustomJs but a normal Python func) instead of say, a OpenUrl Callback Function?

Also, please kindly tell how can I access that @foo kind-of variables in a user defined function ?

Thanks,

Kevad.

I have a similar question for Bokeh widget callbacks in general. Although there are many examples illustrating the use of normal python functions for callbacks for various Bokeh widget events, they don’t actually end up getting triggered when I’m running the code without the server in jupyter notebook. As a NOOB Bokeh user I’ve assumed that the reason the examples run fine for those posting them and not for me is that they are either not running in a notebook or are using the Bokeh server.

The only way I’ve been able to get any events or updated values into python from the Bokeh widgets is using the CustomJS callback and in that JS script use IPython.notebook.kernel.execute to set a python variable and/or execute a python function. As with Kevad’s question, I would love to find a way (that works static in a notebook) to basically do what we can do with ipywidgets and simply define and assign a python function that responds to various events such as on_changed or on_clicked without having to write javascript “wrapper” code for every one.

The push_notebook() functions seems to address part of the problem, i.e. getting getting information on events or data from python into javascript, but not the triggering of the events or flow of information from javascript to python. (Yuck! I hope that mess of words actually makes sense to someone besides me.)

···

On Saturday, January 9, 2016 at 6:30:26 AM UTC-7, Kevad wrote:

SO: http://stackoverflow.com/questions/34693892/define-custom-callback-function-bokeh-taptool

Hello,

I have a BarPlot (Not Chart but built from figure) that I am embedding in a Flask app. I want to execute some function every time a bar is clicked upon (via TapTool). May I know how do I do that ?

One way I see is to use TapTool’s callback function like the one shown in docs. But how do I use a custom defined function (Not CustomJs but a normal Python func) instead of say, a OpenUrl Callback Function?

Also, please kindly tell how can I access that @foo kind-of variables in a user defined function ?

Thanks,

Kevad.

I wrote a map that randomly colors itself using the bokeh server with a pure python callback (the function run): https://github.com/jisantuc/UselessMap/blob/master/map_maker.py
When I was experimenting, it seemed like the magic parameters from javascript (attrname, old, new) were the same parameters your python callbacks should have, and things worked as expected. I played around with print statements and functions that don’t do anything to get figure out the parameters for the python callbacks. Maybe that will help? Or does it still fail in a notebook?

···

On Sat, Jan 9, 2016 at 9:15 AM Jim Sharpe [email protected] wrote:

I have a similar question for Bokeh widget callbacks in general. Although there are many examples illustrating the use of normal python functions for callbacks for various Bokeh widget events, they don’t actually end up getting triggered when I’m running the code without the server in jupyter notebook. As a NOOB Bokeh user I’ve assumed that the reason the examples run fine for those posting them and not for me is that they are either not running in a notebook or are using the Bokeh server.

The only way I’ve been able to get any events or updated values into python from the Bokeh widgets is using the CustomJS callback and in that JS script use IPython.notebook.kernel.execute to set a python variable and/or execute a python function. As with Kevad’s question, I would love to find a way (that works static in a notebook) to basically do what we can do with ipywidgets and simply define and assign a python function that responds to various events such as on_changed or on_clicked without having to write javascript “wrapper” code for every one.

The push_notebook() functions seems to address part of the problem, i.e. getting getting information on events or data from python into javascript, but not the triggering of the events or flow of information from javascript to python. (Yuck! I hope that mess of words actually makes sense to someone besides me.)

On Saturday, January 9, 2016 at 6:30:26 AM UTC-7, Kevad wrote:

SO: http://stackoverflow.com/questions/34693892/define-custom-callback-function-bokeh-taptool

Hello,

I have a BarPlot (Not Chart but built from figure) that I am embedding in a Flask app. I want to execute some function every time a bar is clicked upon (via TapTool). May I know how do I do that ?

One way I see is to use TapTool’s callback function like the one shown in docs. But how do I use a custom defined function (Not CustomJs but a normal Python func) instead of say, a OpenUrl Callback Function?

Also, please kindly tell how can I access that @foo kind-of variables in a user defined function ?

Thanks,

Kevad.

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/6d158258-b6ce-4b50-a2a9-3c495f22672d%40continuum.io.

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

Hi Jim,

I'm just about to hop on a plane so apologies for the brief replay. But we could probably lay out the different callback use-cases a bit more clearly. The cross-language makes for a more than typical number of combinations.

* Callbacks in the browser

This is CustomJS. In Python 3 you can write the callback in Python, and it will get converted to JavaScript, but the callback ultimately executes as JavaScript, in the browser.

* Real Python callbacks

This is where you want to call out to real python code (numpy, or scikit-learn, or whatever). Here's the key observation that sounds obvious but I think bears repeating: this requires a running python interpreter somewhere to run the callback! There are a few possibilities:

  - Use a CustomJS callback that makes an AJAX call out to some REST API that you write. The python code executes in the Flask, or Django, or whatever server. This does not (necessarily) involve the Bokeh server or Bokeh widgets

  - Use Jupyter interactors. The python code executes in a Jupyter python kernel. This is typically in conjunction with push_noteboook. This does not (necessarily) involve the Bokeh server or Bokeh widgets

  - Use a Bokeh server. The python code executes in a Bokeh server. The callbacks are hooked up to Bokeh models with .on_change methods on Bokeh models.

That's the only options configurations I can think of off the top of my head. Will try to write more later.

Bryan

···

On Jan 9, 2016, at 8:15 AM, Jim Sharpe <[email protected]> wrote:

I have a similar question for Bokeh widget callbacks in general. Although there are many examples illustrating the use of normal python functions for callbacks for various Bokeh widget events, they don't actually end up getting triggered when I'm running the code without the server in jupyter notebook. As a NOOB Bokeh user I've assumed that the reason the examples run fine for those posting them and not for me is that they are either not running in a notebook or are using the Bokeh server.

The only way I've been able to get any events or updated values into python from the Bokeh widgets is using the CustomJS callback and in that JS script use IPython.notebook.kernel.execute to set a python variable and/or execute a python function. As with Kevad's question, I would love to find a way (that works static in a notebook) to basically do what we can do with ipywidgets and simply define and assign a python function that responds to various events such as on_changed or on_clicked without having to write javascript "wrapper" code for every one.

The push_notebook() functions seems to address part of the problem, i.e. getting getting information on events or data from python into javascript, but not the triggering of the events or flow of information from javascript to python. (Yuck! I hope that mess of words actually makes sense to someone besides me.)

On Saturday, January 9, 2016 at 6:30:26 AM UTC-7, Kevad wrote:
SO: http://stackoverflow.com/questions/34693892/define-custom-callback-function-bokeh-taptool

Hello,

I have a BarPlot (Not Chart but built from figure) that I am embedding in a Flask app. I want to execute some function every time a bar is clicked upon (via TapTool). May I know how do I do that ?

One way I see is to use TapTool's callback function like the one shown in docs. But how do I use a custom defined function (Not CustomJs but a normal Python func) instead of say, a OpenUrlCallback Function?
Also, please kindly tell how can I access that @foo kind-of variables in a user defined function ?

Thanks,
Kevad.

--
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/6d158258-b6ce-4b50-a2a9-3c495f22672d%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Bryan,

Thanks much for the clarification! I think thats very helpful in framing the discussion and sheds light on why there is such variation in examples. In order to help others avoid the confusion I’ve struggled with in the future I think a short writeup on this topic would be of very high value. I know it would have saved me many hours of experimentation.

I’m especially intrigued by your statement *“Python 3 you can write the callback in Python, and it will get converted to JavaScript”. *Can you point me to an example of how this is written? I’m thinking that might do what I need. I don’t really care if it gets converted under the covers, I just would like to avoid having to write the JS myself.

Although I’m sure others will have different situations, but to clarify my need it would be “callbacks in the browser” as I’m running in a python 3.x notebook.

James,

I just tried running your example in a jupyter notebook (python 3.x) with only a couple tweaks - imported bokeh.io output_notebook and called it at the beginning and changed the last line to “show(HBox(inputs))”. Although both the slider and button show up. Nothing happens when I click the button. As a stab in dark I also tried a call to push_notebook() at the end of the run function but that didn’t help.

···

On Saturday, January 9, 2016 at 8:21:47 AM UTC-7, Bryan Van de ven wrote:

Hi Jim,

I’m just about to hop on a plane so apologies for the brief replay. But we could probably lay out the different callback use-cases a bit more clearly. The cross-language makes for a more than typical number of combinations.

  • Callbacks in the browser

This is CustomJS. In Python 3 you can write the callback in Python, and it will get converted to JavaScript, but the callback ultimately executes as JavaScript, in the browser.

  • Real Python callbacks

This is where you want to call out to real python code (numpy, or scikit-learn, or whatever). Here’s the key observation that sounds obvious but I think bears repeating: this requires a running python interpreter somewhere to run the callback! There are a few possibilities:

  • Use a CustomJS callback that makes an AJAX call out to some REST API that you write. The python code executes in the Flask, or Django, or whatever server. This does not (necessarily) involve the Bokeh server or Bokeh widgets

  • Use Jupyter interactors. The python code executes in a Jupyter python kernel. This is typically in conjunction with push_noteboook. This does not (necessarily) involve the Bokeh server or Bokeh widgets

  • Use a Bokeh server. The python code executes in a Bokeh server. The callbacks are hooked up to Bokeh models with .on_change methods on Bokeh models.

That’s the only options configurations I can think of off the top of my head. Will try to write more later.

Bryan

On Jan 9, 2016, at 8:15 AM, Jim Sharpe [email protected] wrote:

I have a similar question for Bokeh widget callbacks in general. Although there are many examples illustrating the use of normal python functions for callbacks for various Bokeh widget events, they don’t actually end up getting triggered when I’m running the code without the server in jupyter notebook. As a NOOB Bokeh user I’ve assumed that the reason the examples run fine for those posting them and not for me is that they are either not running in a notebook or are using the Bokeh server.

The only way I’ve been able to get any events or updated values into python from the Bokeh widgets is using the CustomJS callback and in that JS script use IPython.notebook.kernel.execute to set a python variable and/or execute a python function. As with Kevad’s question, I would love to find a way (that works static in a notebook) to basically do what we can do with ipywidgets and simply define and assign a python function that responds to various events such as on_changed or on_clicked without having to write javascript “wrapper” code for every one.

The push_notebook() functions seems to address part of the problem, i.e. getting getting information on events or data from python into javascript, but not the triggering of the events or flow of information from javascript to python. (Yuck! I hope that mess of words actually makes sense to someone besides me.)

On Saturday, January 9, 2016 at 6:30:26 AM UTC-7, Kevad wrote:

SO: http://stackoverflow.com/questions/34693892/define-custom-callback-function-bokeh-taptool

Hello,

I have a BarPlot (Not Chart but built from figure) that I am embedding in a Flask app. I want to execute some function every time a bar is clicked upon (via TapTool). May I know how do I do that ?

One way I see is to use TapTool’s callback function like the one shown in docs. But how do I use a custom defined function (Not CustomJs but a normal Python func) instead of say, a OpenUrlCallback Function?
Also, please kindly tell how can I access that @foo kind-of variables in a user defined function ?

Thanks,

Kevad.


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/6d158258-b6ce-4b50-a2a9-3c495f22672d%40continuum.io.

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

Bryan,

I too am intrigued by your statement “Python 3 you can write the callback in Python, and it will get converted to JavaScript” and would love to see an example how to do this.

Greg

···

On Saturday, January 9, 2016 at 8:40:58 AM UTC-7, Jim Sharpe wrote:

Bryan,

Thanks much for the clarification! I think thats very helpful in framing the discussion and sheds light on why there is such variation in examples. In order to help others avoid the confusion I’ve struggled with in the future I think a short writeup on this topic would be of very high value. I know it would have saved me many hours of experimentation.

I’m especially intrigued by your statement *“Python 3 you can write the callback in Python, and it will get converted to JavaScript”. *Can you point me to an example of how this is written? I’m thinking that might do what I need. I don’t really care if it gets converted under the covers, I just would like to avoid having to write the JS myself.

Although I’m sure others will have different situations, but to clarify my need it would be “callbacks in the browser” as I’m running in a python 3.x notebook.

James,

I just tried running your example in a jupyter notebook (python 3.x) with only a couple tweaks - imported bokeh.io output_notebook and called it at the beginning and changed the last line to “show(HBox(inputs))”. Although both the slider and button show up. Nothing happens when I click the button. As a stab in dark I also tried a call to push_notebook() at the end of the run function but that didn’t help.

On Saturday, January 9, 2016 at 8:21:47 AM UTC-7, Bryan Van de ven wrote:

Hi Jim,

I’m just about to hop on a plane so apologies for the brief replay. But we could probably lay out the different callback use-cases a bit more clearly. The cross-language makes for a more than typical number of combinations.

  • Callbacks in the browser

This is CustomJS. In Python 3 you can write the callback in Python, and it will get converted to JavaScript, but the callback ultimately executes as JavaScript, in the browser.

  • Real Python callbacks

This is where you want to call out to real python code (numpy, or scikit-learn, or whatever). Here’s the key observation that sounds obvious but I think bears repeating: this requires a running python interpreter somewhere to run the callback! There are a few possibilities:

  • Use a CustomJS callback that makes an AJAX call out to some REST API that you write. The python code executes in the Flask, or Django, or whatever server. This does not (necessarily) involve the Bokeh server or Bokeh widgets

  • Use Jupyter interactors. The python code executes in a Jupyter python kernel. This is typically in conjunction with push_noteboook. This does not (necessarily) involve the Bokeh server or Bokeh widgets

  • Use a Bokeh server. The python code executes in a Bokeh server. The callbacks are hooked up to Bokeh models with .on_change methods on Bokeh models.

That’s the only options configurations I can think of off the top of my head. Will try to write more later.

Bryan

On Jan 9, 2016, at 8:15 AM, Jim Sharpe [email protected] wrote:

I have a similar question for Bokeh widget callbacks in general. Although there are many examples illustrating the use of normal python functions for callbacks for various Bokeh widget events, they don’t actually end up getting triggered when I’m running the code without the server in jupyter notebook. As a NOOB Bokeh user I’ve assumed that the reason the examples run fine for those posting them and not for me is that they are either not running in a notebook or are using the Bokeh server.

The only way I’ve been able to get any events or updated values into python from the Bokeh widgets is using the CustomJS callback and in that JS script use IPython.notebook.kernel.execute to set a python variable and/or execute a python function. As with Kevad’s question, I would love to find a way (that works static in a notebook) to basically do what we can do with ipywidgets and simply define and assign a python function that responds to various events such as on_changed or on_clicked without having to write javascript “wrapper” code for every one.

The push_notebook() functions seems to address part of the problem, i.e. getting getting information on events or data from python into javascript, but not the triggering of the events or flow of information from javascript to python. (Yuck! I hope that mess of words actually makes sense to someone besides me.)

On Saturday, January 9, 2016 at 6:30:26 AM UTC-7, Kevad wrote:

SO: http://stackoverflow.com/questions/34693892/define-custom-callback-function-bokeh-taptool

Hello,

I have a BarPlot (Not Chart but built from figure) that I am embedding in a Flask app. I want to execute some function every time a bar is clicked upon (via TapTool). May I know how do I do that ?

One way I see is to use TapTool’s callback function like the one shown in docs. But how do I use a custom defined function (Not CustomJs but a normal Python func) instead of say, a OpenUrlCallback Function?
Also, please kindly tell how can I access that @foo kind-of variables in a user defined function ?

Thanks,

Kevad.


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/6d158258-b6ce-4b50-a2a9-3c495f22672d%40continuum.io.

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

Here is the documentation on it:
http://bokeh.pydata.org/en/latest/docs/user_guide/interaction.html#customjs-with-a-python-function

This is using PyScript from Almar Klein (also a bokeh dev):
http://flexx.readthedocs.org/en/latest/pyscript/intro.html#quick-intro

It's very very cool... I'm hoping this feature will definitely cause some
Pythonista's jaws to unhinge... :smiley:

-Peter

···

On Sat, Jan 9, 2016 at 10:13 AM, Greg Nordin <[email protected]> wrote:

Bryan,
I too am intrigued by your statement *"Python 3 you can write the
callback in Python, and it will get converted to JavaScript"* and would
love to see an example how to do this.
Greg

Hi Peter,

That is indeed very cool! I just tried that example in a jupyter python3 notebook and it worked great (unlike all the other python callback examples I tried). The need to install flex and the few extra characters when specifying the callback are a small price to pay for avoiding having to write the JS.

···

On Saturday, January 9, 2016 at 9:22:14 AM UTC-7, pwang wrote:

On Sat, Jan 9, 2016 at 10:13 AM, Greg Nordin [email protected] wrote:

Bryan,
I too am intrigued by your statement “Python 3 you can write the callback in Python, and it will get converted to JavaScript” and would love to see an example how to do this.
Greg

Here is the documentation on it:

http://bokeh.pydata.org/en/latest/docs/user_guide/interaction.html#customjs-with-a-python-function

This is using PyScript from Almar Klein (also a bokeh dev):

http://flexx.readthedocs.org/en/latest/pyscript/intro.html#quick-intro

It’s very very cool… I’m hoping this feature will definitely cause some Pythonista’s jaws to unhinge… :smiley:

-Peter

Peter & Jim,

I just tried it as well, and it is very cool! (For some reason I couldn’t get it to run in a notebook–I got the error ImportError: No module named ‘flexx’ even though I installed flexx and was using the correct env–but it runs fine from the command line: python callback.py).

Can this approach be used with an animation, i.e., using a periodic callback to change the line data values where the callback is python code translated to javascript, without the need for bokeh serve behind it (in other words it’s all in a static html file that can be opened in any browser)?

Thanks,

Greg

···

On Saturday, January 9, 2016 at 9:31:07 AM UTC-7, Jim Sharpe wrote:

Hi Peter,

That is indeed very cool! I just tried that example in a jupyter python3 notebook and it worked great (unlike all the other python callback examples I tried). The need to install flex and the few extra characters when specifying the callback are a small price to pay for avoiding having to write the JS.

On Saturday, January 9, 2016 at 9:22:14 AM UTC-7, pwang wrote:

On Sat, Jan 9, 2016 at 10:13 AM, Greg Nordin [email protected] wrote:

Bryan,
I too am intrigued by your statement “Python 3 you can write the callback in Python, and it will get converted to JavaScript” and would love to see an example how to do this.
Greg

Here is the documentation on it:

http://bokeh.pydata.org/en/latest/docs/user_guide/interaction.html#customjs-with-a-python-function

This is using PyScript from Almar Klein (also a bokeh dev):

http://flexx.readthedocs.org/en/latest/pyscript/intro.html#quick-intro

It’s very very cool… I’m hoping this feature will definitely cause some Pythonista’s jaws to unhinge… :smiley:

-Peter

Greg,

Yes but for the time being you’d have to schedule periodic/timeout callbacks “by hand”. There are two things we’d like to do soon that would make this simpler:

  • lifecycle JS callbacks i.e “on load” etc

  • models for specifying animations, transitions and easing directly from Python.

Neither should be very hard we will just have to see where they fit into the larger set of priorities.

Bryan

···

On Jan 9, 2016, at 11:11, Greg Nordin [email protected] wrote:

Peter & Jim,

I just tried it as well, and it is very cool! (For some reason I couldn’t get it to run in a notebook–I got the error ImportError: No module named ‘flexx’ even though I installed flexx and was using the correct env–but it runs fine from the command line: python callback.py).

Can this approach be used with an animation, i.e., using a periodic callback to change the line data values where the callback is python code translated to javascript, without the need for bokeh serve behind it (in other words it’s all in a static html file that can be opened in any browser)?

Thanks,

Greg

On Saturday, January 9, 2016 at 9:31:07 AM UTC-7, Jim Sharpe wrote:

Hi Peter,

That is indeed very cool! I just tried that example in a jupyter python3 notebook and it worked great (unlike all the other python callback examples I tried). The need to install flex and the few extra characters when specifying the callback are a small price to pay for avoiding having to write the JS.

On Saturday, January 9, 2016 at 9:22:14 AM UTC-7, pwang wrote:

On Sat, Jan 9, 2016 at 10:13 AM, Greg Nordin [email protected] wrote:

Bryan,
I too am intrigued by your statement “Python 3 you can write the callback in Python, and it will get converted to JavaScript” and would love to see an example how to do this.
Greg

Here is the documentation on it:

http://bokeh.pydata.org/en/latest/docs/user_guide/interaction.html#customjs-with-a-python-function

This is using PyScript from Almar Klein (also a bokeh dev):

http://flexx.readthedocs.org/en/latest/pyscript/intro.html#quick-intro

It’s very very cool… I’m hoping this feature will definitely cause some Pythonista’s jaws to unhinge… :smiley:

-Peter

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/0c89d16d-aac0-445d-a64a-7fa4a72253a9%40continuum.io.

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

Hi Bryan,

Something like the “add_periodic_callback()” in line_animate_widget.py in the examples would suffice for what I’m thinking about, which is just animating some lines in a line plot.

Regarding scheduling periodic/timeout callbacks “by hand”, do you mean using something like sleep(0.05) in a python callback, or setting up something in javascript?

Thanks,

Greg

···

On Saturday, January 9, 2016 at 10:15:34 AM UTC-7, Bryan Van de ven wrote:

Greg,

Yes but for the time being you’d have to schedule periodic/timeout callbacks “by hand”. There are two things we’d like to do soon that would make this simpler:

  • lifecycle JS callbacks i.e “on load” etc
  • models for specifying animations, transitions and easing directly from Python.

Neither should be very hard we will just have to see where they fit into the larger set of priorities.

Bryan

On Jan 9, 2016, at 11:11, Greg Nordin [email protected] wrote:

Peter & Jim,

I just tried it as well, and it is very cool! (For some reason I couldn’t get it to run in a notebook–I got the error ImportError: No module named ‘flexx’ even though I installed flexx and was using the correct env–but it runs fine from the command line: python callback.py).

Can this approach be used with an animation, i.e., using a periodic callback to change the line data values where the callback is python code translated to javascript, without the need for bokeh serve behind it (in other words it’s all in a static html file that can be opened in any browser)?

Thanks,

Greg

On Saturday, January 9, 2016 at 9:31:07 AM UTC-7, Jim Sharpe wrote:

Hi Peter,

That is indeed very cool! I just tried that example in a jupyter python3 notebook and it worked great (unlike all the other python callback examples I tried). The need to install flex and the few extra characters when specifying the callback are a small price to pay for avoiding having to write the JS.

On Saturday, January 9, 2016 at 9:22:14 AM UTC-7, pwang wrote:

On Sat, Jan 9, 2016 at 10:13 AM, Greg Nordin [email protected] wrote:

Bryan,
I too am intrigued by your statement “Python 3 you can write the callback in Python, and it will get converted to JavaScript” and would love to see an example how to do this.
Greg

Here is the documentation on it:

http://bokeh.pydata.org/en/latest/docs/user_guide/interaction.html#customjs-with-a-python-function

This is using PyScript from Almar Klein (also a bokeh dev):

http://flexx.readthedocs.org/en/latest/pyscript/intro.html#quick-intro

It’s very very cool… I’m hoping this feature will definitely cause some Pythonista’s jaws to unhinge… :smiley:

-Peter

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/0c89d16d-aac0-445d-a64a-7fa4a72253a9%40continuum.io.

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

Right now it would have to be in JS. Since there are not yet lifecycle callback hooks this probably means:

An existing JS callback has to set up/bootstrap your timer callback, or

Using bokeh.embed to add your own JS directly to the document.

Bryan

···

On Jan 9, 2016, at 11:34, Greg Nordin [email protected] wrote:

Hi Bryan,

Something like the “add_periodic_callback()” in line_animate_widget.py in the examples would suffice for what I’m thinking about, which is just animating some lines in a line plot.

Regarding scheduling periodic/timeout callbacks “by hand”, do you mean using something like sleep(0.05) in a python callback, or setting up something in javascript?

Thanks,

Greg

On Saturday, January 9, 2016 at 10:15:34 AM UTC-7, Bryan Van de ven wrote:

Greg,

Yes but for the time being you’d have to schedule periodic/timeout callbacks “by hand”. There are two things we’d like to do soon that would make this simpler:

  • lifecycle JS callbacks i.e “on load” etc
  • models for specifying animations, transitions and easing directly from Python.

Neither should be very hard we will just have to see where they fit into the larger set of priorities.

Bryan

On Jan 9, 2016, at 11:11, Greg Nordin [email protected] wrote:

Peter & Jim,

I just tried it as well, and it is very cool! (For some reason I couldn’t get it to run in a notebook–I got the error ImportError: No module named ‘flexx’ even though I installed flexx and was using the correct env–but it runs fine from the command line: python callback.py).

Can this approach be used with an animation, i.e., using a periodic callback to change the line data values where the callback is python code translated to javascript, without the need for bokeh serve behind it (in other words it’s all in a static html file that can be opened in any browser)?

Thanks,

Greg

On Saturday, January 9, 2016 at 9:31:07 AM UTC-7, Jim Sharpe wrote:

Hi Peter,

That is indeed very cool! I just tried that example in a jupyter python3 notebook and it worked great (unlike all the other python callback examples I tried). The need to install flex and the few extra characters when specifying the callback are a small price to pay for avoiding having to write the JS.

On Saturday, January 9, 2016 at 9:22:14 AM UTC-7, pwang wrote:

On Sat, Jan 9, 2016 at 10:13 AM, Greg Nordin [email protected] wrote:

Bryan,
I too am intrigued by your statement “Python 3 you can write the callback in Python, and it will get converted to JavaScript” and would love to see an example how to do this.
Greg

Here is the documentation on it:

http://bokeh.pydata.org/en/latest/docs/user_guide/interaction.html#customjs-with-a-python-function

This is using PyScript from Almar Klein (also a bokeh dev):

http://flexx.readthedocs.org/en/latest/pyscript/intro.html#quick-intro

It’s very very cool… I’m hoping this feature will definitely cause some Pythonista’s jaws to unhinge… :smiley:

-Peter

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/0c89d16d-aac0-445d-a64a-7fa4a72253a9%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/4363103d-55a0-446f-a4cf-8078de2b62d7%40continuum.io.

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

I just ran into an apparent snag in using this whizzy new CustomJS.from_py_func(callback) approach. It seems, that while calculating and new data values and updating a (single?) ColumnDataSource works fine in a notebook, it doesn’t seem possible to get any other information out of the callback for other python code to see. For example if all I want to do in the callback for a slider is set a global python variable to the slider value (cb_obj.get(‘value’)), that doesn’t seem to work in a notebook/browser.

···

On Saturday, January 9, 2016 at 10:56:14 AM UTC-7, Bryan Van de ven wrote:

Right now it would have to be in JS. Since there are not yet lifecycle callback hooks this probably means:

An existing JS callback has to set up/bootstrap your timer callback, or

Using bokeh.embed to add your own JS directly to the document.

Bryan

On Jan 9, 2016, at 11:34, Greg Nordin [email protected] wrote:

Hi Bryan,

Something like the “add_periodic_callback()” in line_animate_widget.py in the examples would suffice for what I’m thinking about, which is just animating some lines in a line plot.

Regarding scheduling periodic/timeout callbacks “by hand”, do you mean using something like sleep(0.05) in a python callback, or setting up something in javascript?

Thanks,

Greg

On Saturday, January 9, 2016 at 10:15:34 AM UTC-7, Bryan Van de ven wrote:

Greg,

Yes but for the time being you’d have to schedule periodic/timeout callbacks “by hand”. There are two things we’d like to do soon that would make this simpler:

  • lifecycle JS callbacks i.e “on load” etc
  • models for specifying animations, transitions and easing directly from Python.

Neither should be very hard we will just have to see where they fit into the larger set of priorities.

Bryan

On Jan 9, 2016, at 11:11, Greg Nordin [email protected] wrote:

Peter & Jim,

I just tried it as well, and it is very cool! (For some reason I couldn’t get it to run in a notebook–I got the error ImportError: No module named ‘flexx’ even though I installed flexx and was using the correct env–but it runs fine from the command line: python callback.py).

Can this approach be used with an animation, i.e., using a periodic callback to change the line data values where the callback is python code translated to javascript, without the need for bokeh serve behind it (in other words it’s all in a static html file that can be opened in any browser)?

Thanks,

Greg

On Saturday, January 9, 2016 at 9:31:07 AM UTC-7, Jim Sharpe wrote:

Hi Peter,

That is indeed very cool! I just tried that example in a jupyter python3 notebook and it worked great (unlike all the other python callback examples I tried). The need to install flex and the few extra characters when specifying the callback are a small price to pay for avoiding having to write the JS.

On Saturday, January 9, 2016 at 9:22:14 AM UTC-7, pwang wrote:

On Sat, Jan 9, 2016 at 10:13 AM, Greg Nordin [email protected] wrote:

Bryan,
I too am intrigued by your statement “Python 3 you can write the callback in Python, and it will get converted to JavaScript” and would love to see an example how to do this.
Greg

Here is the documentation on it:

http://bokeh.pydata.org/en/latest/docs/user_guide/interaction.html#customjs-with-a-python-function

This is using PyScript from Almar Klein (also a bokeh dev):

http://flexx.readthedocs.org/en/latest/pyscript/intro.html#quick-intro

It’s very very cool… I’m hoping this feature will definitely cause some Pythonista’s jaws to unhinge… :smiley:

-Peter

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/0c89d16d-aac0-445d-a64a-7fa4a72253a9%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/4363103d-55a0-446f-a4cf-8078de2b62d7%40continuum.io.

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

Hi Jim,

That is not actually a snag it is a fundamental limitation of this particular facility. The python is converted to JavaScript to run in the browser and at that point everything is only in the browser. If you want to affect actual running Python you have to use one of the methods I outlined in another response earlier today: your own rest api, jupyter interactors, or a bokeh server. The other response has more info (apologies I am on a phone right now)

···

On Jan 9, 2016, at 19:35, Jim Sharpe [email protected] wrote:

I just ran into an apparent snag in using this whizzy new CustomJS.from_py_func(callback) approach. It seems, that while calculating and new data values and updating a (single?) ColumnDataSource works fine in a notebook, it doesn’t seem possible to get any other information out of the callback for other python code to see. For example if all I want to do in the callback for a slider is set a global python variable to the slider value (cb_obj.get(‘value’)), that doesn’t seem to work in a notebook/browser.

On Saturday, January 9, 2016 at 10:56:14 AM UTC-7, Bryan Van de ven wrote:

Right now it would have to be in JS. Since there are not yet lifecycle callback hooks this probably means:

An existing JS callback has to set up/bootstrap your timer callback, or

Using bokeh.embed to add your own JS directly to the document.

Bryan

On Jan 9, 2016, at 11:34, Greg Nordin [email protected] wrote:

Hi Bryan,

Something like the “add_periodic_callback()” in line_animate_widget.py in the examples would suffice for what I’m thinking about, which is just animating some lines in a line plot.

Regarding scheduling periodic/timeout callbacks “by hand”, do you mean using something like sleep(0.05) in a python callback, or setting up something in javascript?

Thanks,

Greg

On Saturday, January 9, 2016 at 10:15:34 AM UTC-7, Bryan Van de ven wrote:

Greg,

Yes but for the time being you’d have to schedule periodic/timeout callbacks “by hand”. There are two things we’d like to do soon that would make this simpler:

  • lifecycle JS callbacks i.e “on load” etc
  • models for specifying animations, transitions and easing directly from Python.

Neither should be very hard we will just have to see where they fit into the larger set of priorities.

Bryan

On Jan 9, 2016, at 11:11, Greg Nordin [email protected] wrote:

Peter & Jim,

I just tried it as well, and it is very cool! (For some reason I couldn’t get it to run in a notebook–I got the error ImportError: No module named ‘flexx’ even though I installed flexx and was using the correct env–but it runs fine from the command line: python callback.py).

Can this approach be used with an animation, i.e., using a periodic callback to change the line data values where the callback is python code translated to javascript, without the need for bokeh serve behind it (in other words it’s all in a static html file that can be opened in any browser)?

Thanks,

Greg

On Saturday, January 9, 2016 at 9:31:07 AM UTC-7, Jim Sharpe wrote:

Hi Peter,

That is indeed very cool! I just tried that example in a jupyter python3 notebook and it worked great (unlike all the other python callback examples I tried). The need to install flex and the few extra characters when specifying the callback are a small price to pay for avoiding having to write the JS.

On Saturday, January 9, 2016 at 9:22:14 AM UTC-7, pwang wrote:

On Sat, Jan 9, 2016 at 10:13 AM, Greg Nordin [email protected] wrote:

Bryan,
I too am intrigued by your statement “Python 3 you can write the callback in Python, and it will get converted to JavaScript” and would love to see an example how to do this.
Greg

Here is the documentation on it:

http://bokeh.pydata.org/en/latest/docs/user_guide/interaction.html#customjs-with-a-python-function

This is using PyScript from Almar Klein (also a bokeh dev):

http://flexx.readthedocs.org/en/latest/pyscript/intro.html#quick-intro

It’s very very cool… I’m hoping this feature will definitely cause some Pythonista’s jaws to unhinge… :smiley:

-Peter

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/0c89d16d-aac0-445d-a64a-7fa4a72253a9%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/4363103d-55a0-446f-a4cf-8078de2b62d7%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/079d6059-329c-4353-8327-fad475558dce%40continuum.io.

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

Hi Jim,

That is not actually a snag it is a fundamental limitation of this particular facility. The python is converted to JavaScript to run in the browser and at that point everything is only in the browser. If you want to affect actual running Python you have to use one of the methods I outlined in another response earlier today: your own rest api, jupyter interactors, or a bokeh server. The other response has more info (apologies I am on a phone right now)

···

On Jan 9, 2016, at 19:35, Jim Sharpe [email protected] wrote:

I just ran into an apparent snag in using this whizzy new CustomJS.from_py_func(callback) approach. It seems, that while calculating and new data values and updating a (single?) ColumnDataSource works fine in a notebook, it doesn’t seem possible to get any other information out of the callback for other python code to see. For example if all I want to do in the callback for a slider is set a global python variable to the slider value (cb_obj.get(‘value’)), that doesn’t seem to work in a notebook/browser.

On Saturday, January 9, 2016 at 10:56:14 AM UTC-7, Bryan Van de ven wrote:

Right now it would have to be in JS. Since there are not yet lifecycle callback hooks this probably means:

An existing JS callback has to set up/bootstrap your timer callback, or

Using bokeh.embed to add your own JS directly to the document.

Bryan

On Jan 9, 2016, at 11:34, Greg Nordin [email protected] wrote:

Hi Bryan,

Something like the “add_periodic_callback()” in line_animate_widget.py in the examples would suffice for what I’m thinking about, which is just animating some lines in a line plot.

Regarding scheduling periodic/timeout callbacks “by hand”, do you mean using something like sleep(0.05) in a python callback, or setting up something in javascript?

Thanks,

Greg

On Saturday, January 9, 2016 at 10:15:34 AM UTC-7, Bryan Van de ven wrote:

Greg,

Yes but for the time being you’d have to schedule periodic/timeout callbacks “by hand”. There are two things we’d like to do soon that would make this simpler:

  • lifecycle JS callbacks i.e “on load” etc
  • models for specifying animations, transitions and easing directly from Python.

Neither should be very hard we will just have to see where they fit into the larger set of priorities.

Bryan

On Jan 9, 2016, at 11:11, Greg Nordin [email protected] wrote:

Peter & Jim,

I just tried it as well, and it is very cool! (For some reason I couldn’t get it to run in a notebook–I got the error ImportError: No module named ‘flexx’ even though I installed flexx and was using the correct env–but it runs fine from the command line: python callback.py).

Can this approach be used with an animation, i.e., using a periodic callback to change the line data values where the callback is python code translated to javascript, without the need for bokeh serve behind it (in other words it’s all in a static html file that can be opened in any browser)?

Thanks,

Greg

On Saturday, January 9, 2016 at 9:31:07 AM UTC-7, Jim Sharpe wrote:

Hi Peter,

That is indeed very cool! I just tried that example in a jupyter python3 notebook and it worked great (unlike all the other python callback examples I tried). The need to install flex and the few extra characters when specifying the callback are a small price to pay for avoiding having to write the JS.

On Saturday, January 9, 2016 at 9:22:14 AM UTC-7, pwang wrote:

On Sat, Jan 9, 2016 at 10:13 AM, Greg Nordin [email protected] wrote:

Bryan,
I too am intrigued by your statement “Python 3 you can write the callback in Python, and it will get converted to JavaScript” and would love to see an example how to do this.
Greg

Here is the documentation on it:

http://bokeh.pydata.org/en/latest/docs/user_guide/interaction.html#customjs-with-a-python-function

This is using PyScript from Almar Klein (also a bokeh dev):

http://flexx.readthedocs.org/en/latest/pyscript/intro.html#quick-intro

It’s very very cool… I’m hoping this feature will definitely cause some Pythonista’s jaws to unhinge… :smiley:

-Peter

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/0c89d16d-aac0-445d-a64a-7fa4a72253a9%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/4363103d-55a0-446f-a4cf-8078de2b62d7%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/079d6059-329c-4353-8327-fad475558dce%40continuum.io.

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

Hi Bryan,

I really appreciate timely responses to our queries. It makes me even more comfortable using Bokeh in additional places.

Of the various options you described in one of the earlier messages, executing the python in the jupyter kernel is exactly what we need. I think I understand the role of push_notebook but think I’m still missing something in my understanding of how that overall process works. If I update the ColumnDataSource in the callback and then call push_notebook I do see the plot running in the notebook update. But that only seems to work for updating plots. Any changes outside the Bokeh components, such as setting a variable don’t seem to get exposed to the python kernel.

As a bit of background, the use case I’m working on involves a bunch of widgets to collect information for a query to MongoDB, the results of which will eventually end up getting displayed in Bokeh plots and/or tables. I basically need to wait to submit the query until after all the values in the widgets have been set and then “hit the go button”. Both the query and the subsequent processing that gets performed to transform the data for display in is all in python (as opposed to JS) running in the jupyter kernel, so it would be more convenient to also keep the callback code in python as well. Although I have created a separate version of the application that uses ipywidgets that works just fine, the Bokeh widgets look more appealing. For the ipywidget version, I basically use a shared callback to get all the widget values used to create the query and then the event from a button to fire it. I was hoping to use the same general approach with Bokeh but am open to other options.

···

On Saturday, January 9, 2016 at 7:20:39 PM UTC-7, Bryan Van de ven wrote:

Hi Jim,

That is not actually a snag it is a fundamental limitation of this particular facility. The python is converted to JavaScript to run in the browser and at that point everything is only in the browser. If you want to affect actual running Python you have to use one of the methods I outlined in another response earlier today: your own rest api, jupyter interactors, or a bokeh server. The other response has more info (apologies I am on a phone right now)

On Jan 9, 2016, at 19:35, Jim Sharpe [email protected] wrote:

Right now it would have to be in JS. Since there are not yet lifecycle callback hooks this probably means:

An existing JS callback has to set up/bootstrap your timer callback, or

Using bokeh.embed to add your own JS directly to the document.

Bryan

On Jan 9, 2016, at 11:34, Greg Nordin [email protected] wrote:

Hi Bryan,

Something like the “add_periodic_callback()” in line_animate_widget.py in the examples would suffice for what I’m thinking about, which is just animating some lines in a line plot.

Regarding scheduling periodic/timeout callbacks “by hand”, do you mean using something like sleep(0.05) in a python callback, or setting up something in javascript?

Thanks,

Greg

On Saturday, January 9, 2016 at 10:15:34 AM UTC-7, Bryan Van de ven wrote:

Greg,

Yes but for the time being you’d have to schedule periodic/timeout callbacks “by hand”. There are two things we’d like to do soon that would make this simpler:

  • lifecycle JS callbacks i.e “on load” etc
  • models for specifying animations, transitions and easing directly from Python.

Neither should be very hard we will just have to see where they fit into the larger set of priorities.

Bryan

On Jan 9, 2016, at 11:11, Greg Nordin [email protected] wrote:

Peter & Jim,

I just tried it as well, and it is very cool! (For some reason I couldn’t get it to run in a notebook–I got the error ImportError: No module named ‘flexx’ even though I installed flexx and was using the correct env–but it runs fine from the command line: python callback.py).

Can this approach be used with an animation, i.e., using a periodic callback to change the line data values where the callback is python code translated to javascript, without the need for bokeh serve behind it (in other words it’s all in a static html file that can be opened in any browser)?

Thanks,

Greg

On Saturday, January 9, 2016 at 9:31:07 AM UTC-7, Jim Sharpe wrote:

Hi Peter,

That is indeed very cool! I just tried that example in a jupyter python3 notebook and it worked great (unlike all the other python callback examples I tried). The need to install flex and the few extra characters when specifying the callback are a small price to pay for avoiding having to write the JS.

On Saturday, January 9, 2016 at 9:22:14 AM UTC-7, pwang wrote:

On Sat, Jan 9, 2016 at 10:13 AM, Greg Nordin [email protected] wrote:

Bryan,
I too am intrigued by your statement “Python 3 you can write the callback in Python, and it will get converted to JavaScript” and would love to see an example how to do this.
Greg

Here is the documentation on it:

http://bokeh.pydata.org/en/latest/docs/user_guide/interaction.html#customjs-with-a-python-function

This is using PyScript from Almar Klein (also a bokeh dev):

http://flexx.readthedocs.org/en/latest/pyscript/intro.html#quick-intro

It’s very very cool… I’m hoping this feature will definitely cause some Pythonista’s jaws to unhinge… :smiley:

-Peter

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/0c89d16d-aac0-445d-a64a-7fa4a72253a9%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/4363103d-55a0-446f-a4cf-8078de2b62d7%40continuum.io.

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

I just ran into an apparent snag in using this whizzy new CustomJS.from_py_func(callback) approach. It seems, that while calculating and new data values and updating a (single?) ColumnDataSource works fine in a notebook, it doesn’t seem possible to get any other information out of the callback for other python code to see. For example if all I want to do in the callback for a slider is set a global python variable to the slider value (cb_obj.get(‘value’)), that doesn’t seem to work in a notebook/browser.

On Saturday, January 9, 2016 at 10:56:14 AM UTC-7, Bryan Van de ven wrote:

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/079d6059-329c-4353-8327-fad475558dce%40continuum.io.

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

Hi Jim,

Thanks for the kind words.

I mentioned I was in a hurry before catching flight earlier, so I may have spoken a bit broadly. Let me clarify the situation with notebooks specifically, what is possible now and what would be possible with a little work.

- push_notebook can update basically any property attribute on any Bokeh model (so not just data sources) but as you note it only pushed from python to BokehJS right now. In case details are interesting: every "show" in the notebook sets up a Jupyter comms object that can push Bokeh protocol messages to BokehJS, which processes the messages to update that plot.

- a last minute bug currently means push_notebook only works on the last "shown" plot (comm handles for updating arbitrary cells output should be fixed and in a dev build in the next week)

- In my earlier email, for python callbacks, I had in mind Jupyter interactors (not Bokeh widgets). So, you can have widgets like dropdowns, sliders, buttons, etc that trigger python code to be called (which could then call push_notebook to update a plot, e.g.)

So, putting all that together: if you just need widgets to drive python code, to then drive push_notebook to update a plot, everything you need should be in place now. What is *not* present right now (at least not in any reasonable way) is to have events like range changes and selections from plot tools inform python code in the notebook. What I'd like to do in the near future is a refactor that basically makes the notebook comms case and the bokeh server machinery identical. Right now parts are similar, but they could still share more implementation. Apart from making maintenance simpler (by having less code paths), I think it should open up the possibility of getting events "out" of plots to trigger notebook callbacks.

call push_notebook I do see the plot running in the notebook update. But that only seems to work for updating plots. Any changes outside the Bokeh components, such as setting a variable don't seem to get exposed to the python kernel.

Are you setting a variable in the callback function? Since all python function variables are local by default, if you want a change in the callback to "escape" the callback, you'd probably have to use "global myfoo" in order to be able update a "myfoo" variable outside the callback. I've also seen people make mutating updates to dictionaries created outside the function, to simulate "global". Both methods are both a bit gorpy but I'm not sure there's any better simple ways.

Bryan

···

On Jan 10, 2016, at 2:09 AM, Jim Sharpe <[email protected]> wrote:

Hi Bryan,

I really appreciate timely responses to our queries. It makes me even more comfortable using Bokeh in additional places.

Of the various options you described in one of the earlier messages, executing the python in the jupyter kernel is exactly what we need. I think I understand the role of push_notebook but think I'm still missing something in my understanding of how that overall process works. If I update the ColumnDataSource in the callback and then call push_notebook I do see the plot running in the notebook update. But that only seems to work for updating plots. Any changes outside the Bokeh components, such as setting a variable don't seem to get exposed to the python kernel.

As a bit of background, the use case I'm working on involves a bunch of widgets to collect information for a query to MongoDB, the results of which will eventually end up getting displayed in Bokeh plots and/or tables. I basically need to wait to submit the query until after all the values in the widgets have been set and then "hit the go button". Both the query and the subsequent processing that gets performed to transform the data for display in is all in python (as opposed to JS) running in the jupyter kernel, so it would be more convenient to also keep the callback code in python as well. Although I have created a separate version of the application that uses ipywidgets that works just fine, the Bokeh widgets look more appealing. For the ipywidget version, I basically use a shared callback to get all the widget values used to create the query and then the event from a button to fire it. I was hoping to use the same general approach with Bokeh but am open to other options.

On Saturday, January 9, 2016 at 7:20:39 PM UTC-7, Bryan Van de ven wrote:
Hi Jim,

That is not actually a snag it is a fundamental limitation of this particular facility. The python is converted to JavaScript to run in the browser and at that point everything is *only* in the browser. If you want to affect actual running Python you have to use one of the methods I outlined in another response earlier today: your own rest api, jupyter interactors, or a bokeh server. The other response has more info (apologies I am on a phone right now)

On Jan 9, 2016, at 19:35, Jim Sharpe <[email protected]> wrote:

I just ran into an apparent snag in using this whizzy new CustomJS.from_py_func(callback) approach. It seems, that while calculating and new data values and updating a (single?) ColumnDataSource works fine in a notebook, it doesn't seem possible to get any other information out of the callback for other python code to see. For example if all I want to do in the callback for a slider is set a global python variable to the slider value (cb_obj.get('value')), that doesn't seem to work in a notebook/browser.

On Saturday, January 9, 2016 at 10:56:14 AM UTC-7, Bryan Van de ven wrote:
Right now it would have to be in JS. Since there are not yet lifecycle callback hooks this probably means:

An existing JS callback has to set up/bootstrap your timer callback, or

Using bokeh.embed to add your own JS directly to the document.

Bryan

On Jan 9, 2016, at 11:34, Greg Nordin <[email protected]> wrote:

Hi Bryan,

Something like the "add_periodic_callback()" in line_animate_widget.py in the examples would suffice for what I'm thinking about, which is just animating some lines in a line plot.

Regarding scheduling periodic/timeout callbacks "by hand", do you mean using something like sleep(0.05) in a python callback, or setting up something in javascript?

Thanks,
Greg

On Saturday, January 9, 2016 at 10:15:34 AM UTC-7, Bryan Van de ven wrote:
Greg,

Yes but for the time being you'd have to schedule periodic/timeout callbacks "by hand". There are two things we'd like to do soon that would make this simpler:

* lifecycle JS callbacks i.e "on load" etc

* models for specifying animations, transitions and easing directly from Python.

Neither should be very hard we will just have to see where they fit into the larger set of priorities.

Bryan

On Jan 9, 2016, at 11:11, Greg Nordin <[email protected]> wrote:

Peter & Jim,

I just tried it as well, and it is very cool! (For some reason I couldn't get it to run in a notebook--I got the error ImportError: No module named 'flexx' even though I installed flexx and was using the correct env--but it runs fine from the command line: `python callback.py`).

Can this approach be used with an animation, i.e., using a periodic callback to change the line data values where the callback is python code translated to javascript, without the need for bokeh serve behind it (in other words it's all in a static html file that can be opened in any browser)?

Thanks,
Greg

On Saturday, January 9, 2016 at 9:31:07 AM UTC-7, Jim Sharpe wrote:
Hi Peter,

That is indeed very cool! I just tried that example in a jupyter python3 notebook and it worked great (unlike *all* the other python callback examples I tried). The need to install flex and the few extra characters when specifying the callback are a small price to pay for avoiding having to write the JS.

On Saturday, January 9, 2016 at 9:22:14 AM UTC-7, pwang wrote:
On Sat, Jan 9, 2016 at 10:13 AM, Greg Nordin <[email protected]> wrote:
Bryan,
I too am intrigued by your statement "Python 3 you can write the callback in Python, and it will get converted to JavaScript" and would love to see an example how to do this.
Greg

Here is the documentation on it:
http://bokeh.pydata.org/en/latest/docs/user_guide/interaction.html#customjs-with-a-python-function

This is using PyScript from Almar Klein (also a bokeh dev):
http://flexx.readthedocs.org/en/latest/pyscript/intro.html#quick-intro

It's very very cool... I'm hoping this feature will definitely cause some Pythonista's jaws to unhinge... :smiley:

-Peter

--
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/0c89d16d-aac0-445d-a64a-7fa4a72253a9%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/4363103d-55a0-446f-a4cf-8078de2b62d7%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/079d6059-329c-4353-8327-fad475558dce%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/c9874d7f-3d78-43e9-906e-253399485a67%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Hi Bryan,

From this most recent post and, several others leading up to it ,the following stripped down version of the example should actually work in a juypter notebook. However the behavior I see is that the python variable foo never changes from 0. I did think of “misusing” a ColumnDataSource to export values to python but was hoping there was a better way. Sorry if I’m being dense and missing something obvious.

···

from bokeh.io import output_notebook, show, vform

from bokeh.models import CustomJS, ColumnDataSource, Slider

from bokeh.plotting import Figure, output_file, show

output_notebook()

x = [x*0.005 for x in range(0, 200)]

y = x

foo = 0

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

def callback(source=source):

global foo

foo = cb_obj.get(‘value’)

push_notebook()

slider = Slider(start=0.1, end=4, value=1, step=.1, title=“power”, callback=CustomJS.from_py_func(callback))

layout = vform(slider)

show(layout)

… and then in a following cell:

print(foo)


Of the things that aren’t currently possible, but might be in the future, the one I’m especially interested in is to have selection changes in Bokeh plots trigger callbacks in python. One of my primary use cases involves a chain of selections made on Bokeh components. For example the selection on scatter plot is used to populate the rows of a table. Then a selection on the table is used to populate a bunch of line charts. One thing that complicates doing this now is that there is python code that processes each stage of selection data to create the content for the subsequent components. I have all this working today except the automatic triggering part. For that I have to “manually” execute cells after each selection.

On Sunday, January 10, 2016 at 9:58:51 AM UTC-7, Bryan Van de ven wrote:

Hi Jim,

Thanks for the kind words.

I mentioned I was in a hurry before catching flight earlier, so I may have spoken a bit broadly. Let me clarify the situation with notebooks specifically, what is possible now and what would be possible with a little work.

  • push_notebook can update basically any property attribute on any Bokeh model (so not just data sources) but as you note it only pushed from python to BokehJS right now. In case details are interesting: every “show” in the notebook sets up a Jupyter comms object that can push Bokeh protocol messages to BokehJS, which processes the messages to update that plot.

  • a last minute bug currently means push_notebook only works on the last “shown” plot (comm handles for updating arbitrary cells output should be fixed and in a dev build in the next week)

  • In my earlier email, for python callbacks, I had in mind Jupyter interactors (not Bokeh widgets). So, you can have widgets like dropdowns, sliders, buttons, etc that trigger python code to be called (which could then call push_notebook to update a plot, e.g.)

So, putting all that together: if you just need widgets to drive python code, to then drive push_notebook to update a plot, everything you need should be in place now. What is not present right now (at least not in any reasonable way) is to have events like range changes and selections from plot tools inform python code in the notebook. What I’d like to do in the near future is a refactor that basically makes the notebook comms case and the bokeh server machinery identical. Right now parts are similar, but they could still share more implementation. Apart from making maintenance simpler (by having less code paths), I think it should open up the possibility of getting events “out” of plots to trigger notebook callbacks.

call push_notebook I do see the plot running in the notebook update. But that only seems to work for updating plots. Any changes outside the Bokeh components, such as setting a variable don’t seem to get exposed to the python kernel.

Are you setting a variable in the callback function? Since all python function variables are local by default, if you want a change in the callback to “escape” the callback, you’d probably have to use “global myfoo” in order to be able update a “myfoo” variable outside the callback. I’ve also seen people make mutating updates to dictionaries created outside the function, to simulate “global”. Both methods are both a bit gorpy but I’m not sure there’s any better simple ways.

Bryan

On Jan 10, 2016, at 2:09 AM, Jim Sharpe [email protected] wrote:

Hi Bryan,

I really appreciate timely responses to our queries. It makes me even more comfortable using Bokeh in additional places.

Of the various options you described in one of the earlier messages, executing the python in the jupyter kernel is exactly what we need. I think I understand the role of push_notebook but think I’m still missing something in my understanding of how that overall process works. If I update the ColumnDataSource in the callback and then call push_notebook I do see the plot running in the notebook update. But that only seems to work for updating plots. Any changes outside the Bokeh components, such as setting a variable don’t seem to get exposed to the python kernel.

As a bit of background, the use case I’m working on involves a bunch of widgets to collect information for a query to MongoDB, the results of which will eventually end up getting displayed in Bokeh plots and/or tables. I basically need to wait to submit the query until after all the values in the widgets have been set and then “hit the go button”. Both the query and the subsequent processing that gets performed to transform the data for display in is all in python (as opposed to JS) running in the jupyter kernel, so it would be more convenient to also keep the callback code in python as well. Although I have created a separate version of the application that uses ipywidgets that works just fine, the Bokeh widgets look more appealing. For the ipywidget version, I basically use a shared callback to get all the widget values used to create the query and then the event from a button to fire it. I was hoping to use the same general approach with Bokeh but am open to other options.

On Saturday, January 9, 2016 at 7:20:39 PM UTC-7, Bryan Van de ven wrote:

Hi Jim,

That is not actually a snag it is a fundamental limitation of this particular facility. The python is converted to JavaScript to run in the browser and at that point everything is only in the browser. If you want to affect actual running Python you have to use one of the methods I outlined in another response earlier today: your own rest api, jupyter interactors, or a bokeh server. The other response has more info (apologies I am on a phone right now)

On Jan 9, 2016, at 19:35, Jim Sharpe [email protected] wrote:

I just ran into an apparent snag in using this whizzy new CustomJS.from_py_func(callback) approach. It seems, that while calculating and new data values and updating a (single?) ColumnDataSource works fine in a notebook, it doesn’t seem possible to get any other information out of the callback for other python code to see. For example if all I want to do in the callback for a slider is set a global python variable to the slider value (cb_obj.get(‘value’)), that doesn’t seem to work in a notebook/browser.

On Saturday, January 9, 2016 at 10:56:14 AM UTC-7, Bryan Van de ven wrote:

Right now it would have to be in JS. Since there are not yet lifecycle callback hooks this probably means:

An existing JS callback has to set up/bootstrap your timer callback, or

Using bokeh.embed to add your own JS directly to the document.

Bryan

On Jan 9, 2016, at 11:34, Greg Nordin [email protected] wrote:

Hi Bryan,

Something like the “add_periodic_callback()” in line_animate_widget.py in the examples would suffice for what I’m thinking about, which is just animating some lines in a line plot.

Regarding scheduling periodic/timeout callbacks “by hand”, do you mean using something like sleep(0.05) in a python callback, or setting up something in javascript?

Thanks,

Greg

On Saturday, January 9, 2016 at 10:15:34 AM UTC-7, Bryan Van de ven wrote:

Greg,

Yes but for the time being you’d have to schedule periodic/timeout callbacks “by hand”. There are two things we’d like to do soon that would make this simpler:

  • lifecycle JS callbacks i.e “on load” etc
  • models for specifying animations, transitions and easing directly from Python.

Neither should be very hard we will just have to see where they fit into the larger set of priorities.

Bryan

On Jan 9, 2016, at 11:11, Greg Nordin [email protected] wrote:

Peter & Jim,

I just tried it as well, and it is very cool! (For some reason I couldn’t get it to run in a notebook–I got the error ImportError: No module named ‘flexx’ even though I installed flexx and was using the correct env–but it runs fine from the command line: python callback.py).

Can this approach be used with an animation, i.e., using a periodic callback to change the line data values where the callback is python code translated to javascript, without the need for bokeh serve behind it (in other words it’s all in a static html file that can be opened in any browser)?

Thanks,

Greg

On Saturday, January 9, 2016 at 9:31:07 AM UTC-7, Jim Sharpe wrote:

Hi Peter,

That is indeed very cool! I just tried that example in a jupyter python3 notebook and it worked great (unlike all the other python callback examples I tried). The need to install flex and the few extra characters when specifying the callback are a small price to pay for avoiding having to write the JS.

On Saturday, January 9, 2016 at 9:22:14 AM UTC-7, pwang wrote:

On Sat, Jan 9, 2016 at 10:13 AM, Greg Nordin [email protected] wrote:

Bryan,

I too am intrigued by your statement “Python 3 you can write the callback in Python, and it will get converted to JavaScript” and would love to see an example how to do this.

Greg

Here is the documentation on it:

http://bokeh.pydata.org/en/latest/docs/user_guide/interaction.html#customjs-with-a-python-function

This is using PyScript from Almar Klein (also a bokeh dev):

http://flexx.readthedocs.org/en/latest/pyscript/intro.html#quick-intro

It’s very very cool… I’m hoping this feature will definitely cause some Pythonista’s jaws to unhinge… :smiley:

-Peter


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/0c89d16d-aac0-445d-a64a-7fa4a72253a9%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/4363103d-55a0-446f-a4cf-8078de2b62d7%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/079d6059-329c-4353-8327-fad475558dce%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/c9874d7f-3d78-43e9-906e-253399485a67%40continuum.io.

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

Jim,

Not at all, this is actually very instructive and useful, and I intend to write up a good deal of the information from this thread in the main docs.

There is definitely one aspect I have not conveyed well, and that is that:

   callback=CustomJS.from_py_func(callback)

creates a *JavaScript* callback, by "compiling" the python into JS. Being able to write it by giving python is intended as a convenience, so that people can "write JS callbacks without having to write JS". But the main point to bear in mind is that there is never any python that gets executed when you use "CustomJS", and this is why "foo" is never updated --- it's updating a "foo" variable in the browser JS interpreter, because that is where the callback is run (not in an ipython kernel).

To execute python code without a Bokeh Server, you will need to use "Jupyter interactors" This is a different set of widgets that Jupyter notebooks provide (different from Bokeh widgets) that you can attach real python callbacks to, that get exectued in the ipython kernel. It probably would have been more instructive for me to link to an actual example from the start. You can take a look at this one:

  https://github.com/bokeh/bokeh/blob/master/examples/plotting/notebook/interact_basic.ipynb

(note the location of this notebook may change soon, we are going to re-organize our examples). They key parts to note are these, first a real python callback something like:

  def update(f, w=1, A=1, phi=0):
    if f == "sin": func = np.sin
    elif f == "cos": func = np.cos
    elif f == "tan": func = np.tan
    r.data_source.data['y'] = A * func(w * x + phi),
    push_notebook()

and then the Juptyter "interact" function, that auto-creates a GUI for a set of input parameters for the callback:

  from ipywidgets import interact

  interact(update, f=["sin", "cos", "tan"], w=(0,100), A=(1,5), phi=(0, 20, 0.1))

I believe it it possible to have finer control over the exact widgets that Jupypter uses, but that is beyond my notebook knowledge. The "auto-generated" GUI is generally fairly nice. The one above will have a dropdown select box for "f" and three sliders for the other ranges.

I hope this clears things up a bit more, thanks for your patience,

Bryan

···

On Jan 10, 2016, at 11:39 AM, Jim Sharpe <[email protected]> wrote:

Hi Bryan,

From this most recent post and, several others leading up to it ,the following stripped down version of the example should actually work in a juypter notebook. However the behavior I see is that the python variable foo never changes from 0. I did think of "misusing" a ColumnDataSource to export values to python but was hoping there was a better way. Sorry if I'm being dense and missing something obvious.

---------

from bokeh.io import output_notebook, show, vform
from bokeh.models import CustomJS, ColumnDataSource, Slider
from bokeh.plotting import Figure, output_file, show

output_notebook()

x = [x*0.005 for x in range(0, 200)]
y = x
foo = 0
source = ColumnDataSource(data=dict(x=x, y=y))

def callback(source=source):
    global foo
    foo = cb_obj.get('value')
    push_notebook()

slider = Slider(start=0.1, end=4, value=1, step=.1, title="power", callback=CustomJS.from_py_func(callback))

layout = vform(slider)
show(layout)

... and then in a following cell:

print(foo)

-------------------------

Of the things that aren't currently possible, but might be in the future, the one I'm especially interested in is to have selection changes in Bokeh plots trigger callbacks in python. One of my primary use cases involves a chain of selections made on Bokeh components. For example the selection on scatter plot is used to populate the rows of a table. Then a selection on the table is used to populate a bunch of line charts. One thing that complicates doing this now is that there is python code that processes each stage of selection data to create the content for the subsequent components. I have all this working today except the automatic triggering part. For that I have to "manually" execute cells after each selection.

On Sunday, January 10, 2016 at 9:58:51 AM UTC-7, Bryan Van de ven wrote:
Hi Jim,

Thanks for the kind words.

I mentioned I was in a hurry before catching flight earlier, so I may have spoken a bit broadly. Let me clarify the situation with notebooks specifically, what is possible now and what would be possible with a little work.

- push_notebook can update basically any property attribute on any Bokeh model (so not just data sources) but as you note it only pushed from python to BokehJS right now. In case details are interesting: every "show" in the notebook sets up a Jupyter comms object that can push Bokeh protocol messages to BokehJS, which processes the messages to update that plot.

- a last minute bug currently means push_notebook only works on the last "shown" plot (comm handles for updating arbitrary cells output should be fixed and in a dev build in the next week)

- In my earlier email, for python callbacks, I had in mind Jupyter interactors (not Bokeh widgets). So, you can have widgets like dropdowns, sliders, buttons, etc that trigger python code to be called (which could then call push_notebook to update a plot, e.g.)

So, putting all that together: if you just need widgets to drive python code, to then drive push_notebook to update a plot, everything you need should be in place now. What is *not* present right now (at least not in any reasonable way) is to have events like range changes and selections from plot tools inform python code in the notebook. What I'd like to do in the near future is a refactor that basically makes the notebook comms case and the bokeh server machinery identical. Right now parts are similar, but they could still share more implementation. Apart from making maintenance simpler (by having less code paths), I think it should open up the possibility of getting events "out" of plots to trigger notebook callbacks.

> call push_notebook I do see the plot running in the notebook update. But that only seems to work for updating plots. Any changes outside the Bokeh components, such as setting a variable don't seem to get exposed to the python kernel.

Are you setting a variable in the callback function? Since all python function variables are local by default, if you want a change in the callback to "escape" the callback, you'd probably have to use "global myfoo" in order to be able update a "myfoo" variable outside the callback. I've also seen people make mutating updates to dictionaries created outside the function, to simulate "global". Both methods are both a bit gorpy but I'm not sure there's any better simple ways.

Bryan

> On Jan 10, 2016, at 2:09 AM, Jim Sharpe <[email protected]> wrote:
>
> Hi Bryan,
>
> I really appreciate timely responses to our queries. It makes me even more comfortable using Bokeh in additional places.
>
> Of the various options you described in one of the earlier messages, executing the python in the jupyter kernel is exactly what we need. I think I understand the role of push_notebook but think I'm still missing something in my understanding of how that overall process works. If I update the ColumnDataSource in the callback and then call push_notebook I do see the plot running in the notebook update. But that only seems to work for updating plots. Any changes outside the Bokeh components, such as setting a variable don't seem to get exposed to the python kernel.
>
> As a bit of background, the use case I'm working on involves a bunch of widgets to collect information for a query to MongoDB, the results of which will eventually end up getting displayed in Bokeh plots and/or tables. I basically need to wait to submit the query until after all the values in the widgets have been set and then "hit the go button". Both the query and the subsequent processing that gets performed to transform the data for display in is all in python (as opposed to JS) running in the jupyter kernel, so it would be more convenient to also keep the callback code in python as well. Although I have created a separate version of the application that uses ipywidgets that works just fine, the Bokeh widgets look more appealing. For the ipywidget version, I basically use a shared callback to get all the widget values used to create the query and then the event from a button to fire it. I was hoping to use the same general approach with Bokeh but am open to other options.
>
> On Saturday, January 9, 2016 at 7:20:39 PM UTC-7, Bryan Van de ven wrote:
> Hi Jim,
>
> That is not actually a snag it is a fundamental limitation of this particular facility. The python is converted to JavaScript to run in the browser and at that point everything is *only* in the browser. If you want to affect actual running Python you have to use one of the methods I outlined in another response earlier today: your own rest api, jupyter interactors, or a bokeh server. The other response has more info (apologies I am on a phone right now)
>
> On Jan 9, 2016, at 19:35, Jim Sharpe <[email protected]> wrote:
>
>> I just ran into an apparent snag in using this whizzy new CustomJS.from_py_func(callback) approach. It seems, that while calculating and new data values and updating a (single?) ColumnDataSource works fine in a notebook, it doesn't seem possible to get any other information out of the callback for other python code to see. For example if all I want to do in the callback for a slider is set a global python variable to the slider value (cb_obj.get('value')), that doesn't seem to work in a notebook/browser.
>>
>> On Saturday, January 9, 2016 at 10:56:14 AM UTC-7, Bryan Van de ven wrote:
>> Right now it would have to be in JS. Since there are not yet lifecycle callback hooks this probably means:
>>
>> An existing JS callback has to set up/bootstrap your timer callback, or
>>
>> Using bokeh.embed to add your own JS directly to the document.
>>
>> Bryan
>>
>> On Jan 9, 2016, at 11:34, Greg Nordin <[email protected]> wrote:
>>
>>> Hi Bryan,
>>>
>>> Something like the "add_periodic_callback()" in line_animate_widget.py in the examples would suffice for what I'm thinking about, which is just animating some lines in a line plot.
>>>
>>> Regarding scheduling periodic/timeout callbacks "by hand", do you mean using something like sleep(0.05) in a python callback, or setting up something in javascript?
>>>
>>> Thanks,
>>> Greg
>>>
>>> On Saturday, January 9, 2016 at 10:15:34 AM UTC-7, Bryan Van de ven wrote:
>>> Greg,
>>>
>>> Yes but for the time being you'd have to schedule periodic/timeout callbacks "by hand". There are two things we'd like to do soon that would make this simpler:
>>>
>>> * lifecycle JS callbacks i.e "on load" etc
>>>
>>> * models for specifying animations, transitions and easing directly from Python.
>>>
>>> Neither should be very hard we will just have to see where they fit into the larger set of priorities.
>>>
>>> Bryan
>>>
>>> On Jan 9, 2016, at 11:11, Greg Nordin <[email protected]> wrote:
>>>
>>>> Peter & Jim,
>>>>
>>>> I just tried it as well, and it is very cool! (For some reason I couldn't get it to run in a notebook--I got the error ImportError: No module named 'flexx' even though I installed flexx and was using the correct env--but it runs fine from the command line: `python callback.py`).
>>>>
>>>> Can this approach be used with an animation, i.e., using a periodic callback to change the line data values where the callback is python code translated to javascript, without the need for bokeh serve behind it (in other words it's all in a static html file that can be opened in any browser)?
>>>>
>>>> Thanks,
>>>> Greg
>>>>
>>>> On Saturday, January 9, 2016 at 9:31:07 AM UTC-7, Jim Sharpe wrote:
>>>> Hi Peter,
>>>>
>>>> That is indeed very cool! I just tried that example in a jupyter python3 notebook and it worked great (unlike *all* the other python callback examples I tried). The need to install flex and the few extra characters when specifying the callback are a small price to pay for avoiding having to write the JS.
>>>>
>>>> On Saturday, January 9, 2016 at 9:22:14 AM UTC-7, pwang wrote:
>>>> On Sat, Jan 9, 2016 at 10:13 AM, Greg Nordin <[email protected]> wrote:
>>>> Bryan,
>>>> I too am intrigued by your statement "Python 3 you can write the callback in Python, and it will get converted to JavaScript" and would love to see an example how to do this.
>>>> Greg
>>>>
>>>> Here is the documentation on it:
>>>> http://bokeh.pydata.org/en/latest/docs/user_guide/interaction.html#customjs-with-a-python-function
>>>>
>>>> This is using PyScript from Almar Klein (also a bokeh dev):
>>>> http://flexx.readthedocs.org/en/latest/pyscript/intro.html#quick-intro
>>>>
>>>> It's very very cool... I'm hoping this feature will definitely cause some Pythonista's jaws to unhinge... :smiley:
>>>>
>>>>
>>>> -Peter
>>>>
>>>>
>>>> --
>>>> 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/0c89d16d-aac0-445d-a64a-7fa4a72253a9%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/4363103d-55a0-446f-a4cf-8078de2b62d7%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/079d6059-329c-4353-8327-fad475558dce%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/c9874d7f-3d78-43e9-906e-253399485a67%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/5b223432-95d7-4282-bf7b-63c46b3ab9fc%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Hello Everyone,

Thank you very much for the healthy discussion. Bryan, thanks a lot for the valuable insights. I feel, it would be nice to have an example in the docs with the real python callbacks and would be invaluable for rookies like me. :wink:

In my case, I am confused a bit. I’m embedding my plot in a Flask app and wanted to have python callbacks (just run some other python code, for e.g.). Do I have to run a separate bokeh server instance (apart from the Flask server) ? I would be grateful if there’s any use case / example of this or showing how to achieve the same using REST API instead.

Regards,

Kevad.

···

On Sunday, January 10, 2016 at 7:33:51 PM UTC+1, Bryan Van de ven wrote:

Jim,

Not at all, this is actually very instructive and useful, and I intend to write up a good deal of the information from this thread in the main docs.

There is definitely one aspect I have not conveyed well, and that is that:

     callback=CustomJS.from_py_func(callback)

creates a JavaScript callback, by “compiling” the python into JS. Being able to write it by giving python is intended as a convenience, so that people can “write JS callbacks without having to write JS”. But the main point to bear in mind is that there is never any python that gets executed when you use “CustomJS”, and this is why “foo” is never updated — it’s updating a “foo” variable in the browser JS interpreter, because that is where the callback is run (not in an ipython kernel).

To execute python code without a Bokeh Server, you will need to use “Jupyter interactors” This is a different set of widgets that Jupyter notebooks provide (different from Bokeh widgets) that you can attach real python callbacks to, that get exectued in the ipython kernel. It probably would have been more instructive for me to link to an actual example from the start. You can take a look at this one:

    [https://github.com/bokeh/bokeh/blob/master/examples/plotting/notebook/interact_basic.ipynb](https://github.com/bokeh/bokeh/blob/master/examples/plotting/notebook/interact_basic.ipynb)

(note the location of this notebook may change soon, we are going to re-organize our examples). They key parts to note are these, first a real python callback something like:

    def update(f, w=1, A=1, phi=0):

            if   f == "sin": func = np.sin

            elif f == "cos": func = np.cos

            elif f == "tan": func = np.tan

            r.data_source.data['y'] = A * func(w * x + phi),

            push_notebook()

and then the Juptyter “interact” function, that auto-creates a GUI for a set of input parameters for the callback:

    from ipywidgets import interact



    interact(update, f=["sin", "cos", "tan"], w=(0,100), A=(1,5), phi=(0, 20, 0.1))

I believe it it possible to have finer control over the exact widgets that Jupypter uses, but that is beyond my notebook knowledge. The “auto-generated” GUI is generally fairly nice. The one above will have a dropdown select box for “f” and three sliders for the other ranges.

I hope this clears things up a bit more, thanks for your patience,

Bryan

On Jan 10, 2016, at 11:39 AM, Jim Sharpe [email protected] wrote:

Hi Bryan,

From this most recent post and, several others leading up to it ,the following stripped down version of the example should actually work in a juypter notebook. However the behavior I see is that the python variable foo never changes from 0. I did think of “misusing” a ColumnDataSource to export values to python but was hoping there was a better way. Sorry if I’m being dense and missing something obvious.


from bokeh.io import output_notebook, show, vform

from bokeh.models import CustomJS, ColumnDataSource, Slider

from bokeh.plotting import Figure, output_file, show

output_notebook()

x = [x*0.005 for x in range(0, 200)]

y = x

foo = 0

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

def callback(source=source):

global foo
foo = cb_obj.get('value')
push_notebook()

slider = Slider(start=0.1, end=4, value=1, step=.1, title=“power”, callback=CustomJS.from_py_func(callback))

layout = vform(slider)

show(layout)

… and then in a following cell:

print(foo)


Of the things that aren’t currently possible, but might be in the future, the one I’m especially interested in is to have selection changes in Bokeh plots trigger callbacks in python. One of my primary use cases involves a chain of selections made on Bokeh components. For example the selection on scatter plot is used to populate the rows of a table. Then a selection on the table is used to populate a bunch of line charts. One thing that complicates doing this now is that there is python code that processes each stage of selection data to create the content for the subsequent components. I have all this working today except the automatic triggering part. For that I have to “manually” execute cells after each selection.

On Sunday, January 10, 2016 at 9:58:51 AM UTC-7, Bryan Van de ven wrote:

Hi Jim,

Thanks for the kind words.

I mentioned I was in a hurry before catching flight earlier, so I may have spoken a bit broadly. Let me clarify the situation with notebooks specifically, what is possible now and what would be possible with a little work.

  • push_notebook can update basically any property attribute on any Bokeh model (so not just data sources) but as you note it only pushed from python to BokehJS right now. In case details are interesting: every “show” in the notebook sets up a Jupyter comms object that can push Bokeh protocol messages to BokehJS, which processes the messages to update that plot.

  • a last minute bug currently means push_notebook only works on the last “shown” plot (comm handles for updating arbitrary cells output should be fixed and in a dev build in the next week)

  • In my earlier email, for python callbacks, I had in mind Jupyter interactors (not Bokeh widgets). So, you can have widgets like dropdowns, sliders, buttons, etc that trigger python code to be called (which could then call push_notebook to update a plot, e.g.)

So, putting all that together: if you just need widgets to drive python code, to then drive push_notebook to update a plot, everything you need should be in place now. What is not present right now (at least not in any reasonable way) is to have events like range changes and selections from plot tools inform python code in the notebook. What I’d like to do in the near future is a refactor that basically makes the notebook comms case and the bokeh server machinery identical. Right now parts are similar, but they could still share more implementation. Apart from making maintenance simpler (by having less code paths), I think it should open up the possibility of getting events “out” of plots to trigger notebook callbacks.

call push_notebook I do see the plot running in the notebook update. But that only seems to work for updating plots. Any changes outside the Bokeh components, such as setting a variable don’t seem to get exposed to the python kernel.

Are you setting a variable in the callback function? Since all python function variables are local by default, if you want a change in the callback to “escape” the callback, you’d probably have to use “global myfoo” in order to be able update a “myfoo” variable outside the callback. I’ve also seen people make mutating updates to dictionaries created outside the function, to simulate “global”. Both methods are both a bit gorpy but I’m not sure there’s any better simple ways.

Bryan

On Jan 10, 2016, at 2:09 AM, Jim Sharpe [email protected] wrote:

Hi Bryan,

I really appreciate timely responses to our queries. It makes me even more comfortable using Bokeh in additional places.

Of the various options you described in one of the earlier messages, executing the python in the jupyter kernel is exactly what we need. I think I understand the role of push_notebook but think I’m still missing something in my understanding of how that overall process works. If I update the ColumnDataSource in the callback and then call push_notebook I do see the plot running in the notebook update. But that only seems to work for updating plots. Any changes outside the Bokeh components, such as setting a variable don’t seem to get exposed to the python kernel.

As a bit of background, the use case I’m working on involves a bunch of widgets to collect information for a query to MongoDB, the results of which will eventually end up getting displayed in Bokeh plots and/or tables. I basically need to wait to submit the query until after all the values in the widgets have been set and then “hit the go button”. Both the query and the subsequent processing that gets performed to transform the data for display in is all in python (as opposed to JS) running in the jupyter kernel, so it would be more convenient to also keep the callback code in python as well. Although I have created a separate version of the application that uses ipywidgets that works just fine, the Bokeh widgets look more appealing. For the ipywidget version, I basically use a shared callback to get all the widget values used to create the query and then the event from a button to fire it. I was hoping to use the same general approach with Bokeh but am open to other options.

On Saturday, January 9, 2016 at 7:20:39 PM UTC-7, Bryan Van de ven wrote:
Hi Jim,

That is not actually a snag it is a fundamental limitation of this particular facility. The python is converted to JavaScript to run in the browser and at that point everything is only in the browser. If you want to affect actual running Python you have to use one of the methods I outlined in another response earlier today: your own rest api, jupyter interactors, or a bokeh server. The other response has more info (apologies I am on a phone right now)

On Jan 9, 2016, at 19:35, Jim Sharpe [email protected] wrote:

I just ran into an apparent snag in using this whizzy new CustomJS.from_py_func(callback) approach. It seems, that while calculating and new data values and updating a (single?) ColumnDataSource works fine in a notebook, it doesn’t seem possible to get any other information out of the callback for other python code to see. For example if all I want to do in the callback for a slider is set a global python variable to the slider value (cb_obj.get(‘value’)), that doesn’t seem to work in a notebook/browser.

On Saturday, January 9, 2016 at 10:56:14 AM UTC-7, Bryan Van de ven wrote:
Right now it would have to be in JS. Since there are not yet lifecycle callback hooks this probably means:

An existing JS callback has to set up/bootstrap your timer callback, or

Using bokeh.embed to add your own JS directly to the document.

Bryan

On Jan 9, 2016, at 11:34, Greg Nordin [email protected] wrote:

Hi Bryan,

Something like the “add_periodic_callback()” in line_animate_widget.py in the examples would suffice for what I’m thinking about, which is just animating some lines in a line plot.

Regarding scheduling periodic/timeout callbacks “by hand”, do you mean using something like sleep(0.05) in a python callback, or setting up something in javascript?

Thanks,
Greg

On Saturday, January 9, 2016 at 10:15:34 AM UTC-7, Bryan Van de ven wrote:
Greg,

Yes but for the time being you’d have to schedule periodic/timeout callbacks “by hand”. There are two things we’d like to do soon that would make this simpler:

  • lifecycle JS callbacks i.e “on load” etc

  • models for specifying animations, transitions and easing directly from Python.

Neither should be very hard we will just have to see where they fit into the larger set of priorities.

Bryan

On Jan 9, 2016, at 11:11, Greg Nordin [email protected] wrote:

Peter & Jim,

I just tried it as well, and it is very cool! (For some reason I couldn’t get it to run in a notebook–I got the error ImportError: No module named ‘flexx’ even though I installed flexx and was using the correct env–but it runs fine from the command line: python callback.py).

Can this approach be used with an animation, i.e., using a periodic callback to change the line data values where the callback is python code translated to javascript, without the need for bokeh serve behind it (in other words it’s all in a static html file that can be opened in any browser)?

Thanks,
Greg

On Saturday, January 9, 2016 at 9:31:07 AM UTC-7, Jim Sharpe wrote:
Hi Peter,

That is indeed very cool! I just tried that example in a jupyter python3 notebook and it worked great (unlike all the other python callback examples I tried). The need to install flex and the few extra characters when specifying the callback are a small price to pay for avoiding having to write the JS.

On Saturday, January 9, 2016 at 9:22:14 AM UTC-7, pwang wrote:
On Sat, Jan 9, 2016 at 10:13 AM, Greg Nordin [email protected] wrote:
Bryan,
I too am intrigued by your statement “Python 3 you can write the callback in Python, and it will get converted to JavaScript” and would love to see an example how to do this.
Greg

Here is the documentation on it:
http://bokeh.pydata.org/en/latest/docs/user_guide/interaction.html#customjs-with-a-python-function

This is using PyScript from Almar Klein (also a bokeh dev):
http://flexx.readthedocs.org/en/latest/pyscript/intro.html#quick-intro

It’s very very cool… I’m hoping this feature will definitely cause some Pythonista’s jaws to unhinge… :smiley:

-Peter


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/0c89d16d-aac0-445d-a64a-7fa4a72253a9%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/4363103d-55a0-446f-a4cf-8078de2b62d7%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/079d6059-329c-4353-8327-fad475558dce%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/c9874d7f-3d78-43e9-906e-253399485a67%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/5b223432-95d7-4282-bf7b-63c46b3ab9fc%40continuum.io.

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