python callback and trigger function not working

I am trying to update a very simple columndatamodel in the callback but documented solutions on triggering change
do not seem to work, code:

source = ColumnDataSource(data=dict(classification=classification, counts=counts,
type_color=[colordict for x in colordict],
font_color=[bokutils.contrasting_text_color(colordict) for x in colordict],
subgroups=[subdict for x in subdict]))

def update(source=source, slider=date_range_slider, window=None):
    data = source.data
    print ('slider0',slider.value[0])
    print (source.data['counts'])
    i=0
    arr=source.data['counts']
    al=len(arr)
    print (al)
    while (i < al):
    arr[i]=arr[i]+50
    i=i+1

    source.trigger('change');
    print (source.data['counts'])
    print ('slider1',slider.value[1])
    return

results in a python error:
source.trigger(‘change’);
TypeError: trigger() takes at least 4 arguments (2 given)

Changing the trigger call to :
source.trigger(‘change’,source,source,source);
results in:

VM1492:20 Uncaught TypeError: source.trigger is not a function
at cb (eval at i._make_func (bokeh-0.12.14.min.js:1), :20:12)
at eval (eval at i._make_func (bokeh-0.12.14.min.js:1), :25:1)
at i.execute (bokeh-0.12.14.min.js:1)
at e. (bokeh-0.12.14.min.js:1)
at t.emit (bokeh-0.12.14.min.js:1)
at e._setv (bokeh-0.12.14.min.js:1)
at e.setv (bokeh-0.12.14.min.js:1)
at e.set [as value] (bokeh-0.12.14.min.js:1)
at e._slide (bokeh-widgets-0.12.14.min.js:1)
at Object. (bokeh-widgets-0.12.14.min.js:1)

but the code before this executes fine:
slider0 1473980224165
(4) [1989, 513, 114, 107]

So the source (Columndatastore) seems to have a trigger method that does something undocumented.
What I really need is just for the plot to redraw with the new data set in the update function and I cannot
figure out how to do this simple thing. A plot.revalidate() function for example.
There has to be a way to trigger an update of the plot from the python callback as it is translated to JS
it should just do the appropriate event to tell the plot to update itself with the new source data.
Anybody figured out how to do this? It needs to be general so that it applies to other on_change callbacks?

I find it a bit strange that the documented trigger does not work and nobody seems to have asked this question?
Kind regards,

I assume you are using slider.callback = CustomJS.from_py_func(update)
If not, your callback is wrong.

This works with from_py_func:

from future import print_function

from bokeh.models import ColumnDataSource,RangeSlider, CustomJS

from bokeh.io import show

from bokeh.plotting import figure

from bokeh.layouts import Column

slider = RangeSlider(start=0,end=10,step=1,value=[3,7])

source = ColumnDataSource(data={‘counts’:range(20)})

fig = figure()

fig.scatter(‘counts’,‘counts’,source=source)

def update(source=source,slider=slider):

data = source.data

print(‘slider0’,slider.value[0])

print(source.data[‘counts’])

i=0

arr=source.data[‘counts’]

al=len(arr)

print (al)

while (i < al):

arr[i]=arr[i]+50

i=i+1

source.change.emit()

print(source.data[‘counts’])

print(‘slider1’,slider.value[1])

slider.callback = CustomJS.from_py_func(update)

show(Column(slider,fig))

``

And with the bokeh server, you don’t need the source.change.emit() part:

from future import print_function

from bokeh.models import ColumnDataSource,RangeSlider

from bokeh.io import curdoc

from bokeh.plotting import figure

from bokeh.layouts import Column

slider = RangeSlider(start=0,end=10,step=1,value=[3,7])

source = ColumnDataSource(data={‘counts’:range(20)})

fig = figure()

fig.scatter(‘counts’,‘counts’,source=source)

def update(attr,old,new):

data = source.data

print(‘slider0’,new[0])

print(source.data[‘counts’])

