Смена слайдера Bokeh callback_policy с газа на мышку не работает - PullRequest
0 голосов
/ 04 марта 2019

Я хотел бы свободно перемещаться между 2 политиками обратного вызова ползунка, "mouseup" и "throttle".

Получается, что я могу измениться с "mouseup" на "throttle", но при обратном вызовеpolicy is "throttle", кажется, перезапись атрибута callback_policy ничего не делает, и ползунок остается в режиме "throttle".

Я что-то пропускаю здесь?

from bokeh.layouts import column
from bokeh.models.callbacks import CustomJS
from bokeh.models.sources import ColumnDataSource
from bokeh.models.widgets import Slider, RadioButtonGroup
from bokeh.application.handlers import FunctionHandler
from bokeh.application import Application

# this is the real callback that we want to happen on slider mouseup

def modify_doc(doc):
    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)

    # 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] }
    """)

    def changeMode(attr, old, new):
        if modeSelect.active==0:
            slider.callback_policy='throttle'
            print('settings adjusted to throttle')
            print(slider.callback)
            print(slider.callback_policy)
            print(slider.callback_throttle)
        else:
            slider.callback_policy='mouseup'
            print('settings adjusted to mouseup')
            print(slider.callback)
            print(slider.callback_policy)
            print(slider.callback_throttle)


    modeSelect = RadioButtonGroup(labels=["continuous", "on release"], active=1,button_type='success')
    modeSelect.on_change('active', changeMode)


    doc.add_root(column(modeSelect,slider))




handler = FunctionHandler(modify_doc)
app = Application(handler)



show(app)

1 Ответ

0 голосов
/ 06 марта 2019

В приведенном ниже коде настройка callback_policy для элемента слайдера работает, но только в одном направлении: от «mouseup» до «throttle».Установка его обратно в «mouseup» не имеет никакого эффекта.Возможно, это ошибка в Bokeh v1.0.4 или, возможно, следует манипулировать некоторыми другими атрибутами в модели BokehJS.

from bokeh.layouts import column
from bokeh.models.callbacks import CustomJS
from bokeh.models.sources import ColumnDataSource
from bokeh.models.widgets import Slider, RadioButtonGroup
from bokeh.plotting import curdoc

source = ColumnDataSource(data = dict(value = []))

def cb(attr, old, new): 
    print("UPDATE", source.data['value'])

source.on_change('data', cb)

mode_select_callback = CustomJS(code = """
    var slider = Bokeh.documents[0].get_model_by_name('my_slider')
    if (cb_obj.active == 1)
        slider.callback_policy = "mouseup"
    else (cb_obj.active == 0)
        slider.callback_policy = "throttle" """)

modeSelect = RadioButtonGroup(labels = ["continuous", "on release"], active = 1, button_type = 'default', width = 300)
modeSelect.callback = mode_select_callback
slider = Slider(start = 1, end = 10, value = 1, step = 0.1, callback_policy = 'mouseup', width = 200, name = 'my_slider')
slider.callback = CustomJS(args = dict(source = source), code = "source.data = { value: [cb_obj.value] }")

curdoc().add_root(column(modeSelect, slider))

В этом случае самым простым обходным решением будет динамическое создание и удаление слайдера с помощьюдругая callback_policy.См. Упрощенный пример ниже (Bokeh v1.0.4)

from bokeh.layouts import column
from bokeh.models.callbacks import CustomJS
from bokeh.models.sources import ColumnDataSource
from bokeh.models.widgets import Slider, RadioButtonGroup
from bokeh.plotting import curdoc

layout = column()

def create_slider(callback_policy):
    slider = Slider(start = 1, end = 10, value = 1, step = 0.1, callback_policy = callback_policy, width = 200)
    slider.callback = CustomJS(args = dict(source = source), code = "source.data = { value: [cb_obj.value] }")
    return slider

def cb(attr, old, new): print("UPDATE", source.data['value'])

source = ColumnDataSource(data = dict(value = []))
source.on_change('data', cb)
slider = create_slider(callback_policy = 'mouseup')

def changeMode(attr, old, new):
    global slider
    if modeSelect.active == 0:
        layout.children.remove(slider)
        slider = create_slider(callback_policy = 'throttle')
        layout.children.append(slider)
    else:
        layout.children.remove(slider)
        slider = create_slider(callback_policy = 'mouseup')
        layout.children.append(slider)

modeSelect = RadioButtonGroup(labels = ["continuous", "on release"], active = 1, button_type = 'default', width = 300)
modeSelect.on_change('active', changeMode)

layout.children.append(modeSelect)
layout.children.append(slider)
curdoc().add_root(layout)

Оба примера должны выполняться с bokeh serve --show app.py

...