通过回调更改bokeh中的情节源 [英] Changing source of plot in bokeh with a callback

查看:70
本文介绍了通过回调更改bokeh中的情节源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一下,我有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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