Python Bokeh CustomJS RadioGroup

时间:2017-04-11 09:11:12

标签: javascript python charts bokeh dashboard

我对Python和Pandas有相当的经验,但对于Bokeh软件包来说却是一个新手,并且在过去的几天里一直在努力完成这项任务而没有任何进展。我正在构建一个显示数据的仪表板,使用单选按钮在同一个图上选择/显示不同的行非常有用。我一直在关注这里的例子(https://github.com/bokeh/bokeh/issues/3715),我可以使用复选框来正常工作。我已将“CheckboxGroup”更改为第21行中的“RadioGroup”,以及“active”参数。结果是当我更改单选按钮的选择并且永远不会返回时,两个绘制的线都消失了。我不明白为什么CheckboxGroup工作而RadioGroup没有,考虑它们有多相似,并且它们都使用“active”事件进行回调。有人可以指出我的错误吗?

import numpy as np

from bokeh.io import show
from bokeh.layouts import widgetbox
from bokeh.models.widgets import CheckboxGroup, RadioGroup
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.layouts import column, row
from bokeh.plotting import figure

t = np.arange(0.0, 2.0, 0.01)
s = np.sin(3*np.pi*t)
c = np.cos(3*np.pi*t)

source = ColumnDataSource(data=dict(t=t, s=s, c=c))

plot = figure(plot_width=400, plot_height=400)
a = plot.line('t', 's', source=source, line_width=3, line_alpha=0.6, 
line_color='blue')
b = plot.line('t', 'c', source=source, line_width=3, line_alpha=0.6,
line_color='red')

checkbox = RadioGroup(labels=["Cosinus", "Sinus"], active=0)

checkbox.callback = CustomJS(args=dict(line0=a, line1=b), code="""   
    //console.log(cb_obj.active);
    line0.visible = false;
    line1.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;
        }
    }
""")

layout = row(plot, widgetbox(checkbox))

show(layout)

3 个答案:

答案 0 :(得分:0)

我认为使用multi_line方法绘制它更容易。然后您可以选择在回调中选择哪一行,如下所示。

import numpy as np

from bokeh.io import show
from bokeh.layouts import widgetbox
from bokeh.models.widgets import CheckboxGroup, RadioGroup
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.layouts import column, row
from bokeh.plotting import figure

t = np.arange(0.0, 2.0, 0.01)
s = np.sin(3*np.pi*t)
c = np.cos(3*np.pi*t)

source = ColumnDataSource(data=dict(t=[t]*2, s=[s,c], colors = ['red', 'blue']))

plot = figure(plot_width=400, plot_height=400)
plot.multi_line('t', 's',line_color='colors' ,source=source)

checkbox = RadioGroup(labels=["Cosinus", "Sinus"], active=0)

checkbox.callback = CustomJS(args=dict(s=source), code="""   
    s.selected['1d'].indices = [cb_obj.active]
    s.trigger('change');
""")

layout = row(plot, widgetbox(checkbox))

show(layout)

答案 1 :(得分:0)

在radioboxgroup中,一次只能有一个活动值,因此当您尝试循环整数时,for循环是无用的。这是您的代码更正

checkbox.callback = CustomJS(args=dict(line0=a, line1=b), code="""   
    line0.visible = false;
    line1.visible = false;

    if (cb_obj.active == 0) {
        line0.visible = true;
    } else if (cb_obj.active == 1) {
        line1.visible = true;
    }
""")

有一种更好的方法可以做到这一点,如果你有很多行,你可以使用"标签的长度"循环列表

line_list = [line0,line1];

lab_len=cb_obj.labels.length;

for (i=0;i<lab_len;i++) {
if (cb_obj.active == i) {
line_list[i].visible = true;
} else {
line_list[i].visible = false;
}
}

在复选框组中,&#34;有效&#34; attribute是索引列表。您只需更改if条件以使代码工作:

checkbox = CheckboxGroup(labels=["Cosinus", "Sinus"], active=[0,1])

checkbox.callback = CustomJS(args=dict(line0=a, line1=b), code="""   
    line_list = [line0,line1];

    lab_len=cb_obj.labels.length;

    for (i=0;i<lab_len;i++) {
    if (cb_obj.active.includes(i)) {
    line_list[i].visible = true;
    } else {
    line_list[i].visible = false;
    }
    }
""")

答案 2 :(得分:0)

如果您试图让用户轻松控制字形的可见性,那么从Bokeh 0.12.5开始,当用户点击图例条目时,您可以将图例设为交互式,隐藏字形或将其静音: / p>

enter image description here

如果您想完全隐藏字形,请将图例click_policy设置为"hide"

p = figure()
p.circle([1,2,3], [4,5,6], legend="foo")
p.square([1,2,3], [7,9,8], legend="bar")
p.legend.click_policy = "hide"

您还可以将策略设置为静音:

p.legend.click_policy = "mute"

但是你需要指定&#34;静音&#34;外观看起来像每个字形,例如

p.circle([1,2,3], [4,5,6], muted_alpha=0.2, legend="foo")