Selection on plot with multiple lines (not multiline)

I am having trouble seeing where and how to set the selection (via a JS callback) on a plot that has two different lines plotted.

I have tried the three “indices” options but none work as desired. I see a selected_glyphs property, but that contains objects. I can’t see a simple array to populate with indexes.

Here is a simplified example, where you click the button to make the selection.

from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.models.widgets import Button
from bokeh.layouts import row
from bokeh.io import reset_output, output_file, save
import pandas as pd

data = pd.DataFrame(
data={
‘a’: [1,1,2,2,1,1],
‘b’: [2,2,3,3,2,2],
‘index’: [0,1,2,3,4,5]}
)

source = ColumnDataSource(data)

plot = figure(plot_width=400, plot_height=400)

lines = [plot.line(x=‘index’, y=col, source=source) for col in ‘ab’]

for line in lines:
line.selection_glyph = Line(line_color=‘red’)

Button_code = CustomJS(args={‘source’: source}, code=’’’
console.log(source.selected);
source.selected.indices = [1];
‘’’
)

button = Button(callback=Button_code)

output_file(r’C:\data\test.html’)
save(row(plot, button))
reset_output()

``

For anyone interested, I ended up solving my specific problem by giving the lines names (feature available in 13.0 I think), making them non-visible to begin with, passing the list of lines to the callback, and making my selection based on the name (though you could do some data attribute too).

In my case, I was wanting to link the selection in a table with the lines shown on a chart. So the callback would actually run through the selection.indices on that datatable, collate the values I used as names in the lines, run through the lines and make the line visible if its name was found in the selection.

In this example, I have just shown how to always show the line named ‘a’.

lines = [plot.line(x=‘index’, y=col, name=col, visible=False, source=source) for col in ‘ab’]

Button_code = CustomJS(args={‘lines’: lines}, code=’’’
for (i=0; i<lines.length; i++) {

if (lines[i].name == 'a') {
    lines[i].visible = true;
} else {
    lines[i].visible = false;
}

}
‘’’
)

``

Hi

I get the following ERROR trying your example:

for line in lines:

···

NameError Traceback (most recent call last)
in ()
20
21 for line in lines:
—> 22 line.selection_glyph = Line(line_color=‘red’)
23
24 Button_code = CustomJS(args={‘source’: source}, code=‘’’

NameError: name ‘Line’ is not defined

making that comment and changing the line 19 to
lines = [plot.line(x=‘index’, y=col, source=source, line_color=‘red’) for col in ‘ab’]

PKHG

Op donderdag 2 augustus 2018 09:44:38 UTC+2 schreef Kevin O’Donnell:

I am having trouble seeing where and how to set the selection (via a JS callback) on a plot that has two different lines plotted.

I have tried the three “indices” options but none work as desired. I see a selected_glyphs property, but that contains objects. I can’t see a simple array to populate with indexes.

Here is a simplified example, where you click the button to make the selection.

from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.models.widgets import Button
from bokeh.layouts import row
from bokeh.io import reset_output, output_file, save
import pandas as pd

data = pd.DataFrame(
data={
‘a’: [1,1,2,2,1,1],
‘b’: [2,2,3,3,2,2],
‘index’: [0,1,2,3,4,5]}
)

source = ColumnDataSource(data)

plot = figure(plot_width=400, plot_height=400)

lines = [plot.line(x=‘index’, y=col, source=source) for col in ‘ab’]

for line in lines:
line.selection_glyph = Line(line_color=‘red’)

Button_code = CustomJS(args={‘source’: source}, code=‘’’
console.log(source.selected);
source.selected.indices = [1];
‘’’
)

button = Button(callback=Button_code)

output_file(r’C:\data\test.html’)
save(row(plot, button))
reset_output()

``