import numpy as np
from bokeh.layouts import gridplot
from bokeh.models import CustomAction, CustomJS
from bokeh.plotting import figure, show
x = np.linspace(0, 4*np.pi, 100)
y = np.sin(x)
TOOLS = "pan,wheel_zoom,box_zoom,reset,save,box_select"
p1 = figure(title="Legend Example", tools=TOOLS)
p1.scatter(x, y, legend_label="sin(x)")
p1.scatter(x, 2*y, legend_label="2*sin(x)", color="orange")
p1.scatter(x, 3*y, legend_label="3*sin(x)", color="green")
p1.legend.title = "Markers"
p2 = figure(title="Another Legend Example", tools=TOOLS)
p2.scatter(x, y, legend_label="sin(x)")
p2.line(x, y, legend_label="sin(x)")
p2.line(x, 2*y, legend_label="2*sin(x)",
line_dash=(4, 4), line_color="orange", line_width=2)
p2.scatter(x, 3*y, legend_label="3*sin(x)",
marker="square", fill_color=None, line_color="green")
p2.line(x, 3*y, legend_label="3*sin(x)", line_color="green")
p2.legend.title = "Lines"
toggle_legend = CustomAction(
icon=".bk-tool-icon-list",
description="Toggle legend",
callback=CustomJS(
args=dict(legends=p1.legend + p2.legend),
code="""
export default ({legends}) => {
for (const legend of legends) {
legend.visible = !legend.visible
}
}
""",
),
active_callback=CustomJS(
args=dict(legends=p1.legend + p2.legend),
code="""
export default ({legends}) => {
return legends.every((legend) => legend.visible)
}
""",
),
# or alternatively use:
#
# active_callback="auto",
# active=p1.legend.visible and p2.legend.visible,
)
gp = gridplot([p1, p2], ncols=2, width=400, height=400)
gp.toolbar.tools.append(toggle_legend)
show(gp)