基于小工具选择的散景图显示/隐藏系列

时间:2018-04-14 05:50:35

标签: python bokeh

鉴于以下散景图(此代码必须在jupyter笔记本中运行):

from bokeh.io import output_notebook, show
from bokeh.plotting import figure
from bokeh.palettes import Dark2_5 as palette
from bokeh.layouts import widgetbox, row, column
from bokeh.models.widgets import CheckboxButtonGroup
import itertools
import numpy as np

output_notebook()

# create a new plot (with a title) using figure
p = figure(plot_width=800, plot_height=400, title="My Line Plot")

start = 10.0
x = range(20)
colors = itertools.cycle(palette) 
nseries = 50

# add a line renderer
for n in range(nseries):
    y = np.cumsum(np.random.randn(1,20))
    p.line(x, y, line_width=1, legend=str(n), color=next(colors))

p.legend.location = "top_left"
p.legend.click_policy="hide"

checkbox_button_group = CheckboxButtonGroup(
        labels=[str(n) for n in range(nseries)], active=[0, 1])

show(column([p, checkbox_button_group])) # show the results

生成如下图表:

enter image description here

如何连接复选框按钮以显示/隐藏图表上的相关系列?

注意: 我知道我可以点击图例来达到这个效果。但是,我想绘制比传奇可以显示更多的系列(例如它只显示截图中的13个系列)。显然,人们在任何时候都只会展示10个系列,否则很难看到信息。

2 个答案:

答案 0 :(得分:0)

这是我的尝试。虽然感觉很笨,但有更好的解决方案吗?另外,如果在加载绘图时如何自动调用我的回调,那么系列[0,1,2,3]只能被激活?

from bokeh.io import output_notebook, show
from bokeh.plotting import figure
from bokeh.palettes import Dark2_5 as palette
from bokeh.layouts import widgetbox, row, column
from bokeh.models.widgets import CheckboxButtonGroup
import itertools
import numpy as np

output_notebook()

# create a new plot (with a title) using figure
p = figure(plot_width=800, plot_height=400, title="My Line Plot")

start = 10.0
x = range(20)
colors = itertools.cycle(palette) 
nseries = 50

series = []

# add a line renderer
for n in range(nseries):
    y = np.cumsum(np.random.randn(1,20))
    series.append(p.line(x, y, line_width=1, legend=str(n), color=next(colors)))

p.legend.location = "top_left"
p.legend.click_policy="hide"

js = ""
for n in range(nseries):
    js_ = """
        if (checkbox.active.indexOf({n}) >-1) {{
            l{n}.visible = true
        }} else {{
            l{n}.visible = false
        }} """
    js += js_.format(n=n)

callback = CustomJS(code=js, args={})
checkbox_button_group = CheckboxButtonGroup(labels=[str(n) for n in range(nseries)], active=[0,1,2,3], callback=callback)
callback.args = dict([('l{}'.format(n), series[n]) for n in range(nseries)])
callback.args['checkbox'] = checkbox_button_group

show(column([p, checkbox_button_group])) # show the results

答案 1 :(得分:0)

你的解决方案很好。 这是一个更紧凑的js回调,依赖于使用" name"编号的行。属性

from bokeh.io import output_notebook, show
from bokeh.plotting import figure
from bokeh.palettes import Dark2_5 as palette
from bokeh.layouts import widgetbox, row, column
from bokeh.models import CheckboxButtonGroup, CustomJS
import itertools
import numpy as np

# create a new plot (with a title) using figure
p = figure(plot_width=800, plot_height=400, title="My Line Plot")

start = 10.0
x = range(20)
colors = itertools.cycle(palette) 
nseries = 50

# add a line renderer
for n in range(nseries):
    y = np.cumsum(np.random.randn(1,20))
    p.line(x, y, line_width=1, legend=str(n), color=next(colors), name=str(n))

p.legend.location = "top_left"
p.legend.click_policy="hide"

checkbox_button_group = CheckboxButtonGroup(
        labels=[str(n) for n in range(nseries)], active=[])

code = """
active = cb_obj.active;
rend_list = fig.renderers;

for (rend of rend_list) {
    if (rend.name!==null) {
        rend.visible = !active.includes(Number(rend.name));
    }
}
"""

checkbox_button_group.callback = CustomJS(args={'fig':p},code=code)

show(column([p, checkbox_button_group])) # show the results

如果你想通过关键字隐藏线组来使它们在他们的" name"中共享那些线路,这也很有用。属性

以下是使用散景服务器的方法:

from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.palettes import Dark2_5 as palette
from bokeh.layouts import column
from bokeh.models import CheckboxButtonGroup, CustomJS
import itertools
import numpy as np

# create a new plot (with a title) using figure
p = figure(plot_width=800, plot_height=400, title="My Line Plot")

start = 10.0
x = range(20)
colors = itertools.cycle(palette) 
nseries = 50

# add a line renderer
line_list = []
for n in range(nseries):
    y = np.cumsum(np.random.randn(1,20))
    line_list += [p.line(x, y, line_width=1, legend=str(n), color=next(colors))]

p.legend.location = "top_left"
p.legend.click_policy="hide"

checkbox_button_group = CheckboxButtonGroup(labels=[str(n) for n in range(nseries)], active=[])

def update(attr,old,new):
    for lineID,line in enumerate(line_list):
        line.visible = lineID in new

checkbox_button_group.on_change('active',update)

curdoc().add_root(column([p, checkbox_button_group]))

def init_active():
    checkbox_button_group.active = range(3)

curdoc().add_timeout_callback(init_active,1000)