问题
I have Bokeh application with a Slider widget that uses the Slider.on_change callback to update my graphs. However, the slider updates come in much faster than my callback function can handle so I need a way to throttle the incoming change requests. The problem is very prominent since the slider calls into the callback during sliding, while only the last slider value (when the user releases the mouse) is of interest.
How could I tackle this problem?
回答1:
UPDATE for Bokeh 1.2
As of Bokeh 1.2, the callback policy applies to both JS callbacks as well as Python callbacks on the server. The value
property always updates unconditionally on every move, but a new value_throttled
property can be watched for changes according to the policy:
slider.callback_policy = "mouseup"
# both of these will respect the callback policy now
slider.js_on_change('value_throttled', ...)
slider.on_change('value_throttled', ...)
Note that the old callback
property is deprecated and will be removed in Bokeh 2.0. All new code should use the general on_change
and js_on_change
mechanisms.
HISTORICAL ANSWER:
As of release 0.12
this is still a bit clunky to accomplish, but not impossible. There is a "mouseup"
policy on sliders, but this currently only applies to CustomJS
callbacks. However, if that is combined with a "fake" data source, we can communicate and trigger just the last value:
from bokeh.io import curdoc
from bokeh.layouts import column
from bokeh.plotting import figure
from bokeh.models.callbacks import CustomJS
from bokeh.models.sources import ColumnDataSource
from bokeh.models.widgets import Slider
# this is the real callback that we want to happen on slider mouseup
def cb(attr, old, new):
print("UPDATE", source.data['value'])
# This data source is just used to communicate / trigger the real callback
source = ColumnDataSource(data=dict(value=[]))
source.on_change('data', cb)
# a figure, just for example
p = figure(x_range=(0,1), y_range=(0,1))
# add a slider with a CustomJS callback and a mouseup policy to update the source
slider = Slider(start=1, end=10, value=1, step=0.1, callback_policy='mouseup')
slider.callback = CustomJS(args=dict(source=source), code="""
source.data = { value: [cb_obj.value] }
""")
curdoc().add_root(column(slider, p))
# make sure to add the source explicitly
curdoc().add_root(source)
As I said, this is not ideal. There are some open feature requests that could improve this situation in the future. However the team is quite small, so if you have the ability to contribute, please don't hesitate to reach out (only new contributors can help accelerate development of new features)
来源:https://stackoverflow.com/questions/38375961/throttling-in-bokeh-application