Bokeh / Python: Как изменить столбцы данных в обратном вызове CustomJS - PullRequest
0 голосов
/ 10 июня 2019

Предположим, что источник имеет 4 столбца с именами time_s, time_min, time_h и y.

source = ColumnDataSource(...) 

Затем из этих столбцов изначально выбираются time_s и y

p = figure(tools=tools, toolbar_location="above")
p.line(x='time_s', y='y', source=source)

В кодовом блоке обратного вызова CustomJS я хотел бы переключить x-столбец с time_s на time_min и соответственно перерисовать график.Я знаю, как я могу исследовать / получать доступ к некоторым данным и объектам в целом, анализируя их в консоли DevTools, но я не могу найти x='time_s' из объекта p.line или как к нему можно получить доступ.

js = """
// Explore Objects in DevTools Console
console.log(data)
console.log(source)
console.log(plot) 

data = source.data
data['time_s'] = do something to column here ...

if (widget.value === 'xyz') {
    // Looking for something like:
    plot.line.x = data['time_min'] // not working
}

// After data change -> rerender
source.change.emit()

"""
cb = CustomJS(args=dict(src=source, plot=p, widget=mywidget), code=js)
mywidget.js_on_change('value', cb)

Так как это можно сделать?

1 Ответ

0 голосов
/ 10 июня 2019

Существует множество способов, которыми я могу представить это.Предполагая, что вы можете допустить дублирование одного столбца в источнике данных, я бы посоветовал:

import numpy as np

from bokeh.io import show
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, CustomJS, Select
from bokeh.plotting import figure

x = np.linspace(0, 10, 100)
foo = x**2
bar = np.sin(x)

source = ColumnDataSource(data=dict(x=x, y=foo, foo=foo, bar=bar))

plot = figure(plot_height=350)
plot.line(x='x', y='y', source=source)

select = Select(value='foo', options=['foo', 'bar'])
select.js_on_change('value', CustomJS(args=dict(source=source, select=select), code="""
    // make a shallow copy of the current data dict
    const new_data = Object.assign({}, source.data)

    // update the y column in the new data dict from the appropriate other column
    new_data.y = source.data[select.value]

    // set the new data on source, BokehJS will pick this up automatically
    source.data = new_data
"""))

show(column(plot, select))

Если дублирование выбранного столбца в столбце "y" недопустимо, то оно можно обновить глиф, изменить столбец, на который он указывает.Это будет выглядеть примерно так:

r = p.line(x='x', y='foo' source=source)

cb = CustomJS(args=dict(r=r, select=select), code="""
    // tell the glyph which field of the source y should refer to
    r.glyph.y.field = select.value

    // manually trigger change event to re-render
    r.glyph.change.emit()
""")
...