Hi!
I am very new to Bokeh and I am exploring it as an alternative to Plotly interactive graphs. I am running into a small issue / question when trying to use the interactive legends: in general, i work with plots that show 35 lines at the same time, so it is very common that i need to hide all and only show one or two at a time. This is quite easy to do with Plotly just by double clicking, but I cannot figure out how to do it on Bokeh - and haven’t found any answers online either.
This is some code that I am using to test. I have plotted two lines and enabled interactive legend to mute them. Since I don’t think there is a built-in way to hide all lines at the same time, I came across this option to add a custom button via JS. When I click the button, it hides or shows all lines, but this cannot be later modified by clicking on the legend. What I mean: if I hide all lines with the button, then I cannot show one of them again by clicking on the legend. Is there a way I could make this happen? Or have a similar outcome, I just need to easily isolate lines on my plots.
Thanks in advance!
from bokeh.plotting import figure, show
from bokeh.io import output_notebook
from bokeh.models import CustomJS, Button
from bokeh.layouts import column
import numpy as np
# Enable the output in the notebook
output_notebook()
fig = figure(title="Scatter Plot Example", x_axis_label='X-Axis', y_axis_label='Y-Axis')
x = np.linspace(0, 100, 500)
a1, b1 = np.random.random(2) * 10
series1 = a1 + b1 * np.sin(x)
a2, b2 = np.random.random(2)
series2 = a2 + b2 * np.cos(x)
line1 = fig.line(x, series1, color='red', legend_label='series1', muted_alpha=0.2)
line2 = fig.line(x, series2, color='blue', legend_label='series2', muted_alpha=0.2)
fig.legend.click_policy = 'mute'
# Create a button to hide/show all lines
button = Button(label="Hide All Lines", button_type="success")
callback = CustomJS(args=dict(lines=[line1, line2], button=button), code="""
let allVisible = lines.every(line => line.visible);
for (let i = 0; i < lines.length; i++) {
lines[i].visible = !allVisible;
lines[i].muted = !lines[i].visible;
}
button.label = allVisible ? 'Show All Lines' : 'Hide All Lines';
""")
button.js_on_click(callback)
layout = column(button, fig)
# Show the results
show(layout)