首页 > 解决方案 > Bokeh + Jupyter - 如何在同一个 JS 回调中更新两个字形和图形

问题描述

我想使用几个小部件在 jupyter 笔记本中使用回调来更新图形及其字形(VArea 或 Lines)。

在这个问题中,它们是 2 种小部件:

我设法更新颜色或x_range成功但不能同时更新。

我的理解是 Bokeh JS 库尝试用新颜色重新绘制整个图形,并且这样做会重置 x_range 参数(即使在回调中指定)。我想强制在回调中更改颜色(callback在 MWE 中调用)中的图形更新,但到目前为止我还没有成功。

对此的正确方法是什么?

MWE

from bokeh.io import output_notebook, show
from bokeh.layouts import column, row
from bokeh.models import CustomJS, ColumnDataSource, Select, Spinner
from bokeh.plotting import figure
from bokeh.colors import Color, RGB
output_notebook()

import numpy as np

x = np.arange(0,20)
y1 = 10*np.ones_like(x)
y2 = x

indeces = [1,2]

p = figure()

source = ColumnDataSource(data=dict(x=x,y1=y1,y2=y2))

colors = [RGB(200,50,50), RGB(100,100,250)]

stack = p.varea_stack(["y"+str(i) for i in indeces], x='x', source=source, fill_color=colors, legend_label=["1", "2"])
select = Select(title="Line", value="All", options=["All"]+[str(i) for i in indeces])
spinner_xmin = Spinner(title="x_min", low=round(x[0],0), high=round(x[-1],0), step=1, value=round(x[0],2), width=150)
spinner_xmax = Spinner(title="x_max", low=round(x[0],0), high=round(x[-1],0), step=1, value=round(x[-1],2), width=150)


args = dict(
    colors = colors,
    stack = stack,
    xr = p.x_range,
    spinner_min=spinner_xmin,
    spinner_max=spinner_xmax

)

callback = CustomJS(args=args, code="""
    var k = cb_obj.value;
    
    for (var i=0; i<colors.length; i++){
        if (k != "All"){
            if (k != i+1){
            stack[i].glyph.fill_color = "rgb(0,0,0)"
            }
            else{
                stack[i].glyph.fill_color = colors[i];
            }
        }
        else{
            stack[i].glyph.fill_color = colors[i];
        }
    }
    // FORCE REPAINT/UPDATE HERE
    xr.start = spinner_xmin.value;
    xr.end = spinner_xmax.value;
""")

args2 = dict(
    xr1 = p.x_range
)
update_xmin = CustomJS(args=args2, code="""
    xr1.start = cb_obj.value
""")

update_xmax = CustomJS(args=args2, code="""
    xr1.end = cb_obj.value
""")

p.legend.location = "top_left"
select.js_on_change("value", callback)
spinner_xmin.js_on_change("value", update_xmin)
spinner_xmax.js_on_change("value", update_xmax)
c = column(row(select,spinner_xmin,spinner_xmax), p)
show(c)

标签: callbackjupyterbokeh

解决方案


推荐阅读