i=0

arr=source.data[‘counts’]

al=len(arr)

print (al)

while (i < al):

arr[i]=arr[i]+50

i=i+1

source.data[‘counts’] = arr

print(source.data[‘counts’])

print(‘slider1’,new[1])

slider.on_change(‘value’,update)

curdoc().add_root(Column(slider,fig))

``

Hi,

The .trigger method on the JS side was deprecated (with a console warning) for a long time, then subsequently removed last year. If there are still any current docs or examples that do this, then it is in error. Please let us know where so that we may update them.

Thanks,

Bryan

···

On Mar 23, 2018, at 06:37, Sébastien Roche <[email protected]> wrote:

I assume you are using slider.callback = CustomJS.from_py_func(update)
If not, your callback is wrong.

This works with from_py_func:

from __future__ import print_function

from bokeh.models import ColumnDataSource,RangeSlider, CustomJS
from bokeh.io import show
from bokeh.plotting import figure
from bokeh.layouts import Column

slider = RangeSlider(start=0,end=10,step=1,value=[3,7])
source = ColumnDataSource(data={'counts':range(20)})
fig = figure()
fig.scatter('counts','counts',source=source)

def update(source=source,slider=slider):
    data = source.data
    print('slider0',slider.value[0])
    print(source.data['counts'])
    i=0
    arr=source.data['counts']
    al=len(arr)
    print (al)
    while (i < al):
        arr[i]=arr[i]+50
        i=i+1

    source.change.emit()
    print(source.data['counts'])
    print('slider1',slider.value[1])

slider.callback = CustomJS.from_py_func(update)

show(Column(slider,fig))

And with the bokeh server, you don't need the source.change.emit() part:

from __future__ import print_function

from bokeh.models import ColumnDataSource,RangeSlider
from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.layouts import Column

slider = RangeSlider(start=0,end=10,step=1,value=[3,7])
source = ColumnDataSource(data={'counts':range(20)})
fig = figure()
fig.scatter('counts','counts',source=source)

def update(attr,old,new):
    data = source.data
    print('slider0',new[0])
    print(source.data['counts'])
    i=0
    arr=source.data['counts']
    al=len(arr)
    print (al)
    while (i < al):
        arr[i]=arr[i]+50
        i=i+1
    source.data['counts'] = arr

    print(source.data['counts'])
    print('slider1',new[1])

slider.on_change('value',update)

curdoc().add_root(Column(slider,fig))

--
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/904ba77d-41a5-4947-a5b5-73d8334ee768%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

Many thanks both of you. I have now got the redraw working with the emit call.
There are more documents in the wild with trigger in the example than you can fix
in my view. Trying to assess the capabilities of a plotting package is really hard when
there is so much out of date information available, e.g. the high level charting. There
are not enough warnings that python only works in a server environment and that the
python to JS translator is really basic. People travel around the world saying never write
another JS callback again which is a truth with modification. In my view the landing page
for this package should make the architectural differences blindingly obvious as the no one
priority.
Kind regards,

···

On Friday, March 23, 2018 at 9:14:00 AM UTC, Sue-Nick Leala wrote:

I am trying to update a very simple columndatamodel in the callback but documented solutions on triggering change
do not seem to work, code:

source = ColumnDataSource(data=dict(classification=classification, counts=counts,
type_color=[colordict for x in colordict],
font_color=[bokutils.contrasting_text_color(colordict) for x in colordict],
subgroups=[subdict for x in subdict]))

def update(source=source, slider=date_range_slider, window=None):
    data = source.data
    print ('slider0',slider.value[0])
    print (source.data['counts'])
    i=0
    arr=source.data['counts']
    al=len(arr)
    print (al)
    while (i < al):
    arr[i]=arr[i]+50
    i=i+1

    source.trigger('change');
    print (source.data['counts'])
    print ('slider1',slider.value[1])
    return

results in a python error:
source.trigger(‘change’);
TypeError: trigger() takes at least 4 arguments (2 given)

