Define Custom Callback Function Bokeh TapTool

Thanks again for the clarification. I think it’s finally sunk in. I do already have a version of my application that uses the ipywidgets/interactors for the input and Bokeh charts and table for the output that works pretty well (except for the automatic handling of selections). I was just hoping that I could swap those out for the the Bokeh ones, mainly because IMO the Bokeh ones look better and in some cases provide additional control.

If at some point in the future you do allow for some mechanism to fire a callback when a selection is made in a Bokeh component (in a notebook) I would find that extremely useful, even if it has to be done in a roundabout way.

···

On Sunday, January 10, 2016 at 11:33:51 AM UTC-7, 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.

Hi, is there any chance one can link an example of using a Bokeh server and the on_change methods to run a custom python function (actually a class method) by means of TapTool (or other tools)?

I tried to search around but couldn’t find a simple example to follow…

Thanks!

And btw, Bokeh is amazing!

Jacopo

···

Il giorno sabato 9 gennaio 2016 14:30:26 UTC+1, Kevad ha scritto:

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.

There's not currently an event that can be responded to *just for the tap*, if that's what you are looking for. It could certainly make sense, but there needs to be some preliminary work done to support "fire-and-forget" type events first. (Feel free to open a feature request issue on GH) What tap tool *does* do, is update a selection on a data source (whenever the selected points changes as a result of a tap), and this you can respond to if that is what you want need. But to do that you are put an on_change handler on the data source, not on the tool.

Bryan

···

On Feb 17, 2016, at 10:26 AM, [email protected] wrote:

Hi, is there any chance one can link an example of using a Bokeh server and the on_change methods to run a custom python function (actually a class method) by means of TapTool (or other tools)?

I tried to search around but couldn't find a simple example to follow...

Thanks!

And btw, Bokeh is amazing!

Jacopo

Il giorno sabato 9 gennaio 2016 14:30:26 UTC+1, Kevad ha scritto:
SO: python - Define Custom Callback Function Bokeh TapTool - Stack Overflow

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/80947f67-39e9-4b11-8b24-44aa068b61fa%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

Here’s an example of
doing a callback on a data source on_change:

···

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

It’s responding to a box select but it could just as easily be a tap.
On 2/19/16 5:32 AM, Bryan Van de Ven
wrote:


There's not currently an event that can be responded to *just for the tap*, if that's what you are looking for. It could certainly make sense, but there needs to be some preliminary work done to support "fire-and-forget" type events first. (Feel free to open a feature request issue on GH) What tap tool *does* do, is update a selection on a data source (whenever the selected points changes as a result of a tap), and this you can respond to if that is what you want need. But to do that you are put an on_change handler on the data source, not on the tool.
Bryan

On Feb 17, 2016, at 10:26 AM, wrote:
Hi, is there any chance one can link an example of using a Bokeh server and the on_change methods to run a custom python function (actually a class method) by means of TapTool (or other tools)?
I tried to search around but couldn't find a simple example to follow...
Thanks!
And btw, Bokeh is amazing!
Jacopo
Il giorno sabato 9 gennaio 2016 14:30:26 UTC+1, Kevad ha scritto:
SO: 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 .
To post to this group, send email to .
To view this discussion on the web visit .
For more options, visit .


Sarah Bird
Developer, Bokeh

    [
      ![Continuum Analytics](http://docs.continuum.io/_static/img/ContinuumWordmark.png)
    ](http://continuum.io)

[email protected]http://stackoverflow.com/questions/34693892/define-custom-callback-function-bokeh-taptool[email protected]@continuum.iohttps://groups.google.com/a/continuum.io/d/msgid/bokeh/80947f67-39e9-4b11-8b24-44aa068b61fa%40continuum.iohttps://groups.google.com/a/continuum.io/d/optout

Hi Bryan,

I am new to Bokeh and I’m not sure if this is the right place to ask this question but I didn’t find any other forum talking about my issue. The error that I’m getting when trying to use “CustomJS.from_py_func(callback)” is “AttributeError: type object ‘CustomJS’ has no attribute ‘from_py_func’”. I appreciate it if you can help me with that or direct me to where this question is appropriate. Thanks.

···

On Saturday, January 9, 2016 at 6:20:39 PM UTC-8, 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.

I think you have a version of Bokeh that is too old.

Bryan

···

On Mar 22, 2016, at 2:42 PM, [email protected] wrote:

Hi Bryan,

I am new to Bokeh and I'm not sure if this is the right place to ask this question but I didn't find any other forum talking about my issue. The error that I'm getting when trying to use "CustomJS.from_py_func(callback)" is "AttributeError: type object 'CustomJS' has no attribute 'from_py_func'". I appreciate it if you can help me with that or direct me to where this question is appropriate. Thanks.

On Saturday, January 9, 2016 at 6:20:39 PM UTC-8, 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:
Interaction — Bokeh 3.3.2 Documentation

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 bokeh+un...@continuum.io.
To post to this group, send email to bo...@continuum.io.
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 bokeh+un...@continuum.io.
To post to this group, send email to bo...@continuum.io.
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 bokeh+un...@continuum.io.
To post to this group, send email to bo...@continuum.io.
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/bf24c562-82d4-47e3-b09b-c63382ed1861%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

Bryan,

Thanks a lot man. I upgraded my bokeh and it works fine now.

···

On Tuesday, March 22, 2016 at 12:52:48 PM UTC-7, Bryan Van de ven wrote:

I think you have a version of Bokeh that is too old.

Bryan

On Mar 22, 2016, at 2:42 PM, [email protected] wrote:

Hi Bryan,

I am new to Bokeh and I’m not sure if this is the right place to ask this question but I didn’t find any other forum talking about my issue. The error that I’m getting when trying to use “CustomJS.from_py_func(callback)” is “AttributeError: type object ‘CustomJS’ has no attribute ‘from_py_func’”. I appreciate it if you can help me with that or direct me to where this question is appropriate. Thanks.

On Saturday, January 9, 2016 at 6:20:39 PM UTC-8, 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/bf24c562-82d4-47e3-b09b-c63382ed1861%40continuum.io.

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