通过回调更改bokeh中的情节源 [英] Changing source of plot in bokeh with a callback
问题描述
想象一下,我有2个(或更多)具有相同列和行数的数据源:
Imagine I have 2 (or more) sources of data with the same number of columns and rows:
#Data
dates = [date(2016, i, 1) for i in range(1,13)]
data1 = pd.DataFrame(index = dates, data = random.randn(12, 2),
columns = ['A', 'B'])
data2 = pd.DataFrame(index = dates, data = random.randn(12, 2),
columns = ['A', 'B'])
,我想绘制列A&散景中的B像这样:
and I want to plot columns A & B in bokeh as so:
#Bokeh
source = ColumnDataSource(source1)
source1 = ColumnDataSource(data1)
source2 = ColumnDataSource(data2)
p = figure(x_axis_type = 'datetime')
l1 = p.line(source = source, x = dates, y= 'A', color = 'Red')
l2 = p.line(source = source, x = dates, y= 'B', color = 'Blue')
我有一个下拉列表:
select = Select(options = ['source1', 'source2'], value = 'source1')
最简单的方法是为select
创建回调,以便当在下拉列表中选择其他选项时,折线图中的数据源也会更改?我几乎没有JS经验,也无法真正解决回调问题,因此我们将不胜感激.
What's the easiest way to create a callback for select
so that the source of data in the line charts change as a different option is chosen in the dropdown list? I have little to no experience in JS and can't really wrap my head around callbacks so any help would be appreciated.
我已经尝试过了:
codes = """
var f = cb_obj.get('value');
var sdata = source.data;
var 1data = source1.data;
var 2data = source2.data;
if (f == "source1") {
sdata = 1data ;
source.trigger('change');
};
if (f == "source2") {
sdata = 2data ;
source.trigger('change');
};
"""
select.callback= CustomJS(args= dict(source = source, source1=source1,
source2=source2), code = codes)
但这不起作用...
推荐答案
obj.trigger('change',arg)
已针对bokeh 0.12.6进行了更改,现已弃用,新语法为obj.change.emit(arg)
,请参见 Bokeh版本
obj.trigger('change',arg)
was changed for bokeh 0.12.6 and is now deprecated, the new syntax is obj.change.emit(arg)
, see Bokeh releases
您可以清空源"数据列,然后使用.push()在for循环中重新填充它们.
You can empty your "source" data columns and refill them in a for loop with .push()
此外,您不应使用以数字开头的变量名
Also you shouldn't use variable names starting with numbers
codes = """
var f = cb_obj.get('value');
var sdata = source.data;
var data1 = source1.data;
var data2 = source2.data;
if (f == "source1") {
sdata["A"] = [] ;
for (i=0;i<data1["A"].length; i++) {
sdata["A"].push(data1["A"][i]);
}
sdata["B"] = [] ;
for (i=0;i<data1["B"].length; i++) {
sdata["B"].push(data1["B"][i]);
}
source.trigger('change');
};
if (f == "source2") {
sdata["A"] = [] ;
for (i=0;i<data2["A"].length; i++) {
sdata["A"].push(data2["A"][i]);
}
sdata["B"] = [] ;
for (i=0;i<data2["B"].length; i++) {
sdata["B"].push(data2["B"][i]);
}
source.trigger('change');
};
"""
编辑以回答评论
from bokeh.plotting import figure, output_file
from bokeh.models import CustomJS, ColumnDataSource, Select
from bokeh.layouts import gridplot
from bokeh.resources import CDN
from bokeh.embed import file_html
from random import random
key_list = list('ABCDEFGHIJKLMNOP')
DATA1 = {key:[random() for i in range(10)] for key in key_list}
DATA2 = {key:[random() for i in range(10)] for key in key_list}
DATA1['xaxis'] = range(10)
DATA2['xaxis'] = range(10)
source1 = ColumnDataSource(data=DATA1)
source2 = ColumnDataSource(data=DATA2)
fill_source = ColumnDataSource(data=DATA1)
fig = figure()
for key in key_list:
fig.line(x='xaxis',y=key,source=fill_source)
select = Select(options=['source1','source2'],value='source1')
codes = """
var f = cb_obj.value;
var sdata = source.data;
var data1 = source1.data;
var data2 = source2.data;
console.log(data2);
for (key in data1) {console.log(key);}
if (f == "source1") {
for (key in data1) {
sdata[key] = [];
for (i=0;i<data1[key].length;i++){
sdata[key].push(data1[key][i]);
}
}
} else {
for (key in data2) {
sdata[key] = [];
for (i=0;i<data2[key].length;i++){
sdata[key].push(data2[key][i]);
}
}
};
source.trigger("change");
"""
select.callback = CustomJS(args=dict(source=fill_source,source1=source1,source2=source2),code=codes)
grid = gridplot([[select],[fig]])
outfile=open('select.html','w')
outfile.write(file_html(grid,CDN,'select'))
outfile.close()
不需要console.log()行,但是您可以使用它来帮助自己理解/调试回调,这些回调是浏览器控制台中的print语句(右键单击-> inspect-> Console)
The lines console.log() are not necessary, but you can use it to help yourself with understanding/debugging your callbacks, those are print statement in the browser console (right click -> inspect -> Console )
这篇关于通过回调更改bokeh中的情节源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!