强制更新bokeh小部件? [英] Force update of bokeh widgets?

查看:40
本文介绍了强制更新bokeh小部件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是bokeh的新手,正在编写一个小型bokeh服务器应用程序,该应用程序具有情节和一个按钮.按下按钮后,将重新计算数据并更新绘图.这个想法是,只要按下按钮,它就会更改颜色和标签,同时还会显示一个文本正在计算...".计算完成后,绘图更新且文本消失.

I am new to bokeh and writing a small bokeh server app, which has plot and a button. When the button is pressed, data is recalculated and plot updates. The idea is that as soon as the button pressed, it changes the color and label, also a text "calculating..." appears. When calculations are done, plot updates and the text disappears.

但是,当按下按钮时,它不会改变颜色,并且在完成计算之前,文本不会出现(需要几秒钟).所有这些小部件更新都会在计算后发生.问题,是否可以强制更新小部件,例如在print()情况下是否为flush = True或类似的东西?

However, when button is pressed, it doesn't change color and the text does not appear before the calculations are done (takes several seconds). All this widget update happens after calculations. Question, is it possible to force a widget to update, like flush=True in case of print() or something similar may be?

我在散景文件中找不到任何东西.我也尝试过将小部件更改和计算分开,并在两个单独的函数中执行它们,但这没有帮助.在按钮更改和调用计算功能之间设置延迟也没有帮助.似乎像对小部件的更新仅发生在回调函数退出时或更晚.我唯一没有检查的是CustomJS,但我不知道如何编写用于按钮更新的js代码.

I could not find anything in bokeh documetation. I have tried also to separate widget changes and calculations and execute them in two separate functions, but it didn't help. Setting a delay between button change and invoke of calculation function also did not help. Seems, like update on widgets only happens on exit from callback function or even later. The only thing which I did not check is CustomJS, but I don't know how to write js code for button update.

感谢您的帮助!

以下是与我实际使用的代码接近的代码示例:

Here is a code sample close to what I actually use:

from bokeh.plotting import figure
from bokeh.models import Button, PreText, ColumnDataSource
from bokeh.layouts import row

p = figure()
source = ColumnDataSource(data={"x":[0], "y":[0]})
p.line(x="x", y="y", source=source)
variable = False

# initialise widgets
switchButton = Button(label='Anticrossing OFF', button_type="default")
process_markup = PreText(text='Calculating...', visible=False)

def callback(arg):
    global variable
    global process_markup

    variable = not variable

    # change button style
    if variable:
        switchButton.update(label = 'Anticrossing ON',
                              button_type = 'success')
    else:
        switchButton.update(label = 'Anticrossing OFF',
                              button_type = 'default')
    # show "calculating..."
    process_markup.update(visible=True)

    # do long calculations
    x, y = calculate_data(variable)
    source.data = {"x":x, "y":y}

    # hide "calculating..."
    process_markup.update(visible=False)

switchButton.on_click(callback)
col = column(switchButton, process_markup)
curdoc().add_root(row(col, p))

推荐答案

Bokeh仅在控件返回到服务器事件循环时才可以发送数据更新.在您的情况下,您在运行计算时不会完全放弃控件,因此在回调完成后,它会发送所有更新.

Bokeh can send data updates only when the control is returned back to the server event loop. In your case, you run the computation without every yielding the control, so it sends all of the updates when the callback is already done.

最简单的方法是将回调分为需要同步的块,并在下一个滴答回调中运行每个块:

The simplest thing to do in your case is to split the callback into blocks that require synchronization and run each block in a next tick callback:

def callback(arg):
    global variable
    global process_markup

    variable = not variable

    # change button style
    if variable:
        switchButton.update(label = 'Anticrossing ON',
                              button_type = 'success')
    else:
        switchButton.update(label = 'Anticrossing OFF',
                              button_type = 'default')
    # show "calculating..."
    process_markup.update(visible=True)

    def calc():
        # do long calculations
        x, y = calculate_data(variable)
        source.data = {"x":x, "y":y}

        # hide "calculating..."
        process_markup.update(visible=False)

    curdoc().add_next_tick_callback(calc)

但是请注意,这样的解决方案仅在您是唯一用户并且在计算运行时不需要执行任何操作的情况下才适用.原因是计算受阻-在Bokeh运行时,您无法以任何方式与其通信.适当的解决方案将需要一些异步处理,例如线程.有关更多详细信息,请查看从线程更新的"Bokeh用户指南"部分.

Note however that such a solution is only suitable if you're the only user and you don't need to do anything while the computation is running. The reason is that the computation is blocking - you cannot communicate with Bokeh in any way while it's running. A proper solution would require some async, e.g. threads. For more details, check out the Updating From Threads section of the Bokeh User Guide.

这篇关于强制更新bokeh小部件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