Bokeh从TapTool获得选定的字形/注释

问题描述 投票:0回答:1

对于我的项目,我需要添加和删除bokeh中的glpyhs和注解(线,多线和箭头)。我想使其尽可能地互动。所以为了删除一个字形/注释,要用鼠标单击选择它,然后例如使用按钮将其删除。最小的示例如下所示:

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. 如何选择箭头?
  2. 如何获取所有选定的字形和注释? (如果可能的话,没有CoustomJS回调,因为我不太了解Java)

  3. 是否可以将多行选择为一个字形?

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

python bokeh
1个回答
0
投票
  1. 注解在Bokeh中不是交互式的
  2. 请参见下面的最小示例

但是我需要存储在plot.renders和plot.center中的值才能删除它们并将它们链接到项目中的不同类。

理想情况下,您的工作流应该放弃动态创建和删除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))
© www.soinside.com 2019 - 2024. All rights reserved.