После того, как выбрана опция выпадающего меню, как мне «изменить.emit» или «вызвать изменение» на графике? - PullRequest
0 голосов
/ 10 мая 2019

Любые идеи, что должно идти, где тройки '?'?

import pandas as pd
from bokeh.layouts import column
from bokeh.models import CustomJS, ColumnDataSource, Slider, Select
import bokeh.plotting as bp
from bokeh.plotting import Figure, output_file, show
from bokeh.models import HoverTool, DatetimeTickFormatter

# Create an output file
bp.output_file('columnDataSource.html')

# Create your plot as a bokeh.figure object
myPlot = bp.figure(height = 600,
               width = 800,
               y_range=(0,3))

x_values = [1, 2, 3, 4, 5]
y_values = [1, 2, 3, 4, 5]

myPlot.line(x = x_values, y= y_values, line_width=2)

callback = CustomJS(args={
    'source1': {'x': [1,2,3,4], 'y':[1,1,1,1]},
    'source2': {'x': [0,0,0,0], 'y':[2,2,2,2]},
    'source3': {'x': [1,2,3,4], 'y':[1,1,1,1]}}, 

    code="""

    var data1 = source1;
    var data2 = source2;
    var data3 = source3;

    var f = cb_obj.value;

    if(f == 'A'){
    console.log("A selected from dropdown.");
    data1.x = data1.x;
    data1.y = data1.y;
    }

    else if(f == 'B'){
    // Substitute all old data1 values in with data2 values
    console.log("B selected from dropdown.");
    data1.x = data2.x;
    data1.y = data2.y;
    }

    else{
    console.log("C selected.");
    // Substitute all old data1 values in with data3 values
    data1.x = data3.x;
    data1.y = data3.y;
    }

    // Problematic line!
    ???.change.emit();
""")


select = Select(title='Choose', value='A', options=['A','B','C'])
select.js_on_change('value', callback)

layout = column(select, myPlot)

show(layout) # et voilà.

Я ожидаю, что мои значения x и y изменятся и будут отображаться в соответствии с моим графиком Боке.

На данный момент ничего не меняется, так как я не знаю, какую «триггерную» функцию объекта я должен вызывать.Пожалуйста, помогите, я новичок в Боке.

1 Ответ

0 голосов
/ 10 мая 2019

Вы делаете 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)
...