我想在我的字形的颜色与ColumnDataSource中保存的颜色之间的回调和映射器定义的颜色之间切换,反之亦然。虽然我设法从ColumnDataSource切换到mapper,但我无法让它以相反的方式工作。
这是一个例子:
import numpy as np
from bokeh.models import ColumnDataSource, CustomJS, Select
from bokeh.transform import linear_cmap
from bokeh.palettes import Spectral6
from bokeh.plotting import figure, show
from bokeh.layouts import column, row
x=[1,2,3]
y=[1,2,3]
colormap=[5,6,7]
category=[1,1,2]
color=np.full((len(x)),'green')
legend=np.full((len(x)),'all data')
source = ColumnDataSource(data={'x':x, 'y':y , 'colormap': colormap, 'category': category,'color':color, 'legend':legend})
mapper = linear_cmap(field_name='colormap', palette=Spectral6, low=colormap[0], high=colormap[2])
p1=figure(plot_width=400, plot_height=400)
r=p1.circle('x','y',source=source, fill_color='color', size=20 ,legend='legend')
callback=CustomJS(args=dict(source=source,r=r,mapper=mapper),code='''
var color=source.data['color']
var category=source.data['category']
var legend=source.data['legend']
var r = r
var mapper = mapper
var n = color.length;
if (cb_obj.value == "no distinction"){
for (var i = 0; i < n; ++i) {
color[i] = 'blue';
legend[i] = 'all data';
source.change.emit();
}
}
else if (cb_obj.value == "category"){
for (var i = 0; i < n; ++i) {
if ( category[i] == 1){
color[i] = 'red';
legend[i] = 'category 1';
source.change.emit();
}
else if (category[i] == 2 ){
color[i] = 'black';
legend[i] = 'category 2';
source.change.emit();
}
}
}
else if (cb_obj.value == "mapper"){
r.glyph.fill_color = mapper
r.change.emit();
}
'''
)
select = Select(title=None, value="foo", options=["no distinction", "mapper", "category"])
select.js_on_change('value', callback)
show(column(select,p1))
如果选择第一个类别,然后选择映射器。代码做了应有的事情。但是,当您再次选择类别时,左图不再更改其值。我想解决方案是将ColumnDataSource分配给回调开头的字形,例如:
r.glyph.fill_color = color
但是,我无法弄清楚如何将ColumnDataSource对象分配给一个字形。
r.glyph.fill_color = {field : 'color'}