将小部件添加到所有Bokeh子图中的切换线

时间:2017-10-26 14:01:01

标签: javascript python bokeh

所以我试图创建一个6x6网格的图,其中每个图有多行。我想添加Bokeh的CheckboxGroup小部件,以便能够为所有绘图打开和关闭线。我无法弄清楚如何将小部件链接到所有图。当我运行此代码时,小部件&所有情节我都只能为最后一个情节切换。有什么建议吗?

# 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)

1 个答案:

答案 0 :(得分:1)

在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"对于其他可能需要它的小部件。