如何使用CustomJS更新散景中的散点图

时间:2019-05-15 13:42:00

标签: javascript bokeh

我有许多蝴蝶的多个标本的长度和重量(common_name),我想在Bokeh中制作一个动态图,用户可以选择一个给定的物种来显示长度和重量的散点图。该数据框是一个简单的4列数据框,具有4个变量:lengthweightcommon_namesize。有数百个条目(即每个样本都有一个共同的名称,长度和重量)。大小始终为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})




我的问题是我无法更新散点图(选择给定物种时什么也没有发生)。我一定弄不清回调。

有什么想法吗?

1 个答案:

答案 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)

enter image description here