Changing the trigger call to :
source.trigger(‘change’,source,source,source);
results in:

VM1492:20 Uncaught TypeError: source.trigger is not a function
at cb (eval at i._make_func (bokeh-0.12.14.min.js:1), :20:12)
at eval (eval at i._make_func (bokeh-0.12.14.min.js:1), :25:1)
at i.execute (bokeh-0.12.14.min.js:1)
at e. (bokeh-0.12.14.min.js:1)
at t.emit (bokeh-0.12.14.min.js:1)
at e._setv (bokeh-0.12.14.min.js:1)
at e.setv (bokeh-0.12.14.min.js:1)
at e.set [as value] (bokeh-0.12.14.min.js:1)
at e._slide (bokeh-widgets-0.12.14.min.js:1)
at Object. (bokeh-widgets-0.12.14.min.js:1)

but the code before this executes fine:
slider0 1473980224165
(4) [1989, 513, 114, 107]

So the source (Columndatastore) seems to have a trigger method that does something undocumented.
What I really need is just for the plot to redraw with the new data set in the update function and I cannot
figure out how to do this simple thing. A plot.revalidate() function for example.
There has to be a way to trigger an update of the plot from the python callback as it is translated to JS
it should just do the appropriate event to tell the plot to update itself with the new source data.
Anybody figured out how to do this? It needs to be general so that it applies to other on_change callbacks?

I find it a bit strange that the documented trigger does not work and nobody seems to have asked this question?
Kind regards,

If I google “bokeh callbacks” the very first result is this one: https://bokeh.pydata.org/en/latest/docs/user_guide/interaction/callbacks.html

There are no occurrence of .trigger() on this page, and several occurrences of .change.emit()

And since bokeh is in active development, if you look on other platforms like SO/blogs/github projects you have more chances to find old examples that rely on a previous version since which breaking changes may have been introduced.

Also from_py_func relies on PyScript as can be seen in the documentation https://bokeh.pydata.org/en/latest/docs/reference/models/callbacks.html

Should Bokeh just replicate the info that is on this page http://flexx.readthedocs.io/en/latest/pyscript/intro.html ? That might be nice, but just knowing they use PyScript is enough information, and you can get the best info about it on its own project page.

“Obvious” is oddly subjective. I personally get frustrated with a lot of introductory examples, on bokeh or elsewhere, that are not pure minimal “hello world” type examples that present a specific functionality in the absolute minimum amount of lines. But other people may find it more practical to have several related functionalities present in the same example.

Bokeh probably lacks a nice page like this https://pandas.pydata.org/pandas-docs/stable/release.html where you can just ctrl+f “break”

If the releases page of bokeh had all release notes on one scrollbar like for pandas, you could just ctrl+f “.trigger” and quickly be brought to the 0.12.6 release that documents the change from .trigger to .emit (0.12.6 (Jun 2017) — Bokeh 0.12.14 documentation)

···

Le lundi 26 mars 2018 03:41:24 UTC-4, Sue-Nick Leala a écrit :

Many thanks both of you. I have now got the redraw working with the emit call.
There are more documents in the wild with trigger in the example than you can fix
in my view. Trying to assess the capabilities of a plotting package is really hard when
there is so much out of date information available, e.g. the high level charting. There
are not enough warnings that python only works in a server environment and that the
python to JS translator is really basic. People travel around the world saying never write
another JS callback again which is a truth with modification. In my view the landing page
for this package should make the architectural differences blindingly obvious as the no one
priority.
Kind regards,

On Friday, March 23, 2018 at 9:14:00 AM UTC, Sue-Nick Leala wrote:

I am trying to update a very simple columndatamodel in the callback but documented solutions on triggering change
do not seem to work, code:

source = ColumnDataSource(data=dict(classification=classification, counts=counts,
type_color=[colordict for x in colordict],
font_color=[bokutils.contrasting_text_color(colordict) for x in colordict],
subgroups=[subdict for x in subdict]))

