Python Bokeh:为什么我需要调用source.change.emit()来更新跨度的位置?

Python Bokeh:为什么我需要调用source.change.emit()来更新跨度的位置?,python,bokeh,Python,Bokeh,我想突出显示我悬停的样本。我确实通过一个定制的JSCallback解决了这个问题。请参阅下面的最小工作示例。 我的问题是,为什么我需要调用source.change.emit()来更新Span的位置?如果在回调中删除source.change.emit(),则水平线的位置根本不会改变(视觉上)。到目前为止,我认为,如果我实际更改源对象中的数据(如source.data['Value1']=),我只需要调用这个命令 在我的应用程序中,我处理具有相同源对象的多个绘图中的大量数据在回调中,Span位置

我想突出显示我悬停的样本。我确实通过一个定制的JSCallback解决了这个问题。请参阅下面的最小工作示例。
我的问题是,为什么我需要调用
source.change.emit()
来更新Span的位置?如果在回调中删除
source.change.emit()
,则水平线的位置根本不会改变(视觉上)。到目前为止,我认为,如果我实际更改源对象中的数据(如
source.data['Value1']=
),我只需要调用这个命令

在我的应用程序中,我处理具有相同源对象的多个绘图中的大量数据在回调中,Span位置会发生变化,但视觉悬停注释会明显变慢,并且由于这种非平滑性也会跳过一些示例。是否有方法在不调用
source.change.emit()
的情况下更新Span的位置?
提前谢谢

编辑:

我在Bokeh 2.3.0上运行。

如果您移动到行的开始/结束之外,
位置
行索引
为空,并从
行索引[0]进行设置
未定义。在这种情况下,事物停止更新,因为
未定义的
不是设置
位置的有效对象。也许这就是您看到的

此版本的代码更新并保持工具提示和span同步,无需使用Bokeh 2.3调用
emit
(注意:请始终在每个问题中指定相关软件版本)

callback=CustomJS(args=dict(source=source,v_-line=v_-line),
代码=”“
const loc=cb_数据['index']。行_索引[0]
如果(loc==未定义){
v_line.visible=false
}否则{
v_line.visible=true
v_线位置=loc;
}
""")
hover\u tool\u plot=HoverTool(mode='vline',line\u policy='prev',
回调=回调,渲染器=[line])

注:我还将
line\u策略
更改为
prev
,因为我相信无论怎样,
line\u索引
都会报告这一点。这可能会变得更灵活,但以前从来没有人问过。请随意提出功能请求。

非常感谢!我不知道,这曾经是一个属性y被设置为
未定义
,它将完全停止更新。在我看来,这是一件非常重要的事情。此外,我发现,当尝试将
无穷大
的值设置为
位置
(在我的情况下,在回调中使用
cb_数据['geometry'].x时,情况似乎也是如此)。嗯,设置undefined是否为可恢复错误几乎肯定取决于特定属性。但无论如何,它都属于“undefined behavior”,因此应该避免。一般来说,Bokeh模型属性都是严格类型的(类型记录在参考指南中),只有具有这些类型的值才有效。
import pandas as pd
from bokeh.plotting import figure, curdoc
from bokeh.models import ColumnDataSource, HoverTool, CustomJS, Span
from bokeh.layouts import layout

plot1 = figure(plot_width=1000, plot_height=250)

df = pd.DataFrame({"ID":[0, 1, 2, 3, 4, 5, 6, 7], 
                   "Value1":[0, 100, 200, 300, 400, 500, 600, 700], 
                   "Value2":[0, 1, 2, 4,8 , 16, 32, 64]})
source = ColumnDataSource(df)

line = plot1.line(x='ID', y='Value1', source=source)
circle = plot1.circle(x='ID', y='Value1', source=source)

v_line = Span(location=2,  dimension='height', line_color='green',
                              line_dash='dashed', line_width=3)
plot1.add_layout(v_line)

callback = CustomJS(args=dict(source=source, v_line=v_line), 
                        code="""
                        v_line.location = cb_data['index'].line_indices[0];
                        source.change.emit();
                        """)

hover_tool_plot = HoverTool(mode='vline', line_policy='nearest', callback=callback, renderers=[line])

plot1.add_tools(hover_tool_plot)

layout_ = layout([[plot1]])
curdoc().add_root(layout_)