Как динамически менять цвета точек с помощью флажка в Bokeh - PullRequest
0 голосов
/ 21 мая 2019

Я новичок в 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 голосов
/ 22 мая 2019

В вашем коде 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)
...