如何在bokeh中使用custom.js回调更新下拉菜单

时间:2019-05-21 14:25:53

标签: javascript bokeh

如何使用bokeh中的customjs回调更新下拉菜单

我正在尝试通过使用Bokeh中的customjs回调,根据用户在上一个下拉菜单中所做的选择来更新下拉菜单。 在下面的示例中,用户可以基于选择common_name来创建基本图,也可以通过选择四边形来创建基本图。但是我希望用户能够首先选择一个common_name,然后根据可用于该common_name的数据(即基于首先选择的common_name)选择一个Quadrat。 有什么想法吗?

from bokeh.models import CustomJS, ColumnDataSource, MultiSelect, Column

from bokeh.plotting import figure, show
from bokeh.layouts import row, column
import pandas as pd

# data
data = dict(common_name = ['A','A','B','C','B','B','A','C','C','B','A','B','C'],
length = [10, 20, 10, 20, 30, 20, 20, 30, 20, 30, 30, 20, 30],
weight = [100, 200, 100, 300, 100, 400, 100, 300, 100, 400, 500, 600, 450],
quadrat = ['N', 'N', 'N', 'N', 'M', 'M', 'M', 'M', 'O', 'O', 'M', 'N', 'O'])

data = pd.DataFrame(data)

data_source = ColumnDataSource(data)

# Empty source so the plot is empty before data is selected
source = ColumnDataSource(dict(length = [], weight = []))

plot = figure()

plot.circle(x = 'length', y = 'weight', source = source)


# Select species
available_species = list(set(data['common_name']))
available_species.sort()

species_callback = CustomJS(args = {'source': source, 'data_source': data_source},
code = """
var data = data_source.data;
var source_data = source.data;
var common_name = data['common_name'];
var selected_species = cb_obj.value;
var length_data = data['length'];
var weight_data = data['weight'];
var length = source_data['length'];
length.length = 0;
var weight = source_data['weight'];
weight.length = 0;
 for (var i = 0; i < length_data.length; i++) {
  if (selected_species.indexOf(common_name[i]) >= 0) {
   length.push(length_data[i]);
   weight.push(weight_data[i]);
    }
  }
  source.change.emit();
  """)

multiselect_species = MultiSelect(title = 'Species:', value = [], options = available_species, width = 240)
multiselect_species.js_on_change('value', species_callback)

# Select quadrat
available_quadrat = list(set(data['quadrat']))
available_quadrat.sort()

quadrat_callback = CustomJS(args = {'source': source, 'data_source': data_source},
code = """
var data = data_source.data;
var source_data = source.data;
var quadrat = data['quadrat'];
var selected_quadrat = cb_obj.value;
var length_data = data['length'];
var weight_data = data['weight'];
var length = source_data['length'];
length.length = 0;
  var weight = source_data['weight'];
  weight.length = 0;
  for (var i = 0; i < length_data.length; i++) {
    if (selected_quadrat.indexOf(quadrat[i]) >= 0) {
      length.push(length_data[i]);
      weight.push(weight_data[i]);
    }
  }
  source.change.emit();
  """)

multiselect_quadrat = MultiSelect(title = 'Set:', value = [], options = available_quadrat, width = 240)
multiselect_quadrat.js_on_change('value', quadrat_callback)

  # Set up widgets layout
widgets_layout = column(multiselect_species, multiselect_quadrat)

page_layout = row(widgets_layout, plot)

show(page_layout)




0 个答案:

没有答案