I’ve set up a legend and it all works fine until I start using a slider to filter results and it suddenly thinks it’s in a nightclub. I think it might be due to it referencing fields from another dictionary with lists of a different length but the factor_cmap works as expected for coloring the circles. Here’s a simplified version of what I’m working with:
from bokeh.plotting import figure, show
from bokeh.models import Slider, CustomJSFilter, CDSView, ColumnDataSource, CustomJS, LegendItem
from bokeh.layouts import column, layout
from bokeh.transform import factor_cmap
data = dict(Apples=[97, 34, 23, 6, 26, 97, 21, 92, 73, 10, 92, 14, 77, 4, 25, 48, 26, 39, 93],
Bananas=[87, 63, 56, 38, 57, 63, 73, 56, 30, 23, 66, 47, 76, 15, 80, 78, 69, 87, 28],
Oranges=[21, 65, 86, 39, 32, 62, 46, 51, 17, 79, 64, 43, 54, 50, 47, 63, 54, 84, 79],
Category = ['A', 'B', 'B', 'C', 'A', 'C', 'B', 'C', 'C', 'B', 'A', 'A', 'B', 'B', 'A', 'C', 'C', 'C', 'C'])
colordict = dict(Colors = ['red', 'green', 'blue'], Categories = ['A', 'B', 'C'] )
source = ColumnDataSource(data=data)
MinApples = Slider(start=0, value=50, end=100, step=1)
MinApples.js_on_change('value', CustomJS(args=dict(source=source), code="""source.change.emit()"""))
custom_filter = CustomJSFilter(args=dict(source=source, MinApples=MinApples), code='''
var indices = [];
for (var i = 0; i < source.get_length(); i++){
if (source.data['Apples'][i] > MinApples.value){
indices.push(true);
} else {indices.push(false); } }
return indices;''')
view = CDSView(source=source, filters=[custom_filter])
p = figure()
p.circle('Oranges', 'Bananas', source=source, view=view, size=20, legend_field = 'Category', fill_color = factor_cmap('Category', palette = colordict['Colors'], factors = colordict['Categories']))
controls = [MinApples]
l = layout([[controls, p]], sizing_mode="stretch_both")
show(l)
Could someone please help me understand what I might be doing wrong?
Also, I’m trying to figure out how to disable legend fields when they’re not being used (eg. set slider to 96 and C isn’t shown but still present in legend), like this post asked back in '16. The response at the time was that it can be programmed explicitly through some code I didn’t understand, and that major improvements were coming. Given that answer was from 0.12.2 and we’re now on 1.40 is there now a simpler way to do this?
Thanks for the help!