Issue with Custom Coordinate Names and Bokeh Scatter Plot Selections

Hello !! This is the output of bokeh info

Python version        :  3.11.9 | packaged by Anaconda, Inc. | (main, Apr 19 2024, 16:40:41) [MSC v.1916 64 bit (AMD64)]
Tornado version       :  6.4.1
Bokeh version         :  3.5.0rc2
node.js version       :  v20.14.0
npm version           :  10.7.0
Operating system      :  Windows-10-10.0.22631-SP0

I am trying to set colors for a selection using scatter in Bokeh. However, the samples disappear when I use names other than “x” and “y” for the coordinates. Will this work as intended, or is this a regression? This issue also occurs in version 3.4.2.

import numpy as np
from bokeh.io import curdoc
from bokeh.models import ColumnDataSource, Scatter
from bokeh.plotting import figure
from bokeh.models.tools import (WheelZoomTool, ResetTool, LassoSelectTool)

initial_data = {
    'xx': np.random.rand(100),
    'yx': np.random.rand(100)
}
source = ColumnDataSource(data=initial_data)

p = figure(
    title='title',
    width=200,
    height=200,
    tools='',
)
r = p.scatter(
    'xx', 'yx',
    source=source,
    line_color='black',
    fill_color='green',
    fill_alpha=1.0,
    line_alpha=1.0,
    nonselection_line_color='black',
    nonselection_fill_color='green',
    nonselection_fill_alpha=1.0,
    nonselection_line_alpha=1.0,
)
r.selection_glyph = Scatter(
    marker="circle",
    line_color='red',
    line_alpha=1.0,
    fill_color='yellow',
)

tools = (
    LassoSelectTool(),
    WheelZoomTool(),
    ResetTool()
)

p.add_tools(*tools)

def selection_callback(attr, old, new):
    print(f'>> NEW: {new}')

source.selected.on_change('indices', selection_callback)

curdoc().add_root(p)

There seems to be some issues with selection glyphs specified explicitly in this way (even in 3.4.x releases). I have filed this issue, which may be the same issue or at least related:

Explicit selection glyph example broken · Issue #13957 · bokeh/bokeh · GitHub

I would say using explicit glyphs like this is at least a little uncommon. The following reformulation of your code works for me, in case it is an option:

r = p.scatter(
    'xx', 'yx',
    source=source,
    line_color='black',
    fill_color='green',
    fill_alpha=1.0,
    line_alpha=1.0,

    # use these parameters instead
    selection_line_color='red',
    selection_fill_color='yellow',

    nonselection_line_color='black',
    nonselection_fill_color='green',
    nonselection_fill_alpha=1.0,
    nonselection_line_alpha=1.0,
)
1 Like

The Scatter model defaults to

  x = Field(field='x', transform=Unspecified, units=Unspecified),
  y = Field(field='y', transform=Unspecified, units=Unspecified))

and you have to adapt it, if your CDS does not use x and y.

Adding two lines to Scatter will fix your code.

r.selection_glyph = Scatter(
    marker="circle",
    line_color='red',
    line_alpha=1.0,
    fill_color='yellow',
    x='xx',
    y='yy'
)

Edit:
FYI: running your code and checking the js console, you can see the error message below, which can give a hint.

[bokeh 3.4.2] attempted to retrieve property array for nonexistent field 'x'
1 Like

Those are the defaults, but I’d still regard this as a current bug. The values for the sub-glyphs should be getting inherited from the main glyph.

1 Like