【问题标题】:How to interactively display and hide lines in a Bokeh plot?如何以交互方式显示和隐藏散景图中的线条?
【发布时间】:2015-11-22 02:28:18
【问题描述】:

如果能够以交互方式显示和隐藏散景图中的线条,那就太好了。说,我创建了这样的情节:

from bokeh.plotting import output_file, figure, show
from numpy.random import normal, uniform

meas_data_1 = normal(0, 1, 100)
meas_data_2 = uniform(-0.5, 0.5, 100)

output_file("myplot.html", title="My plot")
fig = figure(width=500, plot_height=500)

fig.line(x=range(0, len(meas_data_1)), y=meas_data_1)
fig.line(x=range(0, len(meas_data_2)), y=meas_data_2)

show(fig)

如何添加以交互方式启用/禁用两行之一的可能性?

我知道这在愿望清单上(请参阅this feature request),但这听起来不会太快实施。

我的印象是使用CheckBoxGroupself-defined callback 应该可以做到这一点,但不幸的是,这个回调必须用JavaScript 编写,我完全没有这方面的经验。

【问题讨论】:

    标签: javascript python bokeh


    【解决方案1】:

    编辑:从 Bokeh 0.12.5 开始,交互式图例现已内置到库中,请参阅 https://bokeh.github.io/blog/2017/4/5/release-0-12-5/


    这似乎有望在某个时候作为交互式图例实施: https://github.com/bokeh/bokeh/issues/3715

    目前(v0.12.1),有一个在复选框上使用 CustomJS 的示例来实现此目的: https://github.com/bokeh/bokeh/pull/4868

    相关代码:

    import numpy as np
    
    from bokeh.io import output_file, show
    from bokeh.layouts import row
    from bokeh.palettes import Viridis3
    from bokeh.plotting import figure
    from bokeh.models import CheckboxGroup, CustomJS
    
    output_file("line_on_off.html", title="line_on_off.py example")
    
    p = figure()
    props = dict(line_width=4, line_alpha=0.7)
    x = np.linspace(0, 4 * np.pi, 100)
    l0 = p.line(x, np.sin(x), color=Viridis3[0], legend="Line 0", **props)
    l1 = p.line(x, 4 * np.cos(x), color=Viridis3[1], legend="Line 1", **props)
    l2 = p.line(x, np.tan(x), color=Viridis3[2], legend="Line 2", **props)
    
    checkbox = CheckboxGroup(labels=["Line 0", "Line 1", "Line 2"],
                             active=[0, 1, 2], width=100)
    checkbox.callback = CustomJS(args=dict(l0=l0, l1=l1, l2=l2, checkbox=checkbox),
                                 lang="coffeescript", code="""
    l0.visible = 0 in checkbox.active;
    l1.visible = 1 in checkbox.active;
    l2.visible = 2 in checkbox.active;
    """)
    
    layout = row(checkbox, p)
    show(layout)
    

    【讨论】:

    • 感谢编辑!附带问题:有没有办法使用渲染器列表而不是单独的变量来做到这一点?我想一次显示/隐藏一组大约 30 个不同的渲染器。
    • 可能,您应该能够将列表作为 args dict, IIRC 中的值之一传递。
    • 无法让它工作,散景提升ValueError: expected an element of Dict(String, Instance(Model)), got {'renderers': [<bokeh.models.renderers.GlyphRenderer object at 0x11db30090>, ...], 'checkbox': <bokeh.models.widgets.groups.CheckboxButtonGroup object at 0x11c4adc90>}
    • 作为一种解决方法,我为每个渲染器提供了我希望能够以交互方式隐藏name="hideable"。然后,我将plot=p 传递给args 字典,而不是渲染器列表。我当时的咖啡脚本代码是:rends = plot.select("hideable"); rends[i].visible = i in checkbox.active for i in [0...rends.length];
    • 从 0.12.5 开始,您只需使用 plot.legend.click_policy = "hide" 即可。
    【解决方案2】:

    我可能错了,但在我看来,各种行没有可用的 ID,隐藏它们的一种方法是 document.getElementById("idSelected").style.visibility = "hidden";

    由于CheckBoxGroup 没有可用的回调,我决定使用Select。 我可以在CustomJS 中获得选定的来源,但仅此而已:

    from bokeh.io import vform
    from bokeh.models import CustomJS, ColumnDataSource, Select
    from bokeh.plotting import output_file, figure, show
    from numpy.random import normal, uniform
    
    meas_data_1 = normal(0, 1, 10)
    meas_data_2 = uniform(-0.5, 0.5, 10)
    
    x1 = range(0, len(meas_data_1))
    y1 = meas_data_1
    source1 = ColumnDataSource(data=dict(x=x1, y=y1))
    x2 = range(0, len(meas_data_2))
    y2 = meas_data_2
    source2 = ColumnDataSource(data=dict(x=x2, y=y2))
    
    
    
    output_file("myplot.html", title="My plot")
    fig = figure(width=500, plot_height=500)
    
    fig.line('x', 'y', source=source1, line_width=3, line_alpha=0.6)
    fig.line('x', 'y', source=source2, line_width=3, line_alpha=0.6)
    
    select = Select(title="Option:", options=["source1", "source2"])
    
    select.callback = CustomJS(args=dict(source1=source1, source2=source2, select=select), code="""
    
            console.log(select.attributes.value);
        """)
    
    
    
    show(vform(fig, select))
    

    也许您可以根据所选内容“调整”CustomJS 中的数据,使其全部为 0,或者您是否可以访问 line_width 属性并将其设置为 0,但这几乎就是我能想到的全部。

    【讨论】:

    • 很抱歉投了反对票,0.12.1 的新答案反映了最新信息/新功能,使这变得更加简单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-22
    • 2021-12-15
    • 2015-10-03
    • 1970-01-01
    • 2014-03-23
    相关资源
    最近更新 更多