How to remove elements from legend when they are hidden with CustomJS?

I made vbar selection via MultiSelect tool and need to optimize legend work. I don’t use bokeh server. Form data with Django and customize with CustomJS.

  1. I need to display only selected objects (cellnames in my case) in legend. Other objects should fully disappear from legend.
  2. I want to control selection only with MultiSelect. Clicking on legend elements should do nothing.
    I attached interface i’m talking about.

One solution would be to recreate legend items on each change:

import pandas as pd
from bokeh.layouts import row

import bokeh.sampledata.stocks as stocks
from bokeh.models import MultiSelect, CustomJS
from bokeh.palettes import Spectral4
from bokeh.plotting import figure, show

p = figure(plot_width=800, plot_height=250, x_axis_type="datetime")
p.title.text = 'Click on legend entries to hide the corresponding lines'

names = ["AAPL", "IBM", "MSFT", "GOOG"]
for name, color in zip(names, Spectral4):
    data = getattr(stocks, name)
    df = pd.DataFrame(data)
    df['date'] = pd.to_datetime(df['date'])
    p.line(df['date'], df['close'], line_width=2, color=color, alpha=0.8, legend_label=name, name=name)

# `p.legend` is a splattered list. It's fine to use it to set
# attributes in Python but it's not as convenient on the JS side.
legend = p.legend[0]
legend.location = "top_left"

ms = MultiSelect(options=names, value=names)
ms.js_on_change('value', CustomJS(args=dict(legend=legend),
    const {LegendItem} = Bokeh.require('models/annotations/legend_item');
    legend.items = => {
        return new LegendItem({label: {value: v},
                               renderers: [cb_obj.document.get_model_by_name(v)]});

show(row(p, ms))

Just a side note: if there’s not enough items in your MultiSelect to create a scroll bar, maybe it makes sense to not use the MultiSelect at all and just use the legend instead.