如何通过使用散景中的复选框动态更改点颜色

时间:2019-05-21 20:01:53

标签: javascript bokeh

我是Bokeh的新手,我正在尝试根据复选框中选择的选项来更改散点图的点的颜色。如果用户选择“全部”,则所有点都应为黑色,否则,如果用户选择“分组”,则点应按组进行着色(组A =绿色,组B =蓝色)。我在下面附上了一个暂定脚本。到目前为止,当复选框被触发时,什么都没有发生,因为我在customjs回调上遇到了麻烦。

任何帮助表示赞赏,


# Data handling
import pandas as pd

# Bokeh libraries
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, Callback, CustomJS
from bokeh.models.widgets import DataTable, NumberFormatter, TableColumn, HTMLTemplateFormatter
from bokeh.io import curdoc
from bokeh.layouts import row, column
from bokeh.models.widgets import CheckboxGroup


# data
data = dict(group = ['A','A','A','A','A','A','A','B','B','B','B','B','B'],
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])

data = pd.DataFrame(data)

source = ColumnDataSource(data)

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

color_checkbox = CheckboxGroup(labels=["all", "group"], active=[0])

color_checkbox.callback = CustomJS(args=dict(source = source), code='''
var source = source
var data = data;
var group = data['group'];
var selected_option = cb_obj.value;

var i, n = group.length;
    for (i = 0; i < n; ++i) {

      if (selected_option = 0);{
        plot.circle.color = 'black'
      }

      else {
        if (group[i] = 'A') {
          plot.circle.color = 'green'
        else
          plot.circle.color = 'blue'
        }
      }
    }
source.change.emit();
''')

widgets = column(color_checkbox)

layout = row(widgets, plot)

show(layout)


1 个答案:

答案 0 :(得分:0)

您的Javascript代码中有一些错误。首先,您不应该编辑plot.circle.color。相反,您应该在ColumnDataSource中添加颜色列,然后在其中编辑颜色。您还忘记添加一些括号。通过在浏览器中按F12并在控制台中查看,可以检测到此类错误。代码中的另一个问题是您使用的是普通复选框,这使用户无法选择任何选项,或者两个选项都不能选中,这在您的情况下是不可能的。我用无线电组代替了它。

工作代码:

# Data handling
import pandas as pd

# Bokeh libraries
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, Callback, CustomJS
from bokeh.models.widgets import DataTable, NumberFormatter, TableColumn, HTMLTemplateFormatter
from bokeh.io import curdoc
from bokeh.layouts import row, column
from bokeh.models.widgets import RadioGroup


# data
data = dict(group = ['A','A','A','A','A','A','A','B','B','B','B','B','B'],
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],
color = ['black', 'black', 'black', 'black', 'black', 'black', 'black', 'black', 'black', 'black', 'black', 'black', 'black'])

data = pd.DataFrame(data)

source = ColumnDataSource(data)

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

color_radiogroup = RadioGroup(labels=["All", "Group"], active=0)

color_radiogroup.callback = CustomJS(args=dict(source = source), code='''
    var data = source.data
    var selected_option = cb_obj.active

    if (cb_obj.active == 0) {
        for (var i = 0; i < data['group'].length; i++) {
            data['color'][i] = 'black'
        }
    } else if (cb_obj.active == 1) {
        for (var i = 0; i < data['group'].length; i++) {
            if (data['group'][i] == 'A') {
                data['color'][i] = 'green'
            } else if (data['group'][i] == 'B') {
                data['color'][i] = 'blue'
            }
        }
    }
    source.change.emit()

''')

widgets = column(color_radiogroup)

layout = row(widgets, plot)

show(layout)