当使用 customjs 回调更改时,Bokeh-Source 未正确更新绘图上的所有行

Bokeh-Source not updating for all lines on plot correctly when changed with customjs callback

我有一个集中运行 22 个元素的数据框。它的结构是这样的

      run           9Be       45Sc    .....
3/24/16 Run A      0.9280     nan
3/24/16 Run B      1.1052     0.4904
4/6/16 Run A       0.490      0.3374

对于每个元素,我需要绘制运行浓度以及该元素的平均值和标准偏差(实线)。我想制作一个散景图,我可以在其中 select table 中的一个元素,并且该图将使用该元素的数据进行更新。代码如下

os.chdir(r'')


low=pd.read_excel(r"", sheet_name="QC LOW", skiprows=5, usecols=range(0,34))
low["run"]=low["run"].astype(str)
low.loc[~(low["run"].str.contains("A")) & ~(low["run"].str.contains("B")),"run"]=pd.to_datetime(low.loc[(~low["run"].str.contains("A")) & (~low["run"].str.contains("B")),"run"]).dt.strftime('%m/%d/%y')
cols=low.columns.tolist()
cols=cols[2:]

select = Select(title="Option:", value="9Be", options=cols)

source=ColumnDataSource(data=low)

#Using 9Be as default. Will be changed when updated
mean=source.data['9Be'].mean()
plus_three_sigma=mean+(source.data['9Be'].std()*3)
minus_three_sigma=mean-(source.data['9Be'].std()*3)
plus_two_sigma=mean+(source.data['9Be'].std()*2)
minus_two_sigma=mean-(source.data['9Be'].std()*2)

tips=[("Run", "@Run"),("Concentration", "$y")]
p = figure(plot_width=1300, plot_height=800, x_range=source.data["run"], tooltips=tips, title="QC Low", x_axis_label="Run ID",y_axis_label="Concentration ng/mL")
p.line(x=source.data["run"], y=mean, line_width=1, color="black")
p.line(x=source.data["run"], y=plus_three_sigma, line_width=1, color="red")
p.line(x=source.data["run"], y=minus_three_sigma, line_width=1, color="red")
p.line(x=source.data["run"], y=minus_two_sigma, line_width=1, color="green",line_dash="dashed")
p.line(x=source.data["run"], y=plus_two_sigma, line_width=1, color="green",line_dash="dashed")
pc=p.circle(x='run', y="9Be",source=source)
p.xaxis.major_label_orientation = 1.2

callback = CustomJS(args=dict(source=source), code="""
    var data=source.data;
    data['9Be'] = data[cb_obj.value];
    source.change.emit();
""")

output_file("output.html")


select.js_on_change('value', callback)

show(row(select,p))

目前,散点图在 selecting 元素时正确更新...大部分时间(它并不总是更新。例如,如果我 select 一个元素然后尝试 select 9再一次)。但我的主要问题是,即使源应该改变,方法和标准偏差也没有更新?

您正在使用使用 show 创建的静态 HTML 文件,但您需要在当前项目更改时 运行 Python 编码。要么你必须提前 运行 Python 计算 所有 列的平均值和其他参数的代码,并将它们存储起来以备后用 CustomJS.code,或者您必须使用 bokeh serve 才能 运行 Python 回调以响应某些用户操作。

您的代码的另一个问题是您更改了 CustomJS.code 中的数据。不要那样做——您只是在覆盖 9Be 值,完全丢失它们。相反,保存每个渲染器(从 p.linep.circle 等返回的值),将渲染器传递给 CustomJS.args(就像 source 一样,您必须提供他们的一些名字),并更新相关字段而不是更新数据。在 CustomJS.code:

中应该看起来像这样
pc.glyph.y = {field: cb_obj.value};

BokehJS 需要 {field: ...} 部分 - 它由 Boken 在 Python 端自动为您创建,但您必须在 CustomJS.code 中手动应用它。 对于静态值,比如预先计算的平均值,它会是这样的:

mean_renderer.glyph.y = {value: current_mean};

如何存储 current_mean 由您决定。您可以将所有预先计算的方法存储在例如另一个数据源,只需使用 {field: ...} 更改列名称,而不是使用 {value: ...}.

更改值