使用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'}"""
))
我感觉我很亲密,但是只缺少一两个关键的东西。...任何建议/帮助表示赞赏!