我正在尝试在bokeh中实现复选框,其中每个复选框应显示/隐藏与其关联的行。我知道可以通过图例实现此目的,但是我希望这种效果可以同时出现在两个情节中。此外,图例也应更新。在下面的示例中,出现复选框,但不执行任何操作。我显然不了解如何更新用作源的de dataframe。感谢您的帮助。
from bokeh.io import show, curdoc
from bokeh.models import HoverTool, ColumnDataSource, Legend
from bokeh.plotting import figure
from bokeh.palettes import Category10
from bokeh.models.widgets import CheckboxGroup
from bokeh.layouts import row
import pandas as pd
def update(atrr, old, new):
lines_to_plot = [checkbox_group.labels[i] for i in checkbox_group.active]
cols = ['x']
for label in lines_to_plot:
cols += [label + 'y']
cols += [label]
newdf = df0[cols]
source.data.update(ColumnDataSource(newdf))
df0 = pd.DataFrame({'x': [1, 2, 3], 'Ay' : [1, 5, 3], 'A': [0.2, 0.1, 0.2], 'By' : [2, 4, 3], 'B':[0.1, 0.3, 0.2]})
columns = ['A', 'B']
checkbox_group = CheckboxGroup(labels=columns, active=[0, 1])
tools_to_show = 'box_zoom,save,hover,reset'
p = figure(plot_height =300, plot_width = 1200,
toolbar_location='above',
tools=tools_to_show)
legend_it = []
color = Category10[10]
columns = ['A', 'B']
source = ColumnDataSource(df0)
for i, col in enumerate(columns):
c = p.line('x', col, source=source, name=col, color=color[i])
legend_it.append((col, [c]))
legend = Legend(items=legend_it, location=(5,114))#(0, -60))
p.add_layout(legend, 'right')
hover = p.select(dict(type=HoverTool))
hover.tooltips = [("Name","$name"), ("Aux", "@$name")]
hover.mode = 'mouse'
layout = row(p,checkbox_group)
checkbox_group.on_change('active', update)
curdoc().add_root(layout)
答案 0 :(得分:1)
您将必须手动管理LegendItem
个对象。这是一个完整的示例:
import numpy as np
from bokeh.io import curdoc
from bokeh.layouts import row
from bokeh.palettes import Viridis3
from bokeh.plotting import figure
from bokeh.models import CheckboxGroup, Legend, LegendItem
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], **props)
l1 = p.line(x, 4 * np.cos(x), color=Viridis3[1], **props)
l2 = p.line(x, np.tan(x), color=Viridis3[2], **props)
legend_items = [LegendItem(label="Line %d" % i, renderers=[r]) for i, r in enumerate([l0, l1, l2])]
p.add_layout(Legend(items=legend_items))
checkbox = CheckboxGroup(labels=["Line 0", "Line 1", "Line 2"], active=[0, 1, 2], width=100)
def update(attr, old, new):
l0.visible = 0 in checkbox.active
l1.visible = 1 in checkbox.active
l2.visible = 2 in checkbox.active
p.legend.items = [legend_items[i] for i in checkbox.active]
checkbox.on_change('active', update)
layout = row(checkbox, p)
curdoc().add_root(layout)