0

我在笔记本(VS Code)中有一个散景图,我想在x_range更改时更新它。为了启用从 JS 到 Python 的回调,我将图形包装在 Panel 中panel

from bokeh.plotting import figure, curdoc
import panel as pn
pn.extension(comms='vscode')

fig = figure()
fig.circle([1, 2, 3], [4, 5, 6])

tai = pn.widgets.input.TextAreaInput(sizing_mode='stretch_both')
panel = pn.Row(pn.pane.Bokeh(fig), tai)

def change_callback(attr, old, new):
    tai.value += f'{fig.x_range.start}, {fig.x_range.end}\n'
fig.x_range.on_change('start', change_callback)
fig.x_range.on_change('end', change_callback)

panel

在此示例中,我没有实际更新图形,而是有一个额外TextAreaInput的记录回调事件。这是它的样子:

问题是每次更改都会x_range导致四个事件,并且图形更新可能需要一秒钟。(两个事件是有意义的,因为我有两个回调,但为什么每个事件都发送两次?)因此我想阻止更新执行四次。

查看 Bokeh 文档,有一个方法add_next_tick_callback。想法是在事件发生时添加此回调,但如果存在旧回调,也将其删除。就像是

ntc = None
def tick_callback():
    tai.value += f'{fig.x_range.start}, {fig.x_range.end}\n'
def change_callback(attr, old, new):
    global ntc
    doc = curdoc()
    if ntc is not None:
        doc.remove_next_tick_callback(ntc)
    ntc = doc.add_next_tick_callback(tick_callback)
    tai.value += f'{ntc}\n'
fig.x_range.on_change('start', change_callback)
fig.x_range.on_change('end', change_callback)

然后将在 中执行图形更新tick_callback

这行不通。change_callback仍然被调用并创建一系列NextTickCallback对象,但从tick_callback未被调用。

我认为这可能是由于curdoc()没有在 Panel 的上下文中返回正确的 Bokeh 文档。还有fig.document,但是它提供与 相同的文档curdoc()。还有pn.statewhich 有一个add_periodic_callback方法,但没有add_next_tick_callback.

如何使用add_next_tick_callback面板包裹的散景图?

4

0 回答 0