添加小部件以切换所有散景子图中的线条

Adding widgets to toggle lines in all Bokeh subplots

所以我正在尝试创建一个 6x6 的地块网格,其中每个地块都有多条线。我想添加 Bokeh 的 CheckboxGroup 小部件,以便能够为所有绘图打开和关闭线条。我无法弄清楚如何 link 将小部件 所有 图。当我 运行 编写小部件和所有绘图时,我只能切换最后一个绘图。有什么建议吗?

# create a list of subplots to iterate over 
ps = [figure(background_fill_color='#DFDFE5', plot_width=200, 
                            plot_height=200) for i in range(36)] 

for i in range(len(ps)):
    # link the range of first plot with every other plot
    ps[i].x_range = ps[0].x_range
    ps[i].y_range = ps[0].y_range

    # axes labels
    ps[i].yaxis.axis_label = 'amplitude'
    ps[i].xaxis.axis_label = 'age'

    # plot data -- xaxis_arr & na are my data arrays
    a = ps[i].line(xaxis_arr, na[0][i][2], line_width=2, color='#1f77b4')
    b = ps[i].line(xaxis_arr, na[1][i][2], line_width=2, color='#ff7f0e')
    c = ps[i].line(xaxis_arr, na[2][i][2], line_width=2, color='#2ca02c')
    ps[i].title.text = i

    customJScode = """
        console.log(cb_obj.active);
        line0.visible = false;
        line1.visible = false;
        line2.visible = false;

        for (i in cb_obj.active) {
            //console.log(cb_obj.active[i]);
            if (cb_obj.active[i] == 0) {
                line0.visible = true;
            } else if (cb_obj.active[i] == 1) {
                line1.visible = true;
            } else if (cb_obj.active[i] == 2) {
                line2.visible = true;
            }
        }
    """

    callback = CustomJS(code=customJScode, args={} )
    checkbox = CheckboxGroup(labels=["toggleLine1", "toggleLine2", "toggleLine3"], 
                             active=[0,1,2], callback=callback)

    callback.args = dict(line0=a, line1=b, line2=c, checkbox=checkbox)

myplots = gridplot(ps, ncols=6)


layout = column(myplots, widgetbox(checkbox))
show(layout)

在 for 循环的每一步,您都在用新代码和新参数覆盖复选框的回调属性,这就是为什么它仅适用于最后一行。 在你的 for 循环中,你应该填充行列表,这样你就可以在循环之后将它们作为参数传递给你的 CustomJS 回调。然后你需要你的 customJS 代码来一次处理所有的行。

这是一个例子:

from bokeh.io import show
from bokeh.plotting import figure
from bokeh.models import CheckboxGroup, CustomJS
from bokeh.layouts import gridplot
import numpy as np

figlist = [figure(title='Figure '+str(i),plot_width=200,plot_height=200) for i in range(6)]

x=np.arange(10)

linelist=[]
for fig in figlist:
    line0 = fig.line(x,x,color='blue')
    line1 = fig.line(x,x[::-1],color='red')
    line2 = fig.line(x,x**2,color='green')

    linelist+=[[line0,line1,line2]]

checkbox = CheckboxGroup(labels=['line0','line1','line2'],active=range(3))

iterable = [elem for part in [[('_'.join(['line',str(figid),str(lineid)]),line) for lineid,line in enumerate(elem)] for figid,elem in enumerate(linelist)] for elem in part]

checkbox_code = ''.join([elem[0]+'.visible=checkbox.active.includes('+elem[0].split('_')[-1]+');' for elem in iterable])

checkbox.callback = CustomJS(args={key:value for key,value in iterable+[('checkbox',checkbox)]}, code=checkbox_code)

grid = gridplot([figlist[:3]+[checkbox],figlist[3:]])

show(grid)

我还有更复杂的示例代码,在 my bitbucket repository

上经常使用行可见性切换

你不需要将复选框作为参数传递给它自己的回调(你可以只使用cb_obj),只是我经常重复使用相同的"iterable"和"checkbox_code" 对于可能需要它的其他小部件。