首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >创建用于修改图例的GlyphRenderers

创建用于修改图例的GlyphRenderers
EN

Stack Overflow用户
提问于 2021-06-23 23:24:33
回答 1查看 76关注 0票数 0

我想创建一个bokeh应用程序,可以根据某些属性过滤点。下面是我的用例的一个非常简单的代码示例,它使用复选框过滤绘图上的点。

代码语言:javascript
复制
from bokeh.plotting import ColumnDataSource, figure, curdoc
import bokeh.models as bmo
from bokeh.layouts import row
import numpy as np


def update_filter(selected_colors):
    keep_indices = []
    for i, color in enumerate(cds.data['color']):
        if color2idx[color] in selected_colors:
            keep_indices.append(i)
    view.filters[0] = bmo.IndexFilter(keep_indices)


cds = ColumnDataSource(data=dict(
                                x=np.random.rand(10),
                                y=np.random.rand(10),
                                color=['red', 'green', 'blue', 'red', 'green', 
                                       'blue', 'red', 'green', 'blue', 'red'])
                      )
view = bmo.CDSView(source=cds, filters=[bmo.IndexFilter(np.arange(10))])
checkboxes = bmo.CheckboxGroup(labels=['red', 'green', 'blue'], active=[0, 1, 2])
color2idx = {'red': 0, 'green': 1, 'blue': 2}
checkboxes.on_change('active', lambda attr, old_val, new_val: update_filter(new_val))
fig = figure(plot_width=400, plot_height=400, title='Visualize')
fig.circle(x='x', y='y', fill_color='color', size=10, source=cds, view=view, legend_field='color')

curdoc().add_root(row(checkboxes, fig))
curdoc().title = 'Plot'

然而,当我通过取消选中其中一个复选框来过滤指出时,它工作得很好,图例变得错误。下面是选择所有颜色时的屏幕截图:

这是取消选择其中一种颜色时的屏幕截图:

可以看到,当取消选中“绿色”的复选框时,“绿色”的图例变为红色。

我发现图例在CDSView上不能正常工作,这仍然是一个未解决的问题:https://github.com/bokeh/bokeh/issues/8010

因此,我写了下面的函数,它将修改图例,使其不会出错。

代码语言:javascript
复制
def update_legend():
    # Find the indices in the CDS that are visible
    filters = view.filters
    visible_indices = set(list(range(len(cds.data['x']))))
    for filter in filters:
        visible_indices = visible_indices & set(filter.indices)

    # Get a list of visible colors
    visible_colors = set([cds.data['color'][i] for i in visible_indices])
    # Create a dummy figure to obtain renderers
    dummy_figure = figure(plot_width=0, plot_height=0, title='')
    legend_items = []

    # Does not work
    for color in visible_colors:
        renderer = dummy_figure.circle(x=[0], y=[0], fill_color=color, size=10)
        legend_items.append(bmo.LegendItem(label=color, renderers=[renderer]))

    fig.legend[0].items = legend_items

并为复选框组添加了另一个事件回调:

代码语言:javascript
复制
checkboxes.on_change('active', lambda attr, old_val, new_val: update_legend())

当我执行上述操作时,图例中的标签已更正,但现在图例中不会呈现字形。下面是相同的屏幕截图:

我做错了什么?我应该如何为图例创建GlyphRenderer,以便问题得到解决?

EN

回答 1

Stack Overflow用户

发布于 2021-06-29 00:47:26

这适用于Bokeh v2.1.1。除了原始代码之外,您还可以单击图例项来显示/隐藏圆圈。

代码语言:javascript
复制
from bokeh.plotting import ColumnDataSource, figure, curdoc
from bokeh.models import CheckboxGroup, Row, CDSView, IndexFilter
import numpy as np

colors = ['red', 'green', 'blue']
cds = ColumnDataSource(dict(x=np.random.rand(10),
                            y=np.random.rand(10),
                            color=['red', 'green', 'blue', 'red', 'green', 'blue', 'red', 'green', 'blue', 'red']))

def update_filter(selected_colors):
    for i in range(len(colors)):
        renderers[i].visible = True if i in selected_colors else False

checkboxes = CheckboxGroup(labels=colors, active=[0, 1, 2], width = 50)
checkboxes.on_change('active', lambda attr, old_val, new_val: update_filter(new_val))

fig = figure(plot_width=400, plot_height=400, title='Visualize')
views = [CDSView(source=cds, filters=[IndexFilter([i for i, x in enumerate(cds.data['color']) if x == color])]) for color in colors]
renderers = [fig.circle(x='x', y='y', fill_color='color', size=10, source=cds, view=views[i], legend=color) for i,color in enumerate(colors)]
fig.legend.click_policy = 'hide'

curdoc().add_root(Row(checkboxes, fig))
curdoc().title = 'Plot'

结果:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68102763

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档