散景通过小部件更改选择字形属性

Bokeh change selection glyph properties via widget

我有一个散景图,我希望能够在其中更改所选点的颜色以反映这些点(在代码的另一部分中不在本示例中)是否会被添加到或从列表中减去标记的数据点。问题是我无法让绘图使用新的选择颜色,即使正在触发回调并按应有的方式更改其他所有内容。

我知道有人提出了类似的问题 ,但我对 Bokeh 完全陌生,不知道如何将其应用于选择字形。

import numpy as np

from bokeh.io import curdoc
from bokeh.layouts import row
from bokeh.models import Circle, Dropdown, ColumnDataSource
from bokeh.plotting import figure

N = 200
x = np.linspace(0, 4*np.pi, N)
y = np.sin(x)
source = ColumnDataSource(data = dict(x = x, y = y))

dropdown_dict = {'green': 'Add', 'red': 'Subtract'}

fig = figure(
    tools="box_select,reset",
    active_drag='box_select'
)
renderer = fig.circle(
    'x',
    'y',
    source=source,
    line_color=None,
    fill_color='black'
)
renderer.selection_glyph = Circle(fill_alpha=1, fill_color="green", line_color=None)
renderer.nonselection_glyph = Circle(fill_alpha=1, fill_color="black", line_color=None)

def dropdown_handler(event):
    color = event.item
    renderer.selection_glyph = Circle(fill_alpha=1, fill_color=color, line_color=None)
    mode = dropdown_dict[color]
    select_mode_dropdown.label = f"Selection mode: {mode}"
    print(f"Selection color changed to {color}.")

select_mode_dropdown = Dropdown(
    label='Selection mode: Add',
    menu=[(dropdown_dict[key], key) for key in dropdown_dict]
)
select_mode_dropdown.on_click(dropdown_handler)

curdoc().add_root(row(select_mode_dropdown,fig))

我终于找到了答案。情节没有改变,因为我试图定义一个全新的选择字形。相反,如果我只是更新现有 selection_glyph 的 fill_color 属性,选择颜色会根据需要更改。

import numpy as np

from bokeh.io import curdoc
from bokeh.layouts import row
from bokeh.models import Circle, Dropdown, ColumnDataSource
from bokeh.plotting import figure

N = 200
x = np.linspace(0, 4*np.pi, N)
y = np.sin(x)
source = ColumnDataSource(data = dict(x = x, y = y))

dropdown_dict = {'green': 'Add', 'red': 'Subtract'}

fig = figure(
    tools="box_select,reset",
    active_drag='box_select'
)
renderer = fig.circle(
    'x',
    'y',
    source=source,
    line_color=None,
    fill_color='black'
)
renderer.selection_glyph = Circle(fill_alpha=1, fill_color="green", line_color=None)
renderer.nonselection_glyph = Circle(fill_alpha=1, fill_color="black", line_color=None)

def dropdown_handler(event):
    color = event.item
    renderer.selection_glyph.update(fill_color=color)
    mode = dropdown_dict[color]
    select_mode_dropdown.label = f"Selection mode: {mode}"
    print(f"Selection color changed to {color}.")

select_mode_dropdown = Dropdown(
    label='Selection mode: Add',
    menu=[(dropdown_dict[key], key) for key in dropdown_dict]
)
select_mode_dropdown.on_click(dropdown_handler)

curdoc().add_root(row(select_mode_dropdown,fig))