Ползунок боке с обратным вызовом JS сопоставляется с тем же значением

Я следовал руководству, опубликованному здесь, чтобы создать инструмент визуализации, аналогичный инструменту от Gapminder ( анимированный пузырьковый график) с использованием моего собственного набора данных.

Все работало нормально (хотя мне пришлось изменить несколько строк для кода обратного вызова JavaScript слайдера из руководства в моем собственном коде).

Однако я заметил, что когда ползунок находится в положении 0 или 1, оба значения будут отображаться на одну и ту же дату в исходном объекте, на который ссылается обратный вызов.

Для справки:

  • 0 соответствует дате (28.08.2019), тогда как 1 соответствует дате (29.08.2019).
  • Объект js_source_array_engagement String выглядит так: {0: _0, 1: _1, 2: _2, 3: _3, 4: _4, 5: _5, 6: _6, 7: _7, 8: _8, 9: _9, 10: _10, 11: _11, 12: _12, 13: _13, 14: _14, 15: _15}.
  • engagement_sources — это словарь со следующими ключами: '_0', '_1', '_2', '_3', '_4', '_5', '_6', '_7', '_8', '_9', '_10', '_11', '_12', '_13', '_14', '_15'. Ключи сопоставляются с объектами ColumnDataSource.
  • В результате объект String js_source_array_engagement будет использоваться для ссылки на engagement_sources в обратном вызове JS.

Это код слайдера:

''' ############ ADD SLIDER ############ '''
code = """
    var day = slider.value,
        sources = %s,
        new_source_data = sources[day].data;

    console.log(day);
    console.log(sources[day].data['days'][0]);

    text = new_source_data['days'][0];
    renderer_source.data = new_source_data;
    text_source.data = {'days':[text]};
""" % js_source_array_engagement

callback = CustomJS(args=engagement_sources, code=code)
slider = Slider(start=days_indices[0], end=days_indices[-1], value=0, step=1, title="Day", callback=callback)

callback.args["renderer_source"] = renderer_source
callback.args["slider"] = slider
callback.args["text_source"] = text_source

layout_one = layout([[plot], [slider]])

print(engagement_sources['_0'].data['days'][0]) #prints (08/28/2019)
print(engagement_sources['_1'].data['days'][0]) #prints (08/29/2019)

plots = row(layout_one, plot_two)

Когда я перемещаю ползунок на 0 или 1, консоль печатает 0 и 1 соответственно.

Однако они оба сопоставляются с датой 29.08.2019. Я проверил правильность значений, распечатав их, и два оператора печати показывают (28.08.2019) и (29.08.2019) соответственно.

В результате я думаю, что может быть что-то не так с кодом обратного вызова, в частности, с тем, как код ссылается на исходный объект, но я не мог понять, что это такое, тем более что он правильно ссылается на все другие значения, за исключением случаев, когда ползунок в 0.


person Sko_Buffs    schedule 11.12.2019    source источник


Ответы (1)


Если вы следуете этому примеру, используя show, вы создаете автономный вывод. Это режим, в котором Bokeh создает кучу статического кода HTML и JS, который отправляется в браузер для отображения графика. Но вот важная часть: никакое соединение не поддерживается ни с одним процессом Python. Обновление ползунка с таким использованием влияет только на состояние JavaScript, оно не может вообще никак повлиять на какие-либо переменные или состояние Python. Если вы хотите иметь полную двустороннюю синхронизацию между Python и отображаемым контентом (который существует на «стороне JavaScript»), то для этого и предназначен сервер Bokeh (именно в этом его цель).

Вы можете увидеть пример того, как встроить серверное приложение Bokeh в ноутбук здесь:

https://github.com/bokeh/bokeh/blob/master/examples/howto/server_embed/notebook_embed.ipynb

Кроме того, учебник, на который вы ссылаетесь, довольно старый и использует очень старый метод замены текста, который совсем не нужен в контексте сервера Bokeh. Вы можете увидеть современную (и значительно более простую) серверную версию Bokeh этого примера Gapminder здесь:

https://github.com/bokeh/bokeh/tree/master/examples/app/gapminder

И вы можете увидеть живую демо-версию этого примера Gapminder, работающую здесь:

https://demo.bokeh.org/gapminder

person bigreddot    schedule 11.12.2019
comment
Спасибо, я начал менять обратные вызовы на Python, я борюсь с обратными вызовами JS в боке. - person Sko_Buffs; 15.12.2019