def raw_visualisation(doc_data,height,width): doc_data = ColumnDataSource(doc_data) TOOLS = "pan,box_zoom,reset,box_select" plot = figure(plot_width=width, plot_height=height, tools=TOOLS) plot.scatter(x='x', y='y', source=doc_data, color=UNLABELED_COLOR, size=SIZE) plot.js_on_event(Tap, CustomJS(args=dict(source=doc_data), code="handle_tap(source,cb_obj)")) doc_data.selected.js_on_change('indices', CustomJS(args=dict(source=doc_data), code="handle_select(source,cb_obj)")) return plot
def test_model_js_on_change_with_non_propname(): cb = CustomJS(code="") m1 = SomeModel() m1.js_on_change('foo', cb) assert m1.js_callbacks == {"foo": [cb]} m2 = SomeModel() m2.js_on_change('change:b', cb) assert m2.js_callbacks == {"change:b": [cb]}
def bottom_graph(self, source, ads): """Generate the bottom graphs (isotherm display).""" graph = figure(tools="pan,wheel_zoom,reset", active_scroll="wheel_zoom", plot_width=400, plot_height=250, x_range=(-0.01, 0.01), y_range=(-0.01, 0.01), title='Isotherms {0}'.format(ads)) rend = graph.multi_line('x', 'y', source=source, alpha=0.6, line_width=3, hover_line_alpha=1.0, hover_line_color="black", line_color='color') # Make clicking a graph open the NIST database graph.add_tools( HoverTool(show_arrow=False, line_policy='nearest', tooltips="""Click for details""")) graph.add_tools( TapTool(renderers=[rend], callback=CustomJS(args={ 'tp': load_details().render(), }, code=load_details_js()))) source.selected.js_on_change( 'indices', CustomJS( code= 'if (cb_obj.indices.length == 0) document.getElementById("iso-details").style.display = \"none\"' )) graph.xaxis.axis_label = 'Pressure (bar)' graph.yaxis.axis_label = 'Uptake (mmol/g)' return graph
def js_link(self, attr, other, other_attr): ''' Link two Bokeh model properties using JavaScript. This is a convenience method that simplifies adding a CustomJS callback to update one Bokeh model property whenever another changes value. Args: attr (str) : The name of a Bokeh property on this model other (Model): A Bokeh model to link to self.attr other_attr (str) : The property on ``other`` to link together Added in version 1.1 Raises: ValueError Examples: This code with ``js_link``: .. code :: python select.js_link('value', plot, 'sizing_mode') is equivalent to the following: .. code:: python from bokeh.models import CustomJS select.js_on_change('value', CustomJS(args=dict(other=plot), code="other.sizing_mode = this.value" ) ) ''' if attr not in self.properties(): raise ValueError("%r is not a property of self (%r)" % (attr, self)) if not isinstance(other, Model): raise ValueError("'other' is not a Bokeh model: %r" % other) if other_attr not in other.properties(): raise ValueError("%r is not a property of other (%r)" % (other_attr, other)) from bokeh.models.callbacks import CustomJS cb = CustomJS(args=dict(other=other), code="other.%s = this.%s" % (other_attr, attr)) self.js_on_change(attr, cb)
def init(): output_notebook() display(Javascript(_init_js)) but = '<img src="resources/show.png" width="34" height="25" style="display: inline" alt="Slideshow button" title="Enter/Exit RISE Slideshow">' txt = Div(text='<h2>You can now start the slideshow!</h3>' + f'<h3 style="margin: 0.5em 0;">Just click the RISE slideshow button above - the one that looks like: {but}<br/>' + '(or you can press alt+R on your keyboard instead if you prefer).</h3>') clearbutton = Button(label="Clear") clearbutton.js_on_click(CustomJS(code='primes_clear();')) cleartext = Paragraph(text='Clear all plots and outputs (e.g. before restarting slideshow).') increm = Toggle(label='Incremental', active=True) increm.js_on_click(CustomJS(code='primes_incremental(cb_obj.active)')) incremtext = Paragraph(text='Update timing plots incrementally (disable for static slide show).') repeats = Slider(start=1, end=10, value=3) repeats.js_on_change('value', CustomJS(code='primes_repeats(cb_obj.value)')) repeatstext = Paragraph(text='Repeats for timing measurements (higher is more accurate, but slower).') controls = layout([[clearbutton, cleartext], [increm, incremtext], [repeats, repeatstext]]) show(column(txt, controls, sizing_mode='stretch_width'))
def color_picker(): red = color_slider("R", "red") green = color_slider("G", "green") blue = color_slider("B", "blue") hex_color = '#888888' source = ColumnDataSource(data=dict(color=[hex_color])) p1 = figure(x_range=(-8, 8), y_range=(-4, 4), plot_width=100, plot_height=100, title='move sliders to change', tools='', toolbar_location=None) p1.axis.visible = False p1.rect(0, 0, width=18, height=10, fill_color='color', line_color='black', source=source) cb = CustomJS(args=dict(source=source, red=red, green=green, blue=blue), code=""" function componentToHex(c) { var hex = c.toString(16) return hex.length == 1 ? "0" + hex : hex } function rgbToHex(r, g, b) { return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b) } function toInt(v) { return v | 0 } const color = source.data['color'] const R = toInt(red.value[0]) const G = toInt(green.value[0]) const B = toInt(blue.value[0]) color[0] = rgbToHex(R, G, B) source.change.emit() """) red.js_on_change('value_throttled', cb) green.js_on_change('value_throttled', cb) blue.js_on_change('value_throttled', cb) return Row(children=[ red, green, blue, p1, ])
def confidence_plot(doc_data,height,width): min_confidence = min(doc_data['prediction_confidence'].values) max_confidence = max(doc_data['prediction_confidence'].values) doc_data = ColumnDataSource(doc_data) TOOLS = "pan,box_zoom,reset,box_select" plot = figure(plot_width=width, plot_height=height, tools=TOOLS) plot.add_tools(HoverTool(tooltips=[("Name", "@documents"), ("Label", "@label"), ("Prediction", "@prediction"), ("Confidence", "@prediction_confidence")])) exp_cmap = LinearColorMapper(palette='Magma256', low=min_confidence, high=max_confidence) plot.scatter(x='x', y='y', fill_color={ "field":'prediction_confidence', 'transform': exp_cmap }, size=SIZE, source=doc_data, ) plot.js_on_event(Tap, CustomJS(args=dict(source=doc_data), code="handle_tap(source,cb_obj)")) doc_data.selected.js_on_change('indices', CustomJS(args=dict(source=doc_data), code="handle_select(source,cb_obj)")) bar = ColorBar(color_mapper=exp_cmap, location=(0, 0)) plot.add_layout(bar, "right") return plot
def joins_sides(stats, colorblind=False): """ Shows the join distribution using a scatter plot. Each join operator is shown by a dot. The x coordinate is the data read from the right-side table, and the y coordinate is the data read from the left-side table. Replicated joins are shown in a different color than Partitioned joins. For optimal performance, keep the right-side smaller than the left-side (the points should be above the y=x line). Replicated joins should be used as long as the right-side table is not too large, to prevent out-of-memory errors. If you are using CBO, ensure the correct statistics are estimated for all tables being joined using ANALYZE command. Optimization Tips - 1. Queries to the left of the black dashed line and above the orange dashed line should all use the REPLICATED join distribution type. 2. Queries to the right of the orange dashed line perform joins with an incorrect table order. Ensure statistics are used, or rewrite the queries to flip the table sides, to boost performance and save cluster resources. """ joins = list(iter_joins(stats)) if not joins: return p = figure( title="Joins distribution", x_axis_label="Right-side data read [bytes]", x_axis_type="log", y_axis_label="Left-side data read [bytes]", y_axis_type="log", sizing_mode="scale_width", tools=TOOLS, ) data = {} for stat, node, probe, build in joins: data.setdefault("x", []).append(build["input_size"]) # right-side data.setdefault("y", []).append(probe["input_size"]) # left-side data.setdefault("dist", []).append(node["distributionType"]) data.setdefault("copy_on_tap", []).append(stat["query_id"]) shape_size = _get_size(colorblind) color_map = {"PARTITIONED": "red", "REPLICATED": "blue"} marker_map = {"PARTITIONED": "circle", "REPLICATED": "square"} data["color"] = [color_map[d] for d in data["dist"]] data["marker"] = [marker_map[d] for d in data["dist"]] source = ColumnDataSource(data) p.scatter("x", "y", marker="marker", color="color", legend_group="dist", alpha=0.5, size=shape_size, source=source) p.select(type=TapTool).callback = CustomJS(args=dict(source=source), code=COPY_JS) p.legend.title = "Join distribution" p.xaxis.ticker = [1, 1e3, 1e6, 1e9, 1e12] p.yaxis.ticker = [1, 1e3, 1e6, 1e9, 1e12] add_constant_line(p, 'height', 1e6) slope = Slope(gradient=1, y_intercept=0, line_color='orange', line_dash='dashed', line_width=2) p.add_layout(slope) return p
def collision(self, site, collision_time): code = '''object.visible = toggle.active''' #toggles = [] for s, e in collision_time: print('start={}, end={}, tz={}'.format(s, e, site.timezone)) s = pytz.timezone("US/Hawaii").localize(s) e = pytz.timezone("US/Hawaii").localize(e) #print('making callback...') #callback = CustomJS.from_coffeescript(code=code, args={}) callback = CustomJS(code=code, args={}) #print('making toggle...') toggle = Toggle(label="{}-{}".format(s.strftime("%Y-%m-%d %H:%M:%S"), e.strftime("%H:%M:%S")), button_type="default", active=True, callback=callback, width=20, height=25) self.toggles.append(toggle) #print('making laser annotation...') laser_collision = BoxAnnotation(left=s, right=e, bottom=self.y_min, top=self.y_max, fill_alpha=0.2, fill_color='magenta', line_color='magenta', line_alpha=0.2) #print('adding layout...') self.fig.add_layout(laser_collision) callback.args = {'toggle': toggle, 'object': laser_collision}
def _set_all_callbacks(self, all=False): """ attach a bokeh CustomJS that will be called when a widget is changed, that puts the value of the widget in the URL, for ALL widget callbacks. """ _args, _parms_all = self._make_args_parms() for key in self.widgets: self.logger.debug("{} - init_done {}".format(key, self.widgets[key]["init_done"])) if not all and self.widgets[key]["init_done"]: continue self.widgets[key]["init_done"] = True if self.widgets[key]["obj"] is not None and self.widgets[key]["pywrap_trigger"]: if isinstance(self.widgets[key]["obj"], AjaxDataSource): # AjaxDataSource, and probably ColumnDataSource, get a different # JS event handler to access the row of data from the user selection # Note that _parms_all is included so that all other widget values are # included in the AjaxDataSource event _code_all = """var idx = source.selected["1d"]["indices"][0];""" if self.widgets[key]["value_field"] is not None: _code_all +="""var params = {{ {} '{}': idx + ',' + source.data["{}"][idx] }};""".format(_parms_all, key, self.widgets[key]["value_field"]) else: _code_all +="""var params = {{ {} '{}': idx }};""".format(_parms_all, key) _code_all += """postAndRedirect('{}', params, '{}');""".format(self.url, key) __args = {**_args, **dict(source=self.widgets[key]["obj"])} callback = CustomJS(args=__args, code=_code_all) self.widgets[key]["obj"].selected.js_on_change('indices', callback) else: _code_all = """ var params = {{ {} }}; postAndRedirect('{}', params, '{}'); """.format(_parms_all, self.url, key) self.widgets[key]["obj"].callback = CustomJS(args=_args, code=_code_all)
def add_deselect_tool(self): ''' This tool should be added only once per tab ''' js_code = """ window.top.postMessage({ 'signal': 'deselect-tool', }, '*'); // to main_renderer.js """ deselect_tool = CustomAction( # I took this from ResetTool that inherits from CustomAction icon=path.join(IMG, 'deselect.png'), callback=CustomJS(code=js_code, args=dict(source=self.env.source, reset_selection=self.env.reset_selection)), action_tooltip='Reset Selection' ) self.plot.add_tools(deselect_tool) # reset is needed?
def enable_interaction(self): data_source = self._scatter.data_source self.figure.js_on_event('tap', CustomJS(args=dict(source=data_source), code=""" var data = { 'x': source.data.x, 'y': source.data.y }; data['x'].push(cb_obj['x']); data['y'].push(cb_obj['y']); source.data = data; source.change.emit(); """)) self.register_state_attribute('inputs', data_source, 'data')
def _checkbox_group(source, subgroup_col): checkbox_title = Div(text=str(subgroup_col).title() + ": ") checkbox_labels = sorted(set(source.data[subgroup_col])) actives = list(range(len(checkbox_labels))) checkboxes = CheckboxGroup( labels=checkbox_labels, active=actives, inline=True, name="subgroup_checkbox", ) checkboxes.js_on_change( "active", CustomJS(code="source.change.emit();", args={"source": source})) return Row(checkbox_title, checkboxes, name="subgroup_widget")
def mg_select(csvList, bar_source, status): select = Select(title="csv File:", value=csvList[0], options=[*enumerate(csvList)]) # Select Code with open(dir_path + '/select.js', 'r') as select_file: select_code = select_file.read() select_callback = CustomJS(args=dict(select=select, bar_source=bar_source, status=status), code=select_code) select.js_on_change('value', select_callback) return select
def mg_slider(source, timeList, time, bar_source, status): slider = Slider(start=1, end=len(time), value=1, step=1, title="Time") with open(dir_path + '/slider.js', 'r') as slider_file: slider_code = slider_file.read() callback = CustomJS(args=dict(source=source, slider=slider, timeList=timeList, bar_source=bar_source, status=status), code=slider_code) slider.js_on_change('value', callback) return slider
def constructLines(directory, df, col1, col2, cachebust, redir_url, file): filename = str(file + "gating" + cachebust + ".html") output_file(os.path.join(directory, filename)) print(df.columns) x = df[col1] y = df[col2] data = pd.DataFrame(dict(x=x, y=y)) source = ColumnDataSource(data) handler = CustomJS(args=dict(source=source), code=""" var src_dat = source.selected['1d']['indices']; var conv_data = JSON.stringify(src_dat); console.log(conv_data); var xhr = new XMLHttpRequest(); xhr.open("POST", '{0}', true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send("json=" + conv_data); var but = document.getElementsByClassName("bk-btn-success").item(0); but.innerHTML = "<p>Reload the page (auto reload in 5 seconds)</p>"; console.log(but);""".format(redir_url, file)) p = figure(plot_height=500, plot_width=1000, title=col1 + " vs " + col2 + ' Gating', x_axis_label=col1, y_axis_label=col2) p.scatter(x="x", y="y", source=source, fill_alpha=0.6, size=8) hover = HoverTool(tooltips=[(col1, "$x"), (col2, "$y")]) p.add_tools(hover) p.add_tools(LassoSelectTool()) p.add_tools(BoxSelectTool()) bargraphs = [] bargraphs.append(p) btn = Button(label='Submit selected points', button_type="success", callback=handler) bargraphs.append(btn) #df1[c[activegroup.data['source']]], df2[c[activegroup.data['source']]] #grid = gridplot([widgetbox(view_selection)], bargraphs, scatterplots) l = layout(bargraphs) save(l)
def _subgroup_slider(source, subgroup_col): sorted_uniques = np.array(sorted(set(source.data[subgroup_col]))) min_val, max_val = sorted_uniques[0], sorted_uniques[-1] min_dist_btw_vals = (sorted_uniques[1:] - sorted_uniques[:-1]).min() slider = RangeSlider( start=min_val - 0.05 * min_val, end=max_val + 0.05 * max_val, value=(min_val, max_val), step=min_dist_btw_vals, title=subgroup_col.title(), name="subgroup_widget", ) slider.js_on_change( "value", CustomJS(code="source.change.emit();", args={"source": source})) return slider
def gauge_small_bokeh(binned): """Returns a 200x124 pixel histogram. Param binned is the main output of some histogramme; should be an array with len() == 256""" p = bokeh.plotting.figure(plot_width=256, plot_height=160, tools='box_zoom') p.toolbar.logo = None p.toolbar_location = None p.xaxis.visible = False p.yaxis.visible = False p.xgrid.grid_line_color = None p.ygrid.grid_line_color = None p.x_range.range_padding = p.y_range.range_padding = 0 # This next sets a double tap on image to reset zoom and pan p.js_on_event(DoubleTap, CustomJS(args=dict(p=p), code='p.reset.emit()')) p.vbar(x=eight_bit_range, width=1.0, bottom=0, top=binned, color='#404040') return p
def makecallbacky(self): code = ''' var column = cb_obj.value; plot.glyph.y.field = column; source.trigger('change'); ''' self.callbacky = CustomJS(args=dict(plot=self.plot, source=self.source, figure=self.figure), code=code) try: print('I am here') self.figure.yaxis.axis_label = self.ywidgetbox.value except: pass
def _add_select_tools(current_src, other_src, param_plot, point_glyph): select_js_kwargs = {"current_src": current_src, "other_src": other_src} select_js_code = """ // adapted from https://stackoverflow.com/a/44996422 var chosen = current_src.selected.indices; if (typeof(chosen) == "number"){ var chosen = [chosen] }; var chosen_models = []; for (var i = 0; i < chosen.length; ++ i){ chosen_models.push(current_src.data['model'][chosen[i]]) }; var chosen_models_indices = []; for (var i = 0; i < current_src.data['index'].length; ++ i){ if (chosen_models.includes(current_src.data['model'][i])){ chosen_models_indices.push(i) }; }; current_src.selected.indices = chosen_models_indices; current_src.change.emit(); for (var i = 0; i < other_src.length; ++i){ var chosen_models_indices = []; for (var j = 0; j < other_src[i].data['index'].length; ++ j){ if (chosen_models.includes(other_src[i].data['model'][j])){ chosen_models_indices.push(j) }; }; other_src[i].selected.indices = chosen_models_indices; other_src[i].change.emit(); }; """ select_callback = CustomJS(args=select_js_kwargs, code=select_js_code) # point_glyph as only renderer assures that when a point is chosen # only that point's model is chosen # this makes it impossible to choose models based on clicking confidence bands tap = TapTool(renderers=[point_glyph], callback=select_callback) param_plot.tools.append(tap) boxselect = BoxSelectTool(renderers=[point_glyph], callback=select_callback) param_plot.tools.append(boxselect)
def makecallbackx(self): code = ''' var column = cb_obj.value; plot.glyph.x.field = column; source.trigger('change'); console.log(cb_obj.value); console.log(source); ''' self.callbackx = CustomJS(args=dict(plot=self.plot, source=self.source, figure=self.figure), code=code) try: self.figure.xaxis.axis_label = self.xwidgetbox.value except: pass
def show_hide_subplot(mainplot_source, \ novos_source, \ novos_length): global m_code global subplot global subplot_source global subplot_dict subplot_colors_length = len(subplot_dict['B2SColors']) return CustomJS(args=dict(allSource=mainplot_source, \ novosSource=novos_source, \ subplotSource=subplot_source, \ subplotColorsLength=subplot_colors_length, \ novosLength=novos_length, \ subplot=subplot \ ),\ code=m_code)
def interactive_CMD(specs,cid1='g_SDSS',cid2='i_SDSS'): ''' Simplistic tool to create an interactive bokeh plot where outliers can be marked and saved in '/home/ekaterina/Documents/appaloosa/stars_shortlist/share/temp' ''' # Create some random data and put it into a ColumnDataSource s = specs.set_index('EPIC') s = s[[cid1, cid2, 'e_'+cid1,'e_'+cid2]].dropna(how='any') x = list(s[cid1]-s[cid2]) y = list(s[cid2]) size = list(np.sqrt(s['e_'+cid1]**2+s['e_'+cid2]**2)*100.) z = list(s.index.values) source_data = ColumnDataSource(data=dict(x=x, y=y,desc=z)) # Create a button that saves the coordinates of selected data points to a file savebutton = Button(label="Save", button_type="success") savebutton.callback = CustomJS(args=dict(source_data=source_data), code=""" var inds = source_data.selected['1d'].indices; var data = source_data.data; var out = ""; for (i = 0; i < inds.length; i++) { out += data['desc'][inds[i]] + " "; } var file = new Blob([out], {type: 'text/plain'}); var elem = window.document.createElement('a'); elem.href = window.URL.createObjectURL(file); elem.download = 'selected-data.txt'; document.body.appendChild(elem); elem.click(); document.body.removeChild(elem); """) # Plot the data and save the html file p = figure(plot_width=800, plot_height=400, #y_range=(20,7), tools="lasso_select, reset, hover",) p.circle(x='x', y='y', source=source_data, fill_alpha=0.8)#add size='desc' to visualize uncertainties on mag p.xaxis.axis_label = '{}-{}'.format(cid1,cid2) p.yaxis.axis_label = cid1 plot = Column(p, savebutton) output_file("test.html") show(plot) return
def _init_bridge_plot(self): lg.info('-- INIT BRIDGE PLOT') self.bridge_plot = figure( plot_width=200, plot_height=200, ) self.bridge_plot.css_classes = ['bridge_plot'] source = ColumnDataSource({ 'x': [1, 2, 3], 'y': [4, 5, 6], }) self.bridge_trigger = self.bridge_plot.scatter( x='x', y='y', source=source, size=1, color="navy", alpha=0.5 ) self.bridge_plot_callback = CustomJS(code=""" // This content will be overwritten by the method run_js_code() """) self.bridge_trigger.glyph.js_on_change('size', self.bridge_plot_callback)
def createManualTool(self): callback = CustomJS(args=dict(button=self.manual), code=""" /// get BoxSelectTool dimensions from cb_data parameter of Callback var geometry = cb_data['geometry']; button.data = { x0: geometry['x0'], x1: geometry['x1'], y: geometry['y'] }; // Callback to the backend button.clicks++; """) self.manualTool = BothDimensionsSelectTool( tool_name = "Peak Picking By Threshold", icon = "my_icon_peak_picking", callback = callback, id = "peakPickingByThresholdTool" )
def page_a(): global widgets init_widgets() # Create a dominate document, see https://github.com/Knio/dominate widgets.dominate_document() with widgets.dom_doc.body: # add css elements here... style(raw("""body {background-color:powderblue;}""")) args, _redirect_page_metrics = widgets.process_req(request) if not args: return _redirect_page_metrics app.logger.info("{} : args {}".format(PAGE_URL, args)) # redirect to another page based on widget data... _redirect = redirect_lookup_table(args.get("sel_nexturl", None)) if _redirect: return redirect(_redirect) widgets.get("sel_nexturl").value = '99' doc_layout = layout(sizing_mode='scale_width') doc_layout.children.append( row(Div(text="""<h1>pywrapBokeh</h1><h2>Page A</h2>"""), Paragraph(text="""Play with all these widgets."""))) source = AjaxDataSource( data=dict(x=[], y=[]), adapter=CustomJS(code="return cb_data.response"), data_url="http://127.0.0.1:6800{}".format(PAGE_URL_GET_DATA), polling_interval=1000, mode='append') fig = figure(title="Streaming Example") fig.line('x', 'y', source=source) doc_layout.children.append(fig) doc_layout.children.append(row(widgets.get("sel_nexturl"))) return widgets.render(doc_layout)
def createTool(self): callback = CustomJS(args=dict(button=self.manual), code=""" /// get BoxSelectTool dimensions from cb_data parameter of Callback var geometry = cb_data['geometry']; button.data = { x0: geometry['x0'], x1: geometry['x1'], y: geometry['y'], y0: geometry['y0'], y1: geometry['y1'] }; // Callback to the backend button.clicks++; """) self.tool = BothDimensionsSelectTool(tool_name="Multiplet Analysis", icon="my_icon_multiplet_analysis", callback=callback, id="multipletAnalysisTool")
def _create_checkbox(widget_labels, all_src): widget_js_kwargs = {"all_src": all_src, "group_list": widget_labels} widget_js_code = """ // adapted from https://stackoverflow.com/a/36145278 var chosen_inds = cb_obj.active; var chosen_widget_groups = []; for (var i = 0; i < group_list.length; ++ i){ if (chosen_inds.includes(i)){ chosen_widget_groups.push(group_list[i]) }; }; for (var j = 0; j < all_src.length; ++ j){ to_select_inds = [] for (var i = 0; i < all_src[j].data['index'].length; ++ i){ if (chosen_widget_groups.includes(all_src[j].data['model_class'][i])){ to_select_inds.push(i) }; }; all_src[j].selected.indices = to_select_inds; all_src[j].change.emit(); }; """ widget_callback = CustomJS(args=widget_js_kwargs, code=widget_js_code) cb_group = CheckboxGroup( labels=widget_labels, active=[0] * len(widget_labels), callback=widget_callback, inline=True, ) return cb_group
def __init__(self, doc): # Save reference self.doc = doc # Dataset self._df = DATASET # Entire dataset self._dfs = INITIAL # Pre-processed KPI dataset self.ads_list = PROBES # All probes in the dashboard self.p_range = np.arange(0.5, 20.5, 0.5) # Adsorbate definitions self.g1 = SETTINGS['g1'] self.g2 = SETTINGS['g2'] # Temperature definitions self.t_abs = SETTINGS['t_abs'] self.t_tol = SETTINGS['t_tol'] # Isotherm type definitions self.iso_type = None # Pressure definitions self.lp = '1' # 0.5 bar self.p1 = '1' # 0.5 bar self.p2 = '10' # 5.0 bar # Bokeh-specific data source generation self.data = ColumnDataSource( data=self.gen_data(self.lp, self.p1, self.p2)) self.errors = ColumnDataSource(data=self.gen_error()) self.g1_iso_sel = ColumnDataSource(data=self.gen_iso_dict()) self.g2_iso_sel = ColumnDataSource(data=self.gen_iso_dict()) # Data selection callback self.data.selected.on_change('indices', self.selection_callback) self.data.js_on_change('data', CustomJS(code="toggleLoading()"))
def button_example(use_bokeh_server=False): if not use_bokeh_server: output_file('button.html') button = Button(label='Press Me') if use_bokeh_server: # To use real Python callbacks, a Bokeh server application may be used. def button_python_callback(window=None): print('Button is cicked.') button.on_click(button_python_callback) else: # Only JavaScript callbacks may be used with standalone output. button_javascript_callback = CustomJS(code=""" console.log('Click event occured at x-position: ') """) button.js_on_event(events.ButtonClick, button_javascript_callback) layout = column(button) if use_bokeh_server: curdoc().add_root(layout) else: show(layout)
xdr = DataRange1d() ydr = DataRange1d() plot = Plot(x_range=xdr, y_range=ydr) circle = Circle(x="x", y="y", radius=0.2, fill_color="color", line_color="black") circle_renderer = plot.add_glyph(source, circle) plot.add_layout(LinearAxis(), "below") plot.add_layout(LinearAxis(), "left") customjs = CustomJS.from_coffeescript( args=dict(source=source), code=""" import {get_indices} from "core/util/selection" for i in get_indices(source) color = source.data['color'][i] window.alert("Selected color: #{color}") """, ) tap = TapTool(renderers=[circle_renderer], callback=customjs) plot.add_tools(PanTool(), WheelZoomTool(), tap) doc = Document() doc.add_root(plot) if __name__ == "__main__": doc.validate() filename = "customjs.html" with open(filename, "w") as f:
xdr = DataRange1d() ydr = DataRange1d() plot = Plot(x_range=xdr, y_range=ydr) circle = Circle(x="x", y="y", radius=0.2, fill_color="color", line_color="black") circle_renderer = plot.add_glyph(source, circle) plot.add_layout(LinearAxis(), 'below') plot.add_layout(LinearAxis(), 'left') customjs = CustomJS.from_coffeescript(args=dict(source=source), code=""" Util = require "util/util" data = source.data for i in Util.get_indices(source) color = data['color'][i] window.alert("Selected color: #{color}") """) tap = TapTool(renderers=[circle_renderer], callback=customjs) plot.add_tools(PanTool(), WheelZoomTool(), tap) doc = Document() doc.add_root(plot) if __name__ == "__main__": doc.validate() filename = "customjs.html" with open(filename, "w") as f: f.write(file_html(doc, INLINE, "Demonstration of custom callback written in CoffeeScript"))