63255

How do I select data points based with a RangeSlider in Bokeh?

Question:

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

<ul><li>I am using rect to draw rectangles producing a heatmap.</li> <li>I am adding a RangeSlider.</li> <li>I am attaching a js_callback on changes of the range.</li> <li>In the custom Callback, I am able to retrieve the start and end range of the range slider.</li> </ul>

What I am uncertain about is how to then select anything with it. <a href="http://bokeh.pydata.org/en/latest/docs/user_guide/interaction/callbacks.html#customjs-for-selections" rel="nofollow">This link</a> (cb_obj.selected['1d'].indices) shows that one retrieve all selected data points. But how does one do the opposite?

In other words:

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

Answer1:

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:

<ol><li>Replace the JSCustom callback function with a Python update function. The udpate function contains code to update the ColumnDataSource.</li> <li>Replace the js_on_change event simply with a on_change event attached to the slider.</li> <li>Place the code above together with the update function within "main.py" within a folder named after the application.</li> <li>Start the bokeh server with "bokeh serve --show INSERTAPP_NAME".</li> </ol>

This information can be found <a href="http://bokeh.pydata.org/en/latest/docs/user_guide/server.html" rel="nofollow">here</a> 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.

Recommend

  • error: bad operand types for binary operator '-'
  • Finding largest and smallest numbers within a file using Java
  • Counting the amount of highest number in a string
  • Converting long to int gives 0
  • Order of columns and rows with ggplot2 tile
  • shortcut to out-of-box of bracket
  • Changes from 3.5 to 4.0
  • Inconsistency between sequences and seqiplot
  • Setting the color label and varying the color palette in qplot
  • EJB3 stateful concurrent calls from different clients
  • What to look for when setting UpdateBatchSize
  • Finding if my mouse is inside a rectangle in Java
  • iOS Safari image rendering issue
  • how to convert JSONString to Javascript Object
  • Shortcut for extract local variable in Visual Studio or ReSharper (for C#)
  • Ignoring a field without modifying the POJO class with Jackson
  • Fibonacci Computation Time
  • Human-readable duration between two UNIX timestamps
  • Kotlin Jackson generation objects from JSON
  • Calling a secure webservice in SSIS through script task
  • python re.compile and split with ÆØÅ charcters
  • Converting Dictionary to Dataframe with tuple as key
  • How to pause a python script running in terminal
  • Bokeh custom ToolTips {safe} tag displays nothing
  • Why does the first run of “XCTestCase -measureBlock:” takes so much time?
  • Java, will (low + high) >>> 1 overflow?
  • Get rendered html code in Backing Component from Composite Component
  • Automapper missing type map configuration or unsupported mapping
  • Upper limits for fibonnacci
  • Watson Conversation - Why is the ANYTHING ELSE node not chosen
  • Python getting common name from URL using ssl.getpeercert()
  • Local Development, Apache vs Developer - file permissions
  • Counter field in MS Access, how to generate?
  • Javascript + PHP Encryption with pidCrypt
  • Websockets service method fails during R startup
  • Unanticipated behavior
  • using conditional logic : check if record exists; if it does, update it, if not, create it
  • Why can't I rebase on to an ancestor of source changesets if on a different branch?
  • Can't mass-assign protected attributes when import data from csv file
  • Unable to use reactive element in my shiny app