如何在Bokeh中基于RangeSlider选择数据点? [英] How do I select data points based with a RangeSlider in Bokeh?

查看:136
本文介绍了如何在Bokeh中基于RangeSlider选择数据点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Bokeh中构建一个交互式图形.到目前为止,可以说我有一个如下的热点图.用简单的英语:

I am trying to build an interactive graph in Bokeh. So far let's say I have a heatmap like below. In plain English:

  • 我正在使用rect绘制产生热图的矩形.
  • 我要添加一个RangeSlider.
  • 我将对范围的更改附加js_callback.
  • 在自定义的回调中,我可以检索范围滑块的开始和结束范围.

我不确定如何选择它. 此链接(cb_obj .selected ['1d'].indices)显示一个检索所有选定的数据点.但是如何做到相反呢?

What I am uncertain about is how to then select anything with it. This link (cb_obj.selected['1d'].indices) shows that one retrieve all selected data points. But how does one do the opposite?

换句话说:

如何选择介于值a和b之间的所有矩形?

How do I select all the rectangles that fall between values a and b?

下面是我已经弄清楚的东西的代码.

Below is the code with things I figured out already.

from math import pi
from bokeh.io import show
from bokeh.models import ColumnDataSource, HoverTool, 
LinearColorMapper, CategoricalColorMapper, ColorBar, LogColorMapper, 
LogTicker
from bokeh.plotting import figure
from bokeh.models.callbacks import CustomJS

col = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
row = ['A', 'B', 'C' , 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 
'N', 'O', 'P']

mapper = LogColorMapper(palette="Viridis256", low=min_value,  
high=max_value)
source = ColumnDataSource(data = dict (
        row = test['plate_row'],
    col = test['plate_col'],
    values = test['Melt Temp']))

TOOLS = "reset, tap,box_select, hover,save,pan,box_zoom,wheel_zoom"

p = figure(title="Plate Heatmap", x_range = (0.0,25.0), y_range = 
list(reversed(row)),
       x_axis_location="above", plot_width=650, plot_height=400,
       tools=TOOLS)

r1 = p.rect(x="col", y="row", width=1, height=1,
        source=source, 
        fill_color={'field': 'values', 'transform': mapper},
        line_color=None)

callback = CustomJS(args=dict(source=source), code="""
    var data = source.data;
    var inds = cb_obj.selected['1d'].indices;
    var lower_bound = cb_obj.start;
    var upper_boudn = cb_obj.end;
    // WHAT DO I DO NEXT?
    source.trigger('change');
""")

range_slider = widgetbox(RangeSlider(start=min_value, end=max_value, 
range= (min_value, max_value), step=0.1, title="Hit Threshold"))
range_slider.js_on_change('range', callback)

color_bar = ColorBar(color_mapper=mapper, ticker=LogTicker(),
                 label_standoff=12, border_line_color=None, location= 
(0,0))
p.add_layout(color_bar, 'left')
layout = column(range_slider, p)
show(layout)      # show the plot

推荐答案

虽然我无法找到一种方法来设置选择的内容,但还是找到了一种实现相同结果的方法.这也许是如何使用Bokeh服务器的主要示例.为了达到同样的效果,需要执行以下操作:

While I was not able to do find a way to set what is selected or not, I found a way to achieve the same outcome. This is perhaps a prime example for how a Bokeh server could be used. To accomplish this same effect, one needs to do the following:

  1. 用Python更新替换JSCustom回调函数 功能. udpate函数包含用于更新 ColumnDataSource.
  2. 只需用on_change事件替换js_on_change事件 附加到滑块.
  3. 将上面的代码与更新功能一起放在其中 以应用程序命名的文件夹中的"main.py".
  4. 使用散景服务-显示INSERTAPP_NAME"启动bokeh服务器.
  1. Replace the JSCustom callback function with a Python update function. The udpate function contains code to update the ColumnDataSource.
  2. Replace the js_on_change event simply with a on_change event attached to the slider.
  3. Place the code above together with the update function within "main.py" within a folder named after the application.
  4. Start the bokeh server with "bokeh serve --show INSERTAPP_NAME".

可以在此处找到此信息,并表示部署交互式可视化的最简单方法.对于您的情况,可能需要更复杂的部署方案.我也在研究这个问题,但这将是另一天的另一个问题.

This information can be found here and represents the simplest way of deploying an interactive visualization. More complicated deployment scenarios may be necessary for your case. I am looking into this as well, but this will be another question for another day.

这篇关于如何在Bokeh中基于RangeSlider选择数据点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