从 TapTool 中选择散景 glyphs/annotations

Bokeh get selected glyphs/annotations from TapTool

对于我的项目,我需要在散景(线、多线和箭头)中添加和删除 glpyhs 和注释。我想让它尽可能具有交互性。因此,为了删除 glyph/annotation 想要 select 它,请单击鼠标,然后例如用一个按钮删除它。最小的例子看起来像这样:

import numpy as np
import random
from bokeh.plotting import figure, ColumnDataSource
from bokeh.models import Button, TapTool,Arrow,NormalHead
from bokeh.layouts import layout 

from bokeh.application import Application
from bokeh.server.server import Server
from bokeh.application.handlers.function import FunctionHandler

plot = figure(plot_height=300, plot_width=600, x_range=(0, 8), y_range=(0, 11),
                   title="Testplot", tools='save, reset, tap')

Lay = layout(children=[])

#adds the glyphs/annotaions to figure
def Click_action():
    x = np.array((random.randrange(1,10),random.randrange(1,10)))
    y = np.array((random.randrange(1,10),random.randrange(1,10)))

    source = ColumnDataSource(data=dict(x = x,
                                        y = y))

    arro = Arrow(end=NormalHead(size=5, fill_color="#C0392B"),
                 x_start=random.randrange(0,10),
                 y_start=random.randrange(0,10),
                 x_end=random.randrange(0,10),
                 y_end=random.randrange(0,10),
                 line_width=3,
                 line_color="#C0392B")

    plot.multi_line(xs=[[1,5],[1,1],[3,3],[5,5]],ys=[[5,5],[5,1],[5,1],[5,1]], color='blue', selection_color='red' )
    plot.add_layout(arro)
    plot.line(x='x',y='y', source = source,selection_color='red')
def Click_delet():
    """ Delete the selected Glyphs/Annotations"""
def make_document(doc):

    btn1 = Button(label="Click", button_type="success")

    btn2 = Button(label="Click_delet", button_type="success")
    btn1.on_click(Click_action)
    btn2.on_click(Click_delet)
    Lay.children.append(plot)
    Lay.children.append(btn1)
    Lay.children.append(btn2)
    doc.add_root(Lay)


if __name__ == '__main__':
    bkapp = {'/': Application(FunctionHandler(make_document))}
    server = Server(bkapp, port=5004)
    server.start()
    server.io_loop.add_callback(server.show, "/")
    server.io_loop.start()

我目前遇到的问题是:

  1. 我怎样才能select箭头?
  2. 如何获得所有 selected 字形和注释? (如果可能的话,没有 CoustomJS 回调,因为我不太了解 java)

  3. 是否可以select将多行作为一个字形?

我已经解决了如何从图中删除线条和箭头的问题。但是我需要存储在 plot.rendersplot.center 中的值才能删除它们,并且 link 它们到我项目中的不同 类。

  1. Bokeh 中的注释不是交互式的
  2. 请参阅下面的最小示例
  3. 没有

But I would need the value stored in plot.renders and plot.center in order to delete them and link them to different classes in my project.

理想情况下,您的工作流程应避免动态创建和删除 Bokeh 模型,尤其是字形等低级模型。如果您需要删除一个字形并添加一个具有新属性的新字形,请考虑只更改旧字形的属性。或者只是清除旧字形的数据以隐藏它。

from bokeh.io import curdoc
from bokeh.layouts import column
from bokeh.models import Button
from bokeh.plotting import figure, ColumnDataSource

line_ds = ColumnDataSource(dict(x=[0, 3, 7],
                                y=[1, 8, 2]))
multi_line_ds = ColumnDataSource(dict(xs=[[1, 5], [1, 1], [3, 3], [5, 5]],
                                      ys=[[5, 5], [5, 1], [5, 1], [5, 1]]))

p = figure(x_range=(0, 8), y_range=(0, 11), tools='save, reset, tap')

p.line('x', 'y', source=line_ds, selection_color='red')
p.multi_line('xs', 'ys', source=multi_line_ds, color='blue', selection_color='red')

b = Button(label="Delete selected", button_type="success")


def delete_rows(ds, indices):
    print(indices)
    if indices:
        print(ds.data)
        ds.data = {k: [v for i, v in enumerate(vs) if i not in set(indices)]
                   for k, vs in ds.data.items()}
        print(ds.data)


def delete_selected():
    delete_rows(line_ds, line_ds.selected.line_indices)
    delete_rows(multi_line_ds, multi_line_ds.selected.indices)


b.on_click(delete_selected)

curdoc().add_root(column(p, b))