Я не вижу необходимости использовать javascript callback
здесь.Здесь можно использовать встроенную функцию python on_change
.Функция изменит диапазон оси X без изменения каких-либо внутренних данных и будет очень быстрой -
from bokeh.models.widgets import Slider
from bokeh.layouts import widgetbox, column
from bokeh.models import Slider, ColumnDataSource
from bokeh.plotting import figure, curdoc
from bokeh.core.properties import value
from bokeh.models.ranges import FactorRange
fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
years = ["2015", "2016", "2017"]
colors = ["#c9d9d3", "#718dbf", "#e84d60"]
data = {'fruits' : fruits,
'2015' : [2, 1, 4, 3, 2, 4],
'2016' : [5, 3, 4, 2, 4, 6],
'2017' : [3, 2, 4, 4, 5, 3]}
source = ColumnDataSource(data=data)
## Note [0:3] for first 3 fruits only in default graph
p = figure(x_range=fruits[0:3], plot_height=350, title="Fruit Counts by Year",
toolbar_location=None, tools="")
renderers= p.vbar_stack(years, x='fruits', width=0.9, color=colors, source=source, \
legend=[value(x) for x in years], name=years)
p.y_range.start = 0
p.x_range.range_padding = 0.1
p.xgrid.grid_line_color = None
p.axis.minor_tick_line_color = None
p.outline_line_color = None
p.legend.location = "top_left"
p.legend.orientation = "horizontal"
slider = Slider(start=1, end=6, value=3, step=1, title="Range")
#function to update axis range
def update_axis(attrname, old, new):
a=slider.value
p.x_range.factors=fruits[0:a]
#Adding fucntion to on_change
slider.on_change('value', update_axis)
layout = column(p, widgetbox(slider))
#use curdoc to be used with bokeh server - use 'bokeh serve --show <filename>.py'
curdoc().add_root(layout)
Вызовите это с помощью Bokeh serve, так как для запуска функции
необходим бэкэнд Python
Если вы хотите использовать только Javascript, а не сервер bokeh, даже в этом случае я предлагаю изменить только x_range, а не данные.Смотрите код ниже -
from bokeh.models.widgets import Slider
from bokeh.layouts import widgetbox, column
from bokeh.models import Slider, ColumnDataSource, CustomJS
from bokeh.plotting import figure, curdoc
from bokeh.core.properties import value
from bokeh.models.ranges import FactorRange
from bokeh.plotting import figure, output_file, show, ColumnDataSource
fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
years = ["2015", "2016", "2017"]
colors = ["#c9d9d3", "#718dbf", "#e84d60"]
data = {'fruits' : fruits,
'2015' : [2, 1, 4, 3, 2, 4],
'2016' : [5, 3, 4, 2, 4, 6],
'2017' : [3, 2, 4, 4, 5, 3]}
source = ColumnDataSource(data=data)
## Note [0:3] for first 3 fruits only in default graph
p = figure(x_range=fruits[0:3], plot_height=350, title="Fruit Counts by Year",
toolbar_location=None, tools="")
renderers= p.vbar_stack(years, x='fruits', width=0.9, color=colors, source=source, \
legend=[value(x) for x in years], name=years)
p.y_range.start = 0
p.x_range.range_padding = 0.1
p.xgrid.grid_line_color = None
p.axis.minor_tick_line_color = None
p.outline_line_color = None
p.legend.location = "top_left"
p.legend.orientation = "horizontal"
print(renderers[0].data_source.data['fruits'])
callback = CustomJS(args=dict(fig=p, xr=renderers[0].data_source.data['fruits']), code="""
var A = slider.value;
fig.x_range.factors = [];
for (i = 0; i < A; i++) {
fig.x_range.factors.push(xr[i])
}
""")
p.x_range.js_on_change('factors', callback)
slider = Slider(start=1, end=6, value=3, step=1, title="Range", callback=callback)
callback.args["slider"] = slider
layout = column(p, widgetbox(slider))
output_file("ChangenumCat.html")
show(layout)