强制更新bokeh小部件?

2024-10-03 02:35:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我是bokeh的新手,正在编写一个小的bokeh服务器应用程序,它有绘图和按钮。按下按钮后,数据将重新计算并更新打印。这个想法是,只要按下按钮,它就会改变颜色和标签,还会出现一个文本“计算…”。计算完成后,打印更新,文本消失

但是,当按下按钮时,它不会改变颜色,并且在计算完成之前不会显示文本(需要几秒钟)。所有这些小部件更新都发生在计算之后。问题,有没有可能强制小部件更新,比如print()中的flush=True或者类似的东西

我在博克文档中找不到任何东西。我还尝试将小部件的更改和计算分离,并在两个单独的函数中执行它们,但没有帮助。设置按钮更改和调用计算函数之间的延迟也没有帮助。看起来,小部件的更新只在退出回调函数时发生,甚至更晚。我唯一没有检查的是CustomJS,但我不知道如何为按钮更新编写js代码

谢谢你的帮助

下面是一个接近我实际使用的代码示例:

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))

Tags: 函数from文本importsourcedata部件bokeh
1条回答
网友
1楼 · 发布于 2024-10-03 02:35:01

只有当控件返回到服务器事件循环时,Bokeh才能发送数据更新。在您的例子中,您在运行计算时不会每次都产生控件,因此当回调已经完成时,它会发送所有更新

在您的情况下,最简单的做法是将回调拆分为需要同步的块,并在下一次tick回调中运行每个块:

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用户指南的Updating From Threads部分

相关问题 更多 >