def update(source=source, slider=date_range_slider, window=None):
    data = source.data
    print ('slider0',slider.value[0])
    print (source.data['counts'])
    i=0
    arr=source.data['counts']
    al=len(arr)
    print (al)
    while (i < al):
    arr[i]=arr[i]+50
    i=i+1

    source.trigger('change');
    print (source.data['counts'])
    print ('slider1',slider.value[1])
    return

results in a python error:
source.trigger(‘change’);
TypeError: trigger() takes at least 4 arguments (2 given)

Changing the trigger call to :
source.trigger(‘change’,source,source,source);
results in:

VM1492:20 Uncaught TypeError: source.trigger is not a function
at cb (eval at i._make_func (bokeh-0.12.14.min.js:1), :20:12)
at eval (eval at i._make_func (bokeh-0.12.14.min.js:1), :25:1)
at i.execute (bokeh-0.12.14.min.js:1)
at e. (bokeh-0.12.14.min.js:1)
at t.emit (bokeh-0.12.14.min.js:1)
at e._setv (bokeh-0.12.14.min.js:1)
at e.setv (bokeh-0.12.14.min.js:1)
at e.set [as value] (bokeh-0.12.14.min.js:1)
at e._slide (bokeh-widgets-0.12.14.min.js:1)
at Object. (bokeh-widgets-0.12.14.min.js:1)

but the code before this executes fine:
slider0 1473980224165
(4) [1989, 513, 114, 107]

So the source (Columndatastore) seems to have a trigger method that does something undocumented.
What I really need is just for the plot to redraw with the new data set in the update function and I cannot
figure out how to do this simple thing. A plot.revalidate() function for example.
There has to be a way to trigger an update of the plot from the python callback as it is translated to JS
it should just do the appropriate event to tell the plot to update itself with the new source data.
Anybody figured out how to do this? It needs to be general so that it applies to other on_change callbacks?

I find it a bit strange that the documented trigger does not work and nobody seems to have asked this question?
Kind regards,

Hi,

I empathize with how having out of date information can be frustrating, however we simply do not have any control over that (which is frustrating for me!) Priorities and resources change over time, and learning also sometimes has to happen from making mistakes that need fixing later. All of these things contribute to the designation "active development". That said, we *are* nearing a plateau of stability and less change, so hopefully this is a problem that will abate by itself over time.

Regarding the release notes on one page, I had not thought of that. My inclination is to prefer things "split out" but what you say is a reasonable reason to consider a combined page. Please feel free to open a GH issue to discuss further.

Regarding single purpose vs slightly more involved examples, I do try to have a mix of both. Almost all the examples in the User's Guide, for example, are very short, and demonstrate only a single thing. The examples in the "examples" directory tend to be slightly more involved, in order to demonstrate something closer to real world usage, to have attractive visuals for the gallery, and so as not to explode the number of examples by 10-100x.

I'm happy to consider suggestions for organizational or content changes (especially if the suggestions come with help)

Thanks,

Bryan

···

On Mar 26, 2018, at 06:22, Sébastien Roche <[email protected]> wrote:

If I google "bokeh callbacks" the very first result is this one: https://bokeh.pydata.org/en/latest/docs/user_guide/interaction/callbacks.html

There are no occurrence of .trigger() on this page, and several occurrences of .change.emit()

And since bokeh is in active development, if you look on other platforms like SO/blogs/github projects you have more chances to find old examples that rely on a previous version since which breaking changes may have been introduced.

Also from_py_func relies on PyScript as can be seen in the documentation https://bokeh.pydata.org/en/latest/docs/reference/models/callbacks.html

Should Bokeh just replicate the info that is on this page http://flexx.readthedocs.io/en/latest/pyscript/intro.html ? That might be nice, but just knowing they use PyScript is enough information, and you can get the best info about it on its own project page.

"Obvious" is oddly subjective. I personally get frustrated with a lot of introductory examples, on bokeh or elsewhere, that are not pure minimal "hello world" type examples that present a specific functionality in the absolute minimum amount of lines. But other people may find it more practical to have several related functionalities present in the same example.

Bokeh probably lacks a nice page like this https://pandas.pydata.org/pandas-docs/stable/release.html where you can just ctrl+f "break"
If the releases page of bokeh had all release notes on one scrollbar like for pandas, you could just ctrl+f ".trigger" and quickly be brought to the 0.12.6 release that documents the change from .trigger to .emit (https://bokeh.pydata.org/en/0.12.14/docs/releases/0.12.6.html\)

Le lundi 26 mars 2018 03:41:24 UTC-4, Sue-Nick Leala a écrit :
Many thanks both of you. I have now got the redraw working with the emit call.
There are more documents in the wild with trigger in the example than you can fix
in my view. Trying to assess the capabilities of a plotting package is really hard when
there is so much out of date information available, e.g. the high level charting. There
are not enough warnings that python only works in a server environment and that the
python to JS translator is really basic. People travel around the world saying never write
another JS callback again which is a truth with modification. In my view the landing page
for this package should make the architectural differences blindingly obvious as the no one
priority.
Kind regards,

On Friday, March 23, 2018 at 9:14:00 AM UTC, Sue-Nick Leala wrote:
I am trying to update a very simple columndatamodel in the callback but documented solutions on triggering change
do not seem to work, code:

source = ColumnDataSource(data=dict(classification=classification, counts=counts,
                                            type_color=[colordict for x in colordict],
                                            font_color=[bokutils.contrasting_text_color(colordict) for x in colordict],
                                            subgroups=[subdict for x in subdict]))
    
    def update(source=source, slider=date_range_slider, window=None):
        data = source.data
        print ('slider0',slider.value[0])
        print (source.data['counts'])
        i=0
        arr=source.data['counts']
        al=len(arr)
        print (al)
        while (i < al):
        arr[i]=arr[i]+50
        i=i+1

        source.trigger('change');
        print (source.data['counts'])
        print ('slider1',slider.value[1])
        return

results in a python error:
   source.trigger('change');
TypeError: trigger() takes at least 4 arguments (2 given)

Changing the trigger call to :
source.trigger('change',source,source,source);
results in:

VM1492:20 Uncaught TypeError: source.trigger is not a function
    at cb (eval at i._make_func (bokeh-0.12.14.min.js:1), <anonymous>:20:12)
    at eval (eval at i._make_func (bokeh-0.12.14.min.js:1), <anonymous>:25:1)
    at i.execute (bokeh-0.12.14.min.js:1)
    at e.<anonymous> (bokeh-0.12.14.min.js:1)
    at t.emit (bokeh-0.12.14.min.js:1)
    at e._setv (bokeh-0.12.14.min.js:1)
    at e.setv (bokeh-0.12.14.min.js:1)
    at e.set [as value] (bokeh-0.12.14.min.js:1)
    at e._slide (bokeh-widgets-0.12.14.min.js:1)
    at Object.<anonymous> (bokeh-widgets-0.12.14.min.js:1)

but the code before this executes fine:
slider0 1473980224165
(4) [1989, 513, 114, 107]

So the source (Columndatastore) seems to have a trigger method that does something undocumented.
What I really need is just for the plot to redraw with the new data set in the update function and I cannot
figure out how to do this simple thing. A plot.revalidate() function for example.
There has to be a way to trigger an update of the plot from the python callback as it is translated to JS
it should just do the appropriate event to tell the plot to update itself with the new source data.
Anybody figured out how to do this? It needs to be general so that it applies to other on_change callbacks?

I find it a bit strange that the documented trigger does not work and nobody seems to have asked this question?
Kind regards,

--
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/5b035761-a4f5-40f9-9137-066b9ae14dbb%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.