散景滑块堆积条形图

时间:2018-06-04 13:00:03

标签: javascript slider bokeh

我希望能够只显示最初的前三个条形,然后使用滑块显示更多或更少的条形图。我不知道是否可以使用散景的滑块小部件或是否有更好的方法。

from bokeh.models.widgets import Slider
from bokeh.layouts import widgetbox, column
from bokeh.models import CustomJS, Slider


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)

p = figure(x_range=fruits, plot_height=350, title="Fruit Counts by Year",
           toolbar_location=None, tools="")

p.vbar_stack(years, x='fruits', width=0.9, color=colors, source=source,
                         legend=[value(x) for x in years], name=years)

callback = CustomJS(args=dict(source = source), code="""
var data = source.data;
var start = slider.value;
var x = data['OOC_EQP'];
x_range.setv({"start":start, "end":start+10});
""")

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")
callback.args["slider"] = slider

layout = column(p, widgetbox(slider))

show(layout)

1 个答案:

答案 0 :(得分:1)

我在这里看不到需要使用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服务调用它,因为它需要python后端来运行函数

如果您只想使用Javascript,而不是散景服务器,即使在这种情况下,我建议只更改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)