我有许多蝴蝶的多个标本的长度和重量(common_name),我想在Bokeh中制作一个动态图,用户可以选择一个给定的物种来显示长度和重量的散点图。该数据框是一个简单的4列数据框,具有4个变量:length
,weight
,common_name
和size
。有数百个条目(即每个样本都有一个共同的名称,长度和重量)。大小始终为10,因此我可以在回调中将其设置为0。我的代码的简化版本如下所示:
def scatter_plot(request):
butterfly_data = pd.DataFrame(butterfly_data)
source = ColumnDataSource( butterfly_data)
### Main plot
plot = figure(title='Length-weight relationship', x_axis_label='length (cm)', y_axis_label='weight (g)',
tools="pan, hover, box_zoom, reset, save", toolbar_location="below",
plot_width=400, plot_height=400)
plot.circle(x='length', y='weight', source=source, line_width=2)
# List of species
available_species = list(set(butterfly_data['common_name']))
available_species.sort()
# Species selection widget
callback99 = CustomJS(args=dict(source=source), code="""
var data = source.data;
var inpt = cb_obj.active;
var size = data['size'];
var common_name = data['common_name'];
for (var i = 0; i < size.length; i++) {
var ret = [];
for (var a = 0; a < inpt.length; a++) {
for (var z = 0; z < common_name[i].length; z++) {
console.log("ret", common_name, ret, common_name[i], "s", inpt[a], size.length);
}
}
if (ret.length == 0) {
size[i] = 0;
} else {
size[i] = 10;
}
}
source.change.emit();
""")
species_selection = CheckboxGroup(labels=available_species, active = [])
species_selection.js_on_change('active', callback99)
# Set up widgets layout
widgets_layout = column(species_selection)
# Set up figures layout
figures_layout = row(plot)
# Set up page layout
page_layout = row(widgets_layout, figures_layout)
script, div = components(page_layout)
return render_to_response('scatter.html', {'script':script, 'div':div})
我的问题是我无法更新散点图(选择给定物种时什么也没有发生)。我一定弄不清回调。
有什么想法吗?
答案 0 :(得分:0)
我认为您需要这样的东西(Bokeh v1.1.0):
import pandas as pd
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, CustomJS, CheckboxGroup, Column
butterfly_data = dict(length = [1, 2, 3], weight = [10, 20, 30], common_name = ['butterfly1', 'butterfly2', 'butterfly3'], size = [100, 100, 100])
butterfly_data = pd.DataFrame(butterfly_data)
butterfly_source = ColumnDataSource(butterfly_data)
source = ColumnDataSource(dict(length = [], weight = [], common_name = [], size = []))
plot = figure(title = 'Length-Weight Relationship', x_axis_label = 'length (cm)', y_axis_label = 'weight (g)',
tools = "pan, hover, box_zoom, reset, save", toolbar_location = "right")
plot.circle(x = 'length', y = 'weight', source = source, line_width = 2)
species_selection = CheckboxGroup(labels = list(butterfly_data['common_name'].values), active = [])
callback = CustomJS(args = dict(source = source, species_selection = species_selection, butterfly_source = butterfly_source), code = """
var data = { length: [], weight: [], common_name: [], size: [] };
var selected_indexes = cb_obj.active;
for (var i = 0; i < selected_indexes.length; i++) {
index = selected_indexes[i];
data['length'].push(butterfly_source.data['length'][index]);
data['weight'].push(butterfly_source.data['weight'][index]);
data['common_name'].push(butterfly_source.data['common_name'][index]);
data['size'].push(butterfly_source.data['size'][index]);
}
source.data = data; """)
species_selection.js_on_change('active', callback)
page_layout = Column(species_selection, plot)
show(page_layout)