散景:x_range的customjs更改,重复的因子或子因子错误



i在条形图中绘制数据。数据分为两个级别的两个级别。我添加了一个范围滑块,以更改绘图的x_range,以显示显示的年份。我试图通过customjs回调实现(我第一次尝试customjs(。

使用滑块,X轴上的因子会按预期更新。但是,如果我然后使用Zoom工具,然后使用重置工具,我会在Web控制台中收到一条错误消息:

错误:重复因子或子因子:2016

不确定我在数据设置的设置中做错了什么。因子范围的更新是否错误?

我正在MacOS上使用Bokeh版本1.1.0。在Safari和Firefox中观察到的同样错误。

下面的代码将重现错误。

from bokeh.models import ColumnDataSource, FactorRange, RangeSlider, CustomJS
from bokeh.plotting import figure
from bokeh.layouts import column
import pandas as pd
output_file("grouped_customJS.html")
fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
data = {'fruits' : fruits,
        '2015'   : [2, 1, 4, 3, 2, 4],
        '2016'   : [5, 3, 3, 2, 4, 6],
        '2017'   : [3, 2, 4, 4, 5, 3]}
df = pd.DataFrame.from_dict(data)
df=df.set_index('fruits').stack().reset_index()
df=df.rename(columns={'level_1':'year', 0:'value'})
# add year as int column for slider
df['year_int'] = df['year'].astype(int)
df=df.set_index(['fruits','year'])
cats = df.index.values
source = ColumnDataSource(
        data = {
            'categories': cats,
            'values': df['value'],
            'year': df['year_int']
        }
)
p = figure(
        x_range=FactorRange(*cats),
        plot_height=250,
        title="Fruit Counts by Year",
)
p.vbar(x='categories', top='values', width=0.9, source=source)
p.y_range.start = 0
p.x_range.range_padding = 0.1
p.xaxis.major_label_orientation = 1
p.xgrid.grid_line_color = None
slider = RangeSlider(
    start=df['year_int'].min(),
    end=df['year_int'].max(),
    step = 1,
    value = (df['year_int'].min(), df['year_int'].max()),
)
callback = CustomJS(args=dict(slider=slider, source=source, plt = p), code="""
    plt.x_range.factors = [];
    for (var i = 0; i < source.get_length(); i++){
        if (source.data['year'][i] >= slider.value[0] && source.data['year'][i] <= slider.value[1]){
            plt.x_range.factors.push(source.data['categories'][i]);
        }
    }
""")
slider.js_on_change('value', callback)
p.x_range.js_on_change('factors', callback)
show(column(p, slider))

尝试一下(与bokeh v1.1.0一起使用(:

callback = CustomJS(args = dict(slider = slider, source = source, plt = p), code = """
    var factors = []
    for (var i = 0; i < source.get_length(); i++){
        if (source.data['year'][i] >= slider.value[0] && source.data['year'][i] <= slider.value[1]){
            factors.push(source.data['categories'][i]);
        }
    }
    plt.x_range.factors = factors; """)

最新更新