Вы делаете ColumnDataSource.change.emit()
, если вы обновили поля источника данных по ссылке, например, когда вы обновляете только x
или только y
:
ColumnDataSource.data['x'] = [4, 3, 2, 1]
ColumnDataSource.change.emit()
Когда вы обновляете их оба, вы делаете:
ColumnDataSource.data = new_data
Где new_data
- это новый объект json, такой как {'x': [1], 'y':[2]}
.Причина этого заключается в том, что JS может автоматически обнаруживать изменение при замене существующего объекта новым, но не может обнаруживать изменения по ссылке, поэтому в этих случаях вам необходимо явно вызвать: ColumnDataSource.change.emit()
для обновления модели BokehJS.
Вот ваш модифицированный код:
from bokeh.models import CustomJS, ColumnDataSource, Select, Column
from bokeh.plotting import figure, show
myPlot = figure(y_range = (0, 4))
data = {'A': {'x': [1, 2, 3, 4], 'y':[1, 1, 1, 1]},
'B': {'x': [1, 2, 3, 4], 'y':[2, 2, 2, 2]},
'C': {'x': [1, 2, 3, 4], 'y':[3, 3, 3, 3]} }
source = ColumnDataSource(data['A'])
myPlot.line('x', 'y', line_width = 2, source = source)
callback = CustomJS(args = {'source': source, 'data': data},
code = """source.data = data[cb_obj.value]; """)
select = Select(title = 'Choose', value = 'A', options = ['A', 'B', 'C'])
select.js_on_change('value', callback)
layout = Column(select, myPlot)
show(layout)