【问题标题】:How to select all the points accross all the Glyphs inside a Plot with the Lasso or the Box Tool?如何使用套索或方​​框工具选择绘图内所有字形中的所有点?
【发布时间】:2018-02-15 16:57:04
【问题描述】:

我有一个带有多个字形的图 (figure)(由 plot.circle 绘制)我想同时选择所有图层。我为每个circle 应用了一个CDSFilter。我也使用legend 来隐藏或显示它们。我想要做的是只选择可见的字形点。

# [...]

plot = figure(
    width=600,
    height=600,
    x_range=x_range,
    y_range=y_range,
    x_axis_label='X',
    y_axis_label='Y',
    tools='',                    # they are added later
)

for key in flags:
    view = CDSView(source=self.source, filters=[IndexFilter(flags[key])])

    g = plot.circle(
        x='X', y='Y',
        size=5,
        fill_color=colors[key],
        legend='FLAG {}'.format(key),
        line_color=None,
        selection_color='red',
        source=self.source,
        view=view,
    )
    g.nonselection_glyph = None  # avoids to alter the color of the nonselected points

plot.legend.location = "top_left"
plot.legend.click_policy = "hide"

# [...]

lasso_select = LassoSelectTool(
    # renderers=self.glyph_rends,       # default >> all renderers inside the plot, this is not working either
    select_every_mousemove=False,
)
tools = (
    wheel_zoom, pan, box_zoom, box_select, lasso_select,
    crosshair, tap, save, reset, hover
)
plot.add_tools(*tools)

正如您在图像中看到的,仅选择了绿点,未选择蓝点。当前选择以红色绘制。如果我用图例上的按钮隐藏绿色点,那么我可以选择蓝色点。如果我使用 Tap 工具,那么它会按预期工作,即使我使用 Lasso Tool 仅选择一个点。

更新

我已发帖an issue on the Git Hub Project

【问题讨论】:

    标签: python python-3.x plot bokeh


    【解决方案1】:

    已解决的问题

    看来这个问题已经在 master 分支中解决了。因此,我正在使用从 master 构建的版本 0.12.14+25.g675aacf72 对其进行测试,并且运行良好。 0.12.15dev1 版本也已发布,我相信该版本也已修复此问题。

    以前的解决方案

    在主分支上解决此问题之前,我找到了一种解决方法。我创建了一个新的圆形字形,将整个 ColumnDataSource 绘制在其余字形的顶部

    from bokeh.models import Button, ColumnDataSource, Circle, CDSView, IndexFilter
    from bokeh.models.tools import LassoSelectTool
    from bokeh.models.glyphs import MultiLine, Line
    from bokeh.palettes import Reds3
    from bokeh.layouts import column
    from bokeh.plotting import curdoc, figure
    import numpy as np
    
    plot_1 = figure(
        width=400,
        height=400,
        tools="pan,box_zoom,box_select,wheel_zoom,tap,save,reset,crosshair",
    )
    
    x = list(range(0,200))
    y = np.random.random_integers(200, size=(200))
    
    source = ColumnDataSource(data=dict(x=x, y=y))
    
    selection = list(np.random.random_integers(100, size=(20)))
    view = CDSView(
        source=source,
        filters=[IndexFilter(x[100:])]
    )
    
    circle = plot_1.circle(
        x='x',
        y='y',
        size=5,
        fill_alpha=1,
        fill_color='orange',
        line_color=None,
        selection_color=Reds3[0],
        source=source,
        view=view,
        legend='FLAG 1',
    )
    circle.selection_glyph = Circle(
        fill_alpha=1.0, # transparent
        line_color=None,
        fill_color='orange',
    )
    circle.nonselection_glyph = Circle(
        fill_alpha=1.0,
        line_color=None,
        fill_color='orange',
    )
    
    view = CDSView(
        source=source,
        filters=[IndexFilter(
            x[:100]
        )]
    )
    
    circle_2 = plot_1.circle(
        x='x',
        y='y',
        size=5,
        fill_alpha=1,
        fill_color='blue',
        line_color=None,
        selection_color=Reds3[0],
        source=source,
        view=view,
        legend='FLAG 2',
    )
    circle_2.selection_glyph = Circle(
        fill_alpha=1.0, # transparente
        line_color=None,
        fill_color='blue',
    )
    circle_2.nonselection_glyph = Circle(
        fill_alpha=1.0,
        line_color=None,
        fill_color='blue',
    )
    
    plot_1.legend.location = "top_left"
    plot_1.legend.click_policy="hide"
    
    circle_all = plot_1.circle(
        x='x',
        y='y',
        size=5,
        fill_alpha=0.0, # transparent
        line_color=None,
        source=source,
    )
    circle_all.selection_glyph = Circle(
        fill_color=Reds3[0],
        fill_alpha=1.0, # transparent
        line_color=None,
    )
    circle_all.nonselection_glyph = Circle(
        fill_alpha=0.0, # transparent
        line_color=None,
        line_alpha=0.0,
    )
    
    lasso = LassoSelectTool(
        renderers=[circle_all],
        select_every_mousemove=False,
    )
    plot_1.add_tools(lasso)
    
    def update_selection(attr, old, new):
        print('>> NEW: {}'.format(new['1d']['indices']))
    
    source.on_change(  # source should be shared along all the plots
        'selected',
        update_selection
    )
    
    curdoc().add_root(column([plot_1]))
    

    无论如何,这只是一个临时解决方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-07
      • 2012-08-21
      • 2019-06-29
      • 1970-01-01
      • 2015-05-09
      • 1970-01-01
      • 1970-01-01
      • 2016-11-06
      相关资源
      最近更新 更多