CDSView associated with LegendItem in legend box

Hello,

Is there a way to set opacity level of certain legend item from legend box? When toggling the visbility of graph plotted and fitlered by CDSView using MultiChoice widget, I notice the legend item is also toggled even though part of graph is still presented in diagram. As the picture below and code snippet, ‘property2’ data has both ‘option1’ and ‘option2’, though data graph filtered with option2 value is still presented in graph, the ‘property2’ in legend box is shown as ‘hidden’ while it’s still visible with the graph that has subset data ‘option2’

When checking LegendItem class, I found only ‘visible’ attribute which does not really tackle the issue of text opacity in legend box. I’m using bokeh version 2.4.3 but with latest version I also don’t find any change between the versions.

import pandas
import itertools
from bokeh.layouts import column, row
from bokeh.plotting import figure, show
from bokeh.plotting import figure, Figure
from bokeh.palettes import Dark2_7 as palette
from bokeh.models import (HoverTool, ColumnDataSource, Range1d, CheckboxGroup, CustomJS, CDSView,
                          GroupFilter)

data = {
    "property1": [
        {"x": 1, "y": 2, "option": "option1"},
        {"x": 2, "y": 4, "option": "option1"},
        {"x": 5, "y": 6, "option": "option1"},
    ],
    "property2": [
        {"x": 6, "y": 3, "option": "option1"},
        {"x": 3, "y": 2, "option": "option2"},
        {"x": 3, "y": 3, "option": "option1"},
        {"x": 5, "y": 8, "option": "option2"},
    ],
}

filter_data = {}

options = ["option1", "option2"]
fig = figure()
for item, color in zip(data.items(), itertools.cycle(palette)):
    property_name, records = item
    x = [item['x'] for item in records]
    y = [item['y'] for item in records]
    option_list = [item['option'] for item in records]
    df = pandas.DataFrame(list(zip(x, y, option_list)), columns=["x", "y", "option_list"])

    data_src = ColumnDataSource(df)
    views = [CDSView(source=data_src,
                        filters=[GroupFilter(column_name='option_list', group=label)]) \
                for label in options]
    filter_data[property_name] = []
    for view in views:
        scatter = fig.step(x="x", y="y", source=data_src,color = color, legend_label=property_name, name=property_name, view = view)
        filter_data[property_name].append(scatter)
options_checkbox = CheckboxGroup(labels=options,
                                active=list(range(len(options))))
# Checkbox callback to filter data based on selected paths
checkbox_callback = CustomJS(args=dict(filtered_view_renderers=filter_data),
                                 code="""
       const selected_options = cb_obj.active;
        for (let [property, renderers] of Object.entries(filtered_view_renderers)) {
            for(let i = 0, j=0; i < renderers.length; ++i){
                renderers[i].visible = (i == selected_options[j]);
                if(i == selected_options[j]) j++;
            }
        }
        """)

options_checkbox.js_on_change('active', checkbox_callback)
fig.legend.click_policy="hide"
fig.add_layout(fig.legend[0], 'right')
show(row(options_checkbox, fig))

There is not currently any public API to control the alpha of individual legend items. There are some things that can cause a legend item to “mute” but these are all a result of manual UI interactions, i.e. clicking on a legend item with the appropriate click policy set on the legend.

Thanks for quick response. I understand that the legend items can be muted or hidden due to the click_policy set on the legend as hide. But in my case, I need to use CheckboxGroup with CustomJS to toggle the visibility of subsets of data associated with a single legend item. The issue shows when some subsets of data linked to a legend item are still visible on the graph; the legend item itself gets ‘muted’ or appears inactive, which is misleading since not all the data is hidden.
So is there a way to associate the ‘CustomJS’ functionality with the legend’s click_policy interaction, such that the legend item’s state accurately reflects whether all, some, or none of its subsets are visible? Or is there any plan to improve legend box or LegendItem class in next version? Thanks

No, there is only what happens in response to clicks, which is all handled internally.

Or is there any plan to improve legend box or LegendItem class in next version?

As far as I know, no-one has ever made any issue regarding this, so no, there is not currently any plan to implement anything. If you’d like to propose it as a new feature, then the appropriate step would be to submit a GitHub Issue with detailed requirements for the use-case. But I can’t make any speculation about when any future development might actually be happen.