-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Description
This seems to be a pain point with users, and I've stumbled into as well. Resetting the whole .selected dict seems to trigger updates in most simple cases, but reliability is finicky at best with more complex selection updates. @bryevdv Your idea, not mine.
Currently the only way to spoof this type of selection function is to create multiple grouped sources and manipulate the selection/nonselection attributes, or stack multiple sources and use the filters. It starts to get out of hand when dealing with larger data sets. Rather than dealing with multiple sources, a single data source paired with a callback that sets the .selected index based on a selection within that group, and reliable plot update trigger is preferred. @clairetang6 Maybe a CDSView extension concept 7BB8 , SelectFilter?
This standalone would select groups accordingly if .selected could detect an internal change and push an update trigger.
def mod_doc(doc):
''''''
import numpy as np
from bokeh.plotting import figure
from bokeh.layouts import layout
from bokeh.models import ColumnDataSource
from bokeh.sampledata.iris import flowers
from bokeh.palettes import Spectral6
from bokeh.transform import factor_cmap
source = ColumnDataSource(flowers)
plot_size_and_tools = {
'plot_height': 500, 'plot_width': 500,
'tools':['box_select','tap','reset', 'help']
}
p1 = figure(title="Proper .selected", **plot_size_and_tools)
p1.circle(
x='petal_length', y='petal_width', source=source,
color=factor_cmap('species', palette=Spectral6[3:],
factors=list(set(flowers.species))), size=10)
def cb_change(attr,old,new):
data = source.data.copy()
selected = source.selected.copy()
species = np.asarray(data['species'])
idx = selected['1d']['indices']
if len(idx) != 0:
selected['1d']['indices'] = []
species_sel = list(set(species[idx]))
for each in species_sel:
idx = np.where(species == each)[0].tolist()
selected['1d']['indices'].extend(idx)
source.selected.update(selected)
source.on_change('selected', cb_change)
worksheet = layout([[p1]], sizing_mode='fixed')
doc.add_root(worksheet)
return doc
def main():
''''''
from tornado.ioloop import IOLoop
from bokeh.document import Document
from bokeh.application.handlers import FunctionHandler
from bokeh.application import Application
from bokeh.server.server import Server
io_loop = IOLoop.current()
doc = Document()
app = Application(FunctionHandler(mod_doc))
server = Server({'/proper.selected': app}, io_loop=io_loop, port=0)
server.start()
io_loop.add_callback(server.show,'/proper.selected')
io_loop.start()
if __name__ == '__main__':
main()
