我在笔记本(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.state
which 有一个add_periodic_callback
方法,但没有add_next_tick_callback
.
如何使用add_next_tick_callback
面板包裹的散景图?