简体   繁体   English

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

[英]How to use CustomJS to update a scatter plot in Bokeh

I have a length and weight of multiple specimens of many species of butterflies (common_name) and I would like to make a dynamic graph in Bokeh where the user can select a given species to display a scatterplot of the lengths and weights. 我有许多蝴蝶种类的多个标本的长度和重量(common_name),我想在Bokeh中制作一个动态图表,用户可以选择给定的物种来显示长度和重量的散点图。 The dataframe is a simple 4 columns dataframe with 4 variables: length , weight , common_name and size . 数据框是一个简单的4列数据框,包含4个变量: lengthweightcommon_namesize There are hundreds of entries (ie each specimen has a common_name, lenght and weight). 有数百个条目(即每个样本具有common_name,lenght和weight)。 The size is always 10 so I can set it to 0 in the callback. 大小总是10,所以我可以在回调中将其设置为0。 A simplified version of my code looks like so: 我的代码的简化版本如下所示:

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})




My problem is that I cant get the scatterplot to update (nothing happens when I select a given species). 我的问题是我无法更新散点图(当我选择给定的物种时没有任何反应)。 I must have fumbled the callback. 我一定是弄乱了回调。

Any ideas ? 有任何想法吗 ?

I think you need something like this (Bokeh v1.1.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)

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM