Динамическое изменение формы фигуры боке

#python-2.7 #bokeh

#python-2.7 #боке

Вопрос:

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

С помощью следующего кода форма Figure изменяется, но изменение вступает в силу только после изменения размера окна браузера, даже если размер окна браузера очень мал.

 import bokeh.plotting
import bokeh.models
import bokeh.layouts

# set up the interface
fig1 = bokeh.plotting.figure()
button = bokeh.models.Button(label='scramble')

# define a callback and connect it
def callback():
    fig1.width = int(fig1.width * .8)
button.on_click(callback)

# add everything to the document
bokeh.plotting.curdoc().add_root(bokeh.layouts.column(button, fig1))
  

Есть ли какой-нибудь метод обновления, который мне нужно запустить? Я читал о «обратных вызовах следующего тика», но я не понимаю, имеет ли это значение.

Описанное выше поведение происходит как с firefox, так и с chromium в моей системе gnome.

Комментарии:

1. Приведенный выше код был выполнен с помощью ‘bokeh serve’

Ответ №1:

Причина, по которой это происходит, заключается в том, что макет не обновляется. Хотя ваш код изменяет значение свойства фигуры, вам необходимо пересчитать все значения в решателе документов, чтобы произошло фактическое изменение размера.

Вот строка в BokehJS, в которой происходит изменение размера:

https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/document.coffee#L92

После вызова resize на уровне документа объекты resize повторно визуализируются:

https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/models/layouts/layout_dom.coffee#L61

Проблема в том, что в настоящее время, насколько мне известно, нет открытого способа повторного запуска события изменения размера документа.

Однако вы можете сделать это на стороне клиента. Вот рабочий код, использующий CustomJS :

test.py

 from bokeh.io import show
from bokeh.layouts import column
from bokeh.models import Button, CustomJS
from bokeh.plotting import figure


fig = figure()
button = Button(label='scramble')
button.callback = CustomJS(args=dict(fig=fig), code="""
    var old_width = fig.width;
    var doc = fig.document;
    fig.width = old_width * 0.8;
    doc.resize();
""")

col = column(button, fig)
show(col)
  

Это можно запустить с python test.py помощью .

Обратите внимание, что вы также можете сделать это с помощью bokeh server, заменив последнюю строку show(col) на curdoc().add_root(col) , но я не сделал этого, чтобы подчеркнуть, что это решение на стороне клиента.

Комментарии:

1. Это все еще работает в версии Boke версии 1.0.4? Это не так. Это сообщение об ошибке в консоли javascript браузера: Uncaught TypeError: doc.resize не является функцией при t.eval (eval при get (customjs.js:37), <anonymous>:7:9) при t.execute (customjs.js:43) при e.t.change_input (abstract_button.js:56) в e.change_input (button.js:14) в e.t._button_click (abstract_button.js:52) в HTMLButtonElement.<анонимный> (abstract_button.js:42)

2. Первое. Очень, очень скоро выйдет следующий релиз со значительно улучшенным макетом. Это очень старый код, и я бы не ожидал, что он будет работать, но я ожидаю, что новый код будет намного чище. Теперь свойство будет plot_width ( bokeh. pydata.org/en/latest/docs/reference/models /… ). Вам не нужно выполнять никаких запусков. Посмотрите этот потрясающий пример для вдохновения: github.com/bokeh/bokeh/blob/master/examples/plotting/file /…

3. Кроме того, теперь передан bokeh 1.0, API обещают больше не ломаться. Спасибо за ваше терпение.

Ответ №2:

Существует способ динамического изменения размера диаграмм боке со встроенной функциональностью. Например,

fig = plotting.figure(width=1200, height=900, title="Dynamic plot".format(chartType), sizing_mode='scale_width')

Ключевым параметром является sizing_mode='scale_width'

Команды width и height служат в качестве начальных значений. Есть и другие варианты sizing_mode , поэтому я бы изучил это.

Комментарии:

1. Я изучил режимы определения размера, но описанное поведение сохранялось.