简体   繁体   English

python 散景动态更新分类 x_range

[英]python bokeh dynamically update categorical x_range

I want to create a candlestick plot in bokeh and dynamically update the x-axis according to user input through a MultiSelect widget.我想在散景中创建烛台 plot 并根据用户通过 MultiSelect 小部件的输入动态更新 x 轴。 Basically the user will choose a few items in the MultiSelect and then I would like those to become the values of the x axis.基本上,用户将在 MultiSelect 中选择一些项目,然后我希望这些项目成为 x 轴的值。 I already have set up the MultiSelect widget and confirmed that it is working by attaching a DataTable to the MultiSelect and having it update accordingly (which it does).我已经设置了 MultiSelect 小部件,并通过将 DataTable 附加到 MultiSelect 并使其相应更新(确实如此)来确认它正在工作。 I just need help retrieving the values from the MultiSelect widget and setting them as my plot.x_range.我只需要帮助从 MultiSelect 小部件中检索值并将它们设置为我的 plot.x_range。 Based on a few github/issues posts (like this one: https://github.com/bokeh/bokeh/issues/4022 ) I tried using a FactorRange, but it isn't working.基于一些 github/issues 帖子(例如: https://github.com/bokeh/bokeh/issues/4022 ),我尝试使用 FactorRange,但它不起作用。 Currently the behavior is the x axis labels stay set to the values that are set during the initial configuration of the MultiSelect ('aaa' and 'bbb'), and don't change when I choose different values in the MultiSelect widget.目前的行为是 x 轴标签保持设置为在 MultiSelect 的初始配置期间设置的值('aaa' 和 'bbb'),并且当我在 MultiSelect 小部件中选择不同的值时不会更改。

Here's a code sample:这是一个代码示例:

### SET UP SOURCE DF INFO ###
tab2_source = ColumnDataSource(df)
tab2_original_source = ColumnDataSource(df)
columns_t2 = [TableColumn(field='Gene', title='Gene'), TableColumn(field='row_min', title='min'), TableColumn(field='row_max', title='max'), 
             TableColumn(field='quantile_25', title='25th quantile'), TableColumn(field='quantile_50', title='50th quantile'), TableColumn(field='quantile_75', title='75th quantile')]
data_table_t2 = DataTable(source=tab2_source, columns=columns_t2, reorderable=False)

### STUFF FOR THE WIDGETS ###
# customJS stuff
tab2_callback_code = """
var t2_data = tab2_source.data;
var t2_original_data = tab2_original_source.data;
var gene_t2 = gene_select_obj_t2.value;
console.log("gene: " + gene_t2);
for (var key in t2_original_data) {
    t2_data[key] = [];
    for (var i = 0; i < t2_original_data['Gene'].length; ++i) {
        if (t2_original_data['Gene'][i] === gene_t2[0] || t2_original_data['Gene'][i] === gene_t2[1]) {
            t2_data[key].push(t2_original_data[key][i]);
        }
    }
}

tab2_source.change.emit();
target_obj_t2.change.emit();
"""

# make drop-down selectors
select_gene_t2 = MultiSelect(title = "Select up to 2 Genes to View:", value=['aaa', 'bbb'], options=list(df.Gene.unique()))

# define the callback objects now that the select widgets exist
tab2_callback = CustomJS(
    args=dict(tab2_source=tab2_source,
             tab2_original_source=tab2_original_source,
             gene_select_obj_t2=select_gene_t2,
             target_obj_t2=data_table_t2),
    code=tab2_callback_code)

# connect the callbacks to the filter widgets
select_gene_t2.js_on_change('value', tab2_callback)


## PLOTTING ##
p2 = figure(plot_width=500, plot_height=400, title='Avg Gene Exp', y_range=(-2,12), x_range=FactorRange())
p2.x_range.factors = list(select_gene_t2.value)
p2.vbar(x='Gene', top='quantile_75', bottom='quantile_25', source=tab2_source, width=0.5, fill_color="#D5E1DD", line_color="black")
tab2 = Panel(child=column(select_gene_t2, p2, data_table_t2), title="Exp by Gene")
tabs = Tabs(tabs=[tab2])
save(tabs)

For anyone who is interested, this is the best solution I found:对于任何有兴趣的人,这是我找到的最佳解决方案:

Add this line to the tab2_callback_code (plot_xr references my figure p2 - you will also need to add these references in the CustomJS args dict):将此行添加到 tab2_callback_code (plot_xr 引用我的图 p2 - 您还需要在 CustomJS args 字典中添加这些引用):

plot_xr.x_range.factors = gene_t2;

Also it is important to instantiate the figure before the tab2_callback_code is called.在调用 tab2_callback_code 之前实例化图形也很重要。 This worked for me and now my x_range values change as I select different options in the MultiSelect.这对我有用,现在我的 x_range 值随着我 select MultiSelect 中的不同选项而改变。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM