是否可以使用CustomJS回调方法来更新图例补丁标签?

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

使用Bokeh 1.4和Python 3.7。我有一组补丁,我想根据来自同一ColumnDataSource的两个不同键(和标签)来更改颜色主题。我想坚持使用一个ColumnDataSource,因为我的真实文件很大,并且几何形状(即xs和ys)在我想要作为主题的两件事之间很常见。

请参阅我的工作示例:

from bokeh.io import show
from bokeh.models import ColumnDataSource,CustomJS, widgets, LinearColorMapper
from bokeh.palettes import RdBu6, Spectral11
from bokeh.plotting import figure
from bokeh.layouts import layout, column, row

source = ColumnDataSource(dict(
    xs=[[1,2,2], [1,2,2], [3,4,4], [3,4,4]],
    ys=[[3,3,4], [1,1,2], [3,3,4], [1,1,2]],
    s1=[0, 50, 75, 50],
    s2=[0, 25, 50, 75],
    label_1=['Blue', 'Orangy', 'Red', 'Orangy'],
    label_2=['S', 'P', 'E', 'C']

))

cmap1 = LinearColorMapper(palette='RdBu6', low = 0, high = 75)
cmap2 = LinearColorMapper(palette='Spectral11', low = 0, high = 75)

p = figure(x_range=(0, 7), y_range=(0, 5), plot_height=300)

patches = p.patches( xs='xs', ys='ys', fill_color={'field':'s1','transform':cmap1}
                    , legend_field='label_1', source=source)


b = widgets.Button(label = 'RdBu')

b.js_on_click(CustomJS(args=dict(b=b,source=source,patches=patches,cmap1=cmap1,cmap2=cmap2,p=p),      
                             code="""if (b.label == 'RdBu')
                                 {b.label='Spectral';
                                 patches.glyph.fill_color = {field: 's2',transform:cmap2};}
                             else if (b.label == 'Spectral')
                                 {b.label='RdBu';
                                 patches.glyph.fill_color = {field: 's1',transform:cmap1}}"""
                            ))
layout=column(row(p),row(b))
show(layout)

这将产生this,然后在单击按钮时产生this。您可以看到,随着颜色的变化,甚至图例中的颜色发生变化,回调的fill_color更新部分都可以正常工作,但是我无法找到一种方法来指示CustomJS正确更新图例条目,以便在第二个中图像将有4个条目,其中“ S”,“ P”,“ E”和“ C”作为图例标签。

据我所知,当我创建补丁对象并指定legend_field参数时,它会使用groupby / aggregate函数为我构造一个图例以为我生成唯一的图例条目,然后将该图例添加到图对象?

因此,这使我无法尝试深入研究p.legend:

p.legend.items #returns a list containing one LegendItem object
p.legend.items[0].label #returns a dictionary: {'field': 'label_1'}

我尝试将p.legend.items [0] .label ['field'] ='label_2'放在回调之外,并且它的工作原理为as I hoped-图例现在读取为S,P,E,C。但是,当我尝试将其放入回调代码中时,它似乎没有更新:

b.js_on_click(CustomJS(args=dict(b=b,source=source,patches=patches,cmap1=cmap1,cmap2=cmap2,p=p),      
                             code="""if (b.label == 'RdBu')
                                 {b.label='Spectral';
                                 patches.glyph.fill_color = {field: 's2',transform:cmap2};
                                 p.legend.items[0].label['field']='label_2'}
                             else if (b.label == 'Spectral')
                                 {b.label='RdBu';
                                 patches.glyph.fill_color = {field: 's1',transform:cmap1}
                                 p.legend.items[0].label['field']='label_1'}"""
                            ))

我感觉我很亲密,但是只缺少一两个关键的东西。...任何建议/帮助表示赞赏!

python python-3.x bokeh bokehjs
1个回答
© www.soinside.com 2019 - 2024. All rights reserved.