Rendering using BooleanFilter depends on chosen layout and if glyph shares view with DataTable

Hi :slight_smile: I am trying to filter simultaneously a table and a plot.
The rendering depends on chosen layout and whether plot shares view with table or not.
If it is not rendering, I get the error in Firefox console:
“Uncaught (in promise) TypeError: this.data is undefined”

Here is my code (see ADAPT part for adaptions):

import pandas as pd
from bokeh.plotting import figure, show
from bokeh.models import CustomJS, ColumnDataSource, CDSView, DataTable, TableColumn, CheckboxButtonGroup, Column, Row
from bokeh.models.filters import BooleanFilter

# ADAPT
# renders: use_working_layout & (use_view_for_plot True or False)
# not rendering: use_working_layout False & use_view_for_plot True
# renders: use_working_layout False & use_view_for_plot False
use_working_layout = True
use_view_for_plot = True

# create source
data = [
    {'a': 10, 'xs': [1, 2, 3, 4, 5], 'ys': [5, 7, 2, 7, 10], 'x': 1, 'y': 10},
    {'a': 100, 'xs': [1, 2, 3, 4, 5], 'ys': [2, 4, 3, 7, 6], 'x': 2, 'y': 11},
    {'a': 500, 'xs': [1, 2, 3, 4, 5], 'ys': [0.1, 0.7, 2, 2, 0.5], 'x': 3, 'y': 12},
    {'a': 100, 'xs': [1, 2, 3, 4, 5], 'ys': [1, 4, 5, 6, 2], 'x': 4, 'y': 13},
    {'a': 10, 'xs': [1, 2, 3, 4, 5], 'ys': [8, 6, 9, 3, 2], 'x': 5, 'y': 14}
]
df = pd.DataFrame(data=data)

col_to_filter = 'a'
df[col_to_filter] = df[col_to_filter].astype(str)

source = ColumnDataSource(df)

# view
boolean_filter = BooleanFilter(booleans=[True] * df.shape[0])
view = CDSView(filter=boolean_filter)

# create table
columns = []
for col in list(df.columns):
    columns.append(TableColumn(field=col, title=col, sortable=True))
data_table = DataTable(source=source, columns=columns, view=view)

# create plot
tooltips = [
    ("index", "$index"),  # shows '#' in data table
    ("(x,y)", "($x, $y)")
]
tools = "tap, pan, box_zoom, wheel_zoom, save, reset"
plot = figure(tooltips=tooltips, tools=tools)
multi_line = plot.multi_line(xs='xs', ys='ys', source=source)
if use_view_for_plot:
    multi_line.view = view

# filter widget
values = sorted(set(df[col_to_filter]))
values = [str(item) for item in values]
filter_widget = CheckboxButtonGroup(labels=values, active=list(range(len(values))))

filter_widget.js_on_change(
    "active", CustomJS(args=dict(source=source, filter=boolean_filter, col_filter=col_to_filter),
                       code="""
    const values = cb_obj.active.map(idx => cb_obj.labels[idx]);
    console.log('values:', values);
    filter.booleans = source.data[col_filter].map(v => values.includes(v));
    console.log('boolean filter:', filter.booleans);

    source.change.emit();
"""))

# create layout
if use_working_layout:
    layout = Column(Row(filter_widget, plot), data_table)  # works!
else:
    layout = Row(Column(filter_widget, data_table), plot)  # error!

show(layout)

Inspired by this Bokeh linked scatter charts with CDSView source data - 'hover_color' only works on the last glyph in figure I tried it for my original code with a duplicated source which then leads to a working rendering, but has serious drawbacks as that my displayed DataTable is not synchronised anymore with my plots. And using another layout would not be possible as then the displayed information would look horrible.

Can anyone please help me with my issue? Thank you in advance.

@DaniK I reproduced the issue myself with Bokeh 3.2 (FYI it is always advised to state a relevant version in all OSS support requests). This is clearly a bug, so please open a GitHub Issue with these details. Unfortunately I don’t have any immediate workarounds to suggest.

Thanks for looking into it. As suggested I opened an issue in github:

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.