def set_radio_logic(stmttable_cds: ColumnDataSource, stmt_view: CDSView, word_import_div: Div, local_metrics_div: Div, null_set_warn_div: Div, tnt_grp: RadioButtonGroup, b_grp: RadioButtonGroup, cc_grp: RadioButtonGroup) -> None: # set additional callback on radio button change someargs = dict(stmttable_cds=stmttable_cds, stmt_view=stmt_view, word_import_div=word_import_div, null_set_warn_div=null_set_warn_div, local_metrics_div=local_metrics_div, local_metrics_static_open=dashboard_constants.local_metrics_static_open, tnt_grp=tnt_grp, b_grp=b_grp, cc_grp=cc_grp) radio_callback = CustomJS(args=someargs, code=dashboard_constants.radio_callback_code) tnt_grp.js_on_change('active', radio_callback) b_grp.js_on_change('active', radio_callback) cc_grp.js_on_change('active', radio_callback)
request = { 'ds': disease_selector, 'ss': smooth_selector, 'pick': picker, 'xr': chart.x_range, 'translate': dict([(x[1], x[0]) for x in DISEASE_DROPDOWN]) } js_history = CustomJS(args=request, code=read_js('history_push.js')) js_toggle_split = CustomJS(args={'pick': picker}, code=read_js('toggle_split.js')) # Events for selector in [disease_selector, smooth_selector]: selector.on_change('value', update_plot) selector.js_on_change('value', js_history) picker.js_on_change('active', js_toggle_split) picker.js_on_change('active', js_history) picker.active = chart_type chart.x_range.callback = js_history download_button.callback = CustomJS(args=dict( source=source_split, save_path='epidemic_co_il_{}.csv'.format( disease_selector.value.lower().replace(' ', '_'))), code=read_js('save_data.js')) # Document for element in [controls, chart_range, chart, chart_split, bars]: element.sizing_mode = "stretch_both" curdoc().add_root(element) curdoc().title = "Epidemic" curdoc().template_variables.update(p=picker.active)
switch(radio.active){ case 0: left.visible = true; right.visible = false; break; case 1: left.visible = false; right.visible = true; break; default: left.visible = true; right.visible = true; } source.change.emit(); """) radio.js_on_change('active', radio_callback) slider_callback = CustomJS(args=dict(source=source, slider=slider), code=""" var a = 0; var b = Math.PI; var data = source.data; var f = Math.cos; var x = a; var y = f(a); var step = (b-a)/slider.value; data.xleft = new Array(); data.xright = new Array(); data.yleft = new Array(); data.yright = new Array(); data.bottom = new Array();
def get_dashboard(local_data=False): """ Assemble the dashboard. Define the layout, controls and its callbacks, as well as data sources. """ # Load data video_data = {} if local_data: data = pd.json_normalize( pd.read_json('data/channel/processed_data.json')['items']) with open('data/channel/processed_data.json', 'r') as f: data = json.load(f) video_data = data['items'] else: video_data = handle_channel_data.get_data_firebase()['items'] # X axis categories x_axis_map = { "Climber": "climber", "Zone": "zone", "Grade": "grade", } # Y axis categories y_axis_map = { "Count": "count", "Views": "viewCount", # "Favourites": "favoriteCount", "Likes": "likeCount", "Dislikes": "dislikeCount", "Comments": "commentCount" } # get ready to plot data barchart_data = prepare_barchart_data(video_data, x_axis_map) # html template to place the plots desc = Div(text=open(join(dirname(__file__), "templates/stats.html")).read(), sizing_mode="stretch_width") # initial data source fill data_to_plot = barchart_data['grade']['raw'] od = collections.OrderedDict( sorted(data_to_plot.items(), key=lambda x: x[0])) x_to_plot = np.array([key for key, _ in od.items()]) y_to_plot = np.array([val['count'] for _, val in od.items()]) source = ColumnDataSource(data=dict(x=x_to_plot, y=y_to_plot)) # initial data x_init = x_to_plot[0:NUM_RESULTS] y_init = y_to_plot[0:NUM_RESULTS] # Create Input controls checkbox_limit_results = CheckboxGroup( labels=["Show only first 50 results"], active=[0]) label_slider = Slider(start=0, end=90, value=90, step=1, title="Label Angle") range_slider = RangeSlider(title="Value Range", start=0, end=max(y_to_plot), value=(0, max(y_to_plot)), step=1) min_year = Slider(title="From", start=2015, end=2020, value=2015, step=1) max_year = Slider(title="To", start=2015, end=2020, value=2020, step=1) sort_order = RadioButtonGroup( labels=["Alphabetically", "Decreasing", "Increasing"], active=0) x_axis = Select(title="X Axis", options=sorted(x_axis_map.keys()), value="Grade") y_axis = Select(title="Y Axis", options=sorted(y_axis_map.keys()), value="Count") checkbox = CheckboxGroup( labels=["Show ratio with respect to number of videos"], active=[]) # show number of categories x_count_source = ColumnDataSource( data=dict(x_count=[len(x_init)], category=[x_axis.value])) columns = [ TableColumn(field="category", title="Category"), TableColumn(field="x_count", title="Count"), ] x_count_data_table = DataTable(source=x_count_source, columns=columns, width=320, height=280) # Generate the actual plot # p = figure(x_range=x_to_plot, y_range=(0, max(y_to_plot)), plot_height=250, title="{} {}".format(x_axis.value, y_axis.value), # toolbar_location="above") p = figure(x_range=x_init, y_range=(0, max(y_init)), plot_height=250, title="{} {}".format(x_axis.value, y_axis.value), toolbar_location="above") # Fill it with data and format it p.vbar(x='x', top='y', width=0.9, source=source) p.xaxis.major_label_orientation = math.pi / 2 p.add_tools(HoverTool(tooltips=[("name", "@x"), ("count", "@y")])) # Controls controls = [ checkbox_limit_results, range_slider, min_year, max_year, sort_order, x_axis, y_axis, checkbox, label_slider, x_count_data_table ] # Callbacks for controls label_callback = CustomJS(args=dict(axis=p.xaxis[0]), code=""" axis.major_label_orientation = cb_obj.value * Math.PI / 180; """) label_slider.js_on_change('value', label_callback) # limit checkbox checkbox_limit_results_callback = CustomJS( args=dict(source=source, x_source=x_count_source, o_data=barchart_data, sort_order=sort_order, x_axis_map=x_axis_map, x_axis=x_axis, y_axis_map=y_axis_map, y_axis=y_axis, range_slider=range_slider, checkbox=checkbox, fig=p, title=p.title), code=SORT_FUNCTION + JS_NUM_RESULTS + """ var data = o_data[x_axis_map[x_axis.value]]; var x = data['x']; var y = data['y']; var apply_limit = cb_obj.active.length > 0; var is_ratio = checkbox.active.length > 0; title.text = x_axis.value.concat(" ", y_axis.value); // Sort data var sorted_data = sortData(data['raw'], sort_order.active, y_axis_map[y_axis.value], is_ratio); var new_y = []; var new_x = []; var final_x = []; var final_y = []; for (var i = 0; i < x.length; i++) { if (apply_limit) { if(sorted_data[i][1] >= range_slider.value[0] && sorted_data[i][1] <= range_slider.value[1]) { new_x.push(sorted_data[i][0]); new_y.push(sorted_data[i][1]); } } else { new_x.push(sorted_data[i][0]); new_y.push(sorted_data[i][1]); } } if (apply_limit) { final_x = new_x.slice(0, num_results); final_y = new_y.slice(0, num_results); window.should_update_range = false; } else { final_x = new_x; final_y = new_y; window.should_update_range = true; } x_source.data['x_count'] = [final_x.length]; x_source.data['category'] = [x_axis.value]; x_source.change.emit(); source.data['x'] = new_x; source.data['y'] = new_y; source.change.emit(); fig.x_range.factors = []; fig.x_range.factors = final_x; if (Array.isArray(new_y) && new_y.length) { // range init and end cannot have same value var range_end = Math.max.apply(Math, new_y); if (range_end == 0 || range_end == -Infinity) { range_end = 1; } range_slider.value = [0, Math.max.apply(Math, final_y)]; range_slider.end = range_end; fig.y_range.end = Math.max.apply(Math, final_y); fig.change.emit(); } """) checkbox_limit_results.js_on_change('active', checkbox_limit_results_callback) # ratio checkbox checkbox_callback = CustomJS(args=dict( source=source, x_source=x_count_source, o_data=barchart_data, sort_order=sort_order, x_axis_map=x_axis_map, x_axis=x_axis, y_axis_map=y_axis_map, y_axis=y_axis, range_slider=range_slider, checkbox_limit_results=checkbox_limit_results, fig=p, title=p.title), code=SORT_FUNCTION + JS_NUM_RESULTS + """ var data = o_data[x_axis_map[x_axis.value]]; var x = data['x']; var y = data['y']; var is_ratio = cb_obj.active.length > 0; title.text = x_axis.value.concat(" ", y_axis.value); if (is_ratio) { title.text = x_axis.value.concat(" ", y_axis.value, " per video"); } // Sort data var sorted_data = sortData(data['raw'], sort_order.active, y_axis_map[y_axis.value], is_ratio); var new_y = []; var new_x = []; var final_x = []; var final_y = []; for (var i = 0; i < x.length; i++) { if (checkbox_limit_results.active.length <= 0) { if(sorted_data[i][1] >= range_slider.value[0] && sorted_data[i][1] <= range_slider.value[1]) { new_x.push(sorted_data[i][0]); new_y.push(sorted_data[i][1]); } } else { new_x.push(sorted_data[i][0]); new_y.push(sorted_data[i][1]); } } if (checkbox_limit_results.active.length > 0) { final_x = new_x.slice(0, num_results); final_y = new_y.slice(0, num_results); window.should_update_range = false; } else { final_x = new_x; final_y = new_y; window.should_update_range = true; } x_source.data['x_count'] = [final_x.length]; x_source.data['category'] = [x_axis.value]; x_source.change.emit(); source.data['x'] = new_x; source.data['y'] = new_y; source.change.emit(); fig.x_range.factors = []; fig.x_range.factors = final_x; if (Array.isArray(new_y) && new_y.length) { // range init and end cannot have same value var range_end = Math.max.apply(Math, new_y); if (range_end == 0 || range_end == -Infinity) { range_end = 1; } range_slider.value = [0, Math.max.apply(Math, final_y)]; range_slider.end = range_end; fig.y_range.end = Math.max.apply(Math, final_y); fig.change.emit(); } """) checkbox.js_on_change('active', checkbox_callback) # range slider range_callback = CustomJS(args=dict( source=source, x_source=x_count_source, o_data=barchart_data, sort_order=sort_order, x_axis_map=x_axis_map, x_axis=x_axis, y_axis_map=y_axis_map, y_axis=y_axis, checkbox=checkbox, checkbox_limit_results=checkbox_limit_results, fig=p), code=SORT_FUNCTION + """ if (window.should_update_range == true) { var data = o_data[x_axis_map[x_axis.value]]; var x = data['x']; var y = data['y']; var is_ratio = checkbox.active.length > 0; // Sort data var sorted_data = sortData(data['raw'], sort_order.active, y_axis_map[y_axis.value], is_ratio); var new_y = []; var new_x = []; for (var i = 0; i < x.length; i++) { if (checkbox_limit_results.active.length <= 0) { if (sorted_data[i][1] >= cb_obj.value[0] && sorted_data[i][1] <= cb_obj.value[1]) { new_x.push(sorted_data[i][0]); new_y.push(sorted_data[i][1]); } } else { new_x.push(sorted_data[i][0]); new_y.push(sorted_data[i][1]); } } x_source.data['x_count'] = [new_x.length]; x_source.data['category'] = [x_axis.value]; x_source.change.emit(); source.data['x'] = new_x; source.data['y'] = new_y; source.change.emit(); fig.x_range.factors = []; fig.x_range.factors = new_x; if (Array.isArray(new_y) && new_y.length) { fig.y_range.end = Math.max.apply(Math, new_y); } } else { window.should_update_range = true; } """) range_slider.js_on_change('value', range_callback) # variable to group data x_axis_callback = CustomJS(args=dict( source=source, x_source=x_count_source, o_data=barchart_data, x_axis_map=x_axis_map, y_axis_map=y_axis_map, y_axis=y_axis, range_slider=range_slider, sort_order=sort_order, checkbox=checkbox, checkbox_limit_results=checkbox_limit_results, fig=p, title=p.title), code=SORT_FUNCTION + JS_NUM_RESULTS + """ title.text = cb_obj.value.concat(" ", y_axis.value); var data = o_data[x_axis_map[cb_obj.value]]; var x = data['x']; var y = data['y']; var is_ratio = checkbox.active.length > 0; if (is_ratio) { title.text = title.text.concat(" per video"); } var sorted_data = sortData(data['raw'], sort_order.active, y_axis_map[y_axis.value], is_ratio); var new_y = []; var new_x = []; var final_x = []; var final_y = []; for (var i = 0; i < x.length; i++) { new_x.push(sorted_data[i][0]); new_y.push(sorted_data[i][1]); } if (checkbox_limit_results.active.length > 0) { final_x = new_x.slice(0, num_results); final_y = new_y.slice(0, num_results); window.should_update_range = false; } else { final_x = new_x; final_y = new_y; window.should_update_range = true; } x_source.data['x_count'] = [final_x.length]; x_source.data['category'] = [cb_obj.value]; x_source.change.emit(); source.data['x'] = new_x; source.data['y'] = new_y; source.change.emit(); fig.x_range.factors = []; fig.x_range.factors = final_x; if (new_y && Array.isArray(new_y) && new_y.length) { // range init and end cannot have same value var range_end = Math.max.apply(Math, new_y); if (range_end == 0 || range_end == -Infinity) { range_end = 1; } range_slider.value = [0, Math.max.apply(Math, final_y)]; range_slider.end = range_end; fig.y_range.end = Math.max.apply(Math, final_y); fig.change.emit(); } """) x_axis.js_on_change('value', x_axis_callback) # variable to group data y_axis_callback = CustomJS(args=dict( source=source, x_source=x_count_source, o_data=barchart_data, x_axis_map=x_axis_map, x_axis=x_axis, y_axis_map=y_axis_map, range_slider=range_slider, sort_order=sort_order, checkbox=checkbox, checkbox_limit_results=checkbox_limit_results, fig=p, title=p.title), code=SORT_FUNCTION + JS_NUM_RESULTS + """ title.text = x_axis.value.concat(" ", cb_obj.value); var data = o_data[x_axis_map[x_axis.value]]; var x = data['x']; var y = data['y']; var is_ratio = checkbox.active.length > 0; if (is_ratio) { title.text = x_axis.value.concat(" ", cb_obj.value, " per video"); } var sorted_data = sortData(data['raw'], sort_order.active, y_axis_map[cb_obj.value], is_ratio); var new_y = []; var new_x = []; var final_x = []; var final_y = []; for (var i = 0; i < x.length; i++) { new_x.push(sorted_data[i][0]); new_y.push(sorted_data[i][1]); } if (checkbox_limit_results.active.length > 0) { final_x = new_x.slice(0, num_results); final_y = new_y.slice(0, num_results); window.should_update_range = false; } else { final_x = new_x; final_y = new_y; window.should_update_range = true; } x_source.data['x_count'] = [final_x.length]; x_source.data['category'] = [x_axis.value]; x_source.change.emit(); source.data['x'] = new_x; source.data['y'] = new_y; source.change.emit(); fig.x_range.factors = []; fig.x_range.factors = final_x; if (new_y && Array.isArray(new_y) && new_y.length) { // range init and end cannot have same value var range_end = Math.max.apply(Math, new_y); if (range_end == 0 || range_end == -Infinity) { range_end = 1; } range_slider.value = [0, Math.max.apply(Math, final_y)]; range_slider.end = range_end; fig.y_range.end = Math.max.apply(Math, final_y); } """) y_axis.js_on_change('value', y_axis_callback) # sort order control sort_order_callback = CustomJS(args=dict( source=source, x_source=x_count_source, o_data=barchart_data, x_axis_map=x_axis_map, x_axis=x_axis, y_axis_map=y_axis_map, y_axis=y_axis, range_slider=range_slider, checkbox=checkbox, checkbox_limit_results=checkbox_limit_results, fig=p), code=SORT_FUNCTION + JS_NUM_RESULTS + """ var data = o_data[x_axis_map[x_axis.value]]; var x = data['x']; var y = data['y']; // Sort data var is_ratio = checkbox.active.length > 0; var sorted_data = sortData(data['raw'], cb_obj.active, y_axis_map[y_axis.value], is_ratio); var new_y = []; var new_x = []; var final_x = []; var final_y = []; // push data if it lies inside range for (var i = 0; i < x.length; i++) { if (checkbox_limit_results.active.length <= 0) { if (sorted_data[i][1] >= cb_obj.value[0] && sorted_data[i][1] <= cb_obj.value[1]) { new_x.push(sorted_data[i][0]); new_y.push(sorted_data[i][1]); } } else { new_x.push(sorted_data[i][0]); new_y.push(sorted_data[i][1]); } } if (checkbox_limit_results.active.length > 0) { final_x = new_x.slice(0, 50); final_y = new_y.slice(0, 50); window.should_update_range = false; } else { final_x = new_x; final_y = new_y; window.should_update_range = true; } x_source.data['x_count'] = [final_x.length]; x_source.data['category'] = [x_axis.value]; x_source.change.emit(); source.data['x'] = new_x; source.data['y'] = new_y; source.change.emit(); fig.x_range.factors = []; fig.x_range.factors = final_x; if (new_y && Array.isArray(new_y) && new_y.length) { // range init and end cannot have same value var range_end = Math.max.apply(Math, new_y); if (range_end == 0 || range_end == -Infinity) { range_end = 1; } range_slider.value = [0, Math.max.apply(Math, final_y)]; range_slider.end = range_end; fig.y_range.end = Math.max.apply(Math, final_y); fig.change.emit(); } """) sort_order.js_on_change('active', sort_order_callback) # Define layout inputs = column(*controls, width=320, height=1000) inputs.sizing_mode = "fixed" l = layout([ [desc], [inputs, p], ], sizing_mode="scale_both") return l
def plot(location=None): ( source_df, labels, colors, location_labels, xs_df, ys_df, scales_dict ) = load_database(location=location) print(location_labels) if location is None: location = location_labels[0] print(location) source = ColumnDataSource(source_df) xs = ColumnDataSource(xs_df) ys = ColumnDataSource(ys_df) scales = ColumnDataSource(scales_dict) bfig = bokeh_plot(source) labels_group = RadioGroup( labels=labels, active=None) active = location_labels.index(location) locations_group = RadioButtonGroup( labels=location_labels, active=active, name='locations_group' ) x_scale, y_scale = scales_dict[location] x_slider = Slider( start=0.05, end=20, value=x_scale, step=0.05, title='x scale' ) y_slider = Slider( start=0.001, end=0.2, value=y_scale, step=0.001, title='y scale' ) with open('bokeh_js/bokeh_plot_onclick.js', 'r') as f: code = f.read() source.selected.js_on_change( 'indices', CustomJS( args=dict( s=source, ls=labels, r=labels_group, ), code=code ) ) with open('bokeh_js/bokeh_label_onchange.js', 'r') as f: code = f.read() labels_group.js_on_change( 'active', CustomJS( args=dict( s=source, r=labels_group, ls=labels, cs=colors), code=code ) ) with open('bokeh_js/bokeh_locations_onchange.js', 'r') as f: code = f.read() locations_group.js_on_change( 'active', CustomJS( args=dict( s=source, r=locations_group, location_labels=location_labels, xs=xs, ys=ys, scales=scales, x_slider=x_slider, y_slider=y_slider, ), code=code ) ) with open('bokeh_js/bokeh_x_slider_onchange.js', 'r') as f: code = f.read() x_slider.js_on_change( 'value', CustomJS( args=dict( s=source, r=locations_group, location_labels=location_labels, xs=xs, ys=ys, scales=scales, x_slider=x_slider, y_slider=y_slider, ), code=code ) ) with open('bokeh_js/bokeh_y_slider_onchange.js', 'r') as f: code = f.read() y_slider.js_on_change( 'value', CustomJS( args=dict( s=source, r=locations_group, location_labels=location_labels, xs=xs, ys=ys, scales=scales, x_slider=x_slider, y_slider=y_slider, ), code=code ) ) return components( column( row( locations_group, ), row( x_slider, y_slider, ), row( bfig, column( labels_group, ) ) ) )
} else if (m == 1) { var x = data['x']; var y = data['y']; var P0 = data['beta_p0']; var P1 = data['beta_p1']; var P2 = data['beta_p2']; } else if (m == 2) { var x = data['x']; var y = data['y']; var P0 = data['sarah_p0']; var P1 = data['sarah_p1']; var P2 = data['sarah_p2']; } for (var i = 0; i < x.length; i++) { var P0_beta = P0[i]**f / ( P0[i]**f + P1[i]**f + P2[i]**f ) ; var P1_beta = P1[i]**f / ( P0[i]**f + P1[i]**f + P2[i]**f ) ; x[i] = Math.sqrt(2) * (P0_beta + P1_beta / 2); y[i] = P1_beta * Math.sqrt(6) * 0.5 ; } source.change.emit(); """) slider.js_on_change('value', slider_callback) radio_button_group.js_on_change('active', button_callback) layout = column(radio_button_group, slider, p) show(layout)
def lidar2js(path, ncfile, jsfile): fname_nc = join(path,ncfile) if isfile(fname_nc): if Debug: print "Found file: ", ncfile ds = Dataset(fname_nc,'r',format="NETCDF3_CLASSIC") t_raw = ds.variables["time"] z = ds.variables["alt1"][:] bsc532 = ds.variables["bsc532"][:] bsc1064 = ds.variables["bsc1064"][:] zb = ds.variables["zb"][:] zpbl = ds.variables["zpbl"][:] t = num2date(t_raw[:], units = t_raw.units) tm = t_raw[:] ds.close() else: if Debug: print "Not found file: ", ncfile return "No Data" DX = t[1]-t[0] Dx_sec = DX.total_seconds() Nx = len(t) Nx0 = int(max_days*86400.0/Dx_sec) if Nx0<Nx: Nx=Nx0 tmin = t[-Nx] tmax = t[-1]+DX twidth = 1000.0*(tmax-tmin).total_seconds() zmin = 0 zmax = z[-1] my_cmap,my_norm,my_rgb = build_palette4(levs1,levs2,levs3,levs4) img532_raw = my_norm(bsc532[-Nx:,:]) img1064_raw = my_norm(bsc1064[-Nx:,:]) data1 = {'zbase': zb[-Nx:], 'zpbl': zpbl[-Nx:], 'tcenter': t[-Nx:] + DX/2, } data2 = { 'image532': [np.array(img532_raw.filled().T, dtype=np.int8)], 'image1064': [np.array(img1064_raw.filled().T, dtype=np.int8)], } data3 = { 'profile532': bsc532[-1,:], 'range': z } src = ColumnDataSource(data=data1) src_img = ColumnDataSource(data=data2) src_z = ColumnDataSource(data=data3) color_mapper = LinearColorMapper(palette=[rgb2hex(item) for item in my_rgb], low=0, high=my_cmap.N ) plot = figure(x_range=(tmin,tmax), y_range=(zmin,zmax), title="Attenuated Backscatter coefficient [/sr /km]", toolbar_location="above", tools = "pan,wheel_zoom,box_zoom,reset,save", active_scroll=None, active_drag=None, active_inspect=None, # toolbar_sticky=False, y_axis_label = 'Height [km]', plot_width=900, plot_height=350, ) plot.toolbar.logo=None plot2 = figure(title="Last Profile at 532 nm - {}".format(t[-1]), tools = "pan,wheel_zoom,box_zoom,reset,save", y_axis_label = 'Height [km]', x_axis_label = 'Attenuated Backscatter coefficient [/sr /km]', # y_axis_type="log", active_inspect=None, plot_width=900, plot_height=350 ) plot2.toolbar.logo=None plot2.line(x='profile532', y='range', source=src_z, line_color="black", ) im = plot.image(image="image532", source=src_img, color_mapper=color_mapper, dh=zmax, dw=twidth, x=tmin, y=zmin ) #l1 = plot.line( x='tcenter', y='zbase', source=source, line_width=2, alpha=0.8, color="black") #l2 = plot.line( x='tcenter', y='zpbl' , source=source, line_width=2, alpha=0.8, color="red") r1 = plot.circle( x='tcenter', y='zbase', source=src, fill_color="black", line_color="black", fill_alpha=0.3, size=4, name="r1" ) r2 = plot.square( x='tcenter', y='zpbl', source=src, fill_color="red", line_color="red", fill_alpha=0.3, size=4, name="r2" ) for item in [r1,r2]: item.visible = False color_bar = ColorBar(color_mapper=color_mapper, ticker=FixedTicker(ticks=[0,5,20,25]), label_standoff=12, border_line_color=None, location=(0,0) ) color_bar.bar_line_color = "black" color_bar.major_tick_line_color = "black" color_bar.formatter = FuncTickFormatter(code="return {}[tick].toExponential(2)".format(levs)) legend = Legend(items=[("Cloud Base",[r1]), ("PBL Height",[r2])], location="top_left" ) legend.click_policy = "hide" legend.visible = False hover = HoverTool(names=["r1","r2"]) hover.tooltips=[("Cloud base", "@zbase km"), ("PBL height", "@zpbl km"), ("Time", "@tcenter{%d-%b-%y %H:%M}")] hover.formatters = { "tcenter": "datetime"} hover2 = HoverTool(tooltips=[ ("Signal", "@profile532"), ("Range", "@range"), ]) plot.add_layout(color_bar, 'right') plot.add_layout(legend) plot.add_tools(hover) plot2.add_tools(hover2) plot.xaxis.formatter = DatetimeTickFormatter(months = ['%Y-%b'], years = ['%Y'], days = ['%d-%b-%Y'] ) callback = CustomJS(args=dict(im=im), code=""" var f = cb_obj.active if (f==0){ im.glyph.image.field = "image532" } else { im.glyph.image.field = "image1064" } im.glyph.change.emit(); """) radio_button_group = RadioButtonGroup(labels=["532 nm", "1064 nm"], active=0) radio_button_group.js_on_change('active',callback) callback2 = CustomJS(args=dict(leg=legend), code=""" leg.visible = !leg.visible console.log("ol") """) toggle = Toggle(label="Legend", button_type="default") toggle.js_on_click(callback2) layout = column( children=[ row(widgetbox(radio_button_group, width=200), widgetbox(toggle, width=80) ), plot, Spacer(height=50), # row(Spacer(width=50),plot2), plot2, ], ) #show(plot) return create_js(layout,path,jsfile)
def create_bokeh_figure( corners, lon_limits, lat_limits, base_url="figs/", base_height=800, image_alpha=0.8, title="GOES GeoColor Imagery at ", ): img_args, x_range, y_range, scale = compute_image_locations_ranges( corners, lon_limits, lat_limits) map_fig = figure( plot_width=int(scale * base_height), plot_height=base_height, x_axis_type="mercator", y_axis_type="mercator", x_range=x_range, y_range=y_range, title=title, toolbar_location="right", sizing_mode="scale_width", name="map_fig", ) hover = HoverTool( names=['sites'], tooltips=[("Site", "@name"), ('Value', '@value of @capacity @units Max'), ('Time', '@time')], ) map_fig.add_tools(hover) map_fig.xaxis.axis_label = ( "Data from https://registry.opendata.aws/noaa-goes/. Map tiles from Stamen Design. " # NOQA "Plot generated with Bokeh by UA HAS Renewable Power Forecasting Group." ) map_fig.xaxis.axis_label_text_font_size = "7pt" map_fig.xaxis.axis_line_alpha = 0 slider = Slider( title="GOES Image", start=0, end=1, value=1, name="timeslider", sizing_mode="scale_width", ) play_buttons = RadioButtonGroup( labels=["\u25B6", "\u25FC", "\u27F3"], active=1, name="play_buttons", sizing_mode="scale_width", ) speed_source = ColumnDataSource(data=dict(speed=[config.PLAY_SPEED]), name='speed_source') faster_button = Button(label="\u2795", sizing_mode='fixed', width=30, height=30, name="faster_button") slower_button = Button(label="\u2796", sizing_mode='fixed', width=30, height=30, name="slower_button") play_button_row = row([play_buttons, faster_button, slower_button], sizing_mode='scale_width', name='all_play_buttons') fig_source = ColumnDataSource(data=dict(url=[]), name="figsource", id="figsource") adapter = CustomJS( args=dict(slider=slider, fig_source=fig_source, base_url=base_url, title=map_fig.title, max_images=config.MAX_IMAGES), code=""" const result = {url: []} const urls = cb_data.response var pnglen = 0 var len = urls.length var start = 0 if (len > max_images) { start = len - max_images } for (i=start; i<len; i++) { var name = urls[i]['name']; if (name.endsWith('.png')) { result.url.push(base_url + name) pnglen += 1 } } slider.end = Math.max(pnglen - 1, 1) var lasturl = result.url[pnglen - 1] cb_obj.tags = [lasturl] // first run if (fig_source.data['url'].length == 0) { fig_source.data['url'][0] = lasturl fig_source.tags = [''] fig_source.change.emit() slider.value = slider.end } slider.change.emit() return result """, ) url_source = AjaxDataSource(data_url=base_url, polling_interval=10000, adapter=adapter) url_source.method = "GET" # url_source.if_modified = True pt_adapter = CustomJS(code=""" const result = {x: [], y: [], name: [], capacity: [], value: [], time: [], units: []} const pts = cb_data.response for (i=0; i<pts.length; i++) { result.x.push(pts[i]['x']) result.y.push(pts[i]['y']) result.name.push(pts[i]['name']) result.capacity.push(pts[i]['capacity']) result.units.push(pts[i]['units']) result.time.push(pts[i]['last_time']) result.value.push(pts[i]['last_value']) } return result """) pt_source = AjaxDataSource(data_url="metadata.json", polling_interval=int(1e5), adapter=pt_adapter) pt_source.method = "GET" slider_callback = CustomJS( args=dict(fig_source=fig_source, url_source=url_source), code=""" if ('url' in url_source.data && cb_obj.value < url_source.data['url'].length){ var inp_url = url_source.data['url'][cb_obj.value]; fig_source.data['url'][0] = inp_url; fig_source.tags = [inp_url]; fig_source.change.emit(); } if (cb_obj.value == cb_obj.end) { cb_obj.tags = [1] } else { cb_obj.tags = [0] } """, ) newest_callback = CustomJS(args=dict(fig_source=fig_source, slider=slider), code=""" if (slider.tags[0] == 1){ if (slider.value != slider.end) { slider.value = slider.end slider.change.emit() } fig_source.data['url'][0] = cb_obj.tags[0] fig_source.tags = [cb_obj.tags[0]]; fig_source.change.emit(); } """) title_callback = CustomJS( args=dict(title=map_fig.title, base_title=title), code=""" var url = cb_obj.data['url'][0] var date = new Date(url.split('/').pop().split('_').pop().split('.')[0]) title.text = base_title + date title.change.emit() """, ) faster_callback = CustomJS(args=dict(speed_source=speed_source, speed_incr=config.PLAY_SPEED_INCR), code=""" var old = speed_source.data['speed'][0] var newspeed = old - speed_incr if (newspeed > 0){ speed_source.data = {"speed": [newspeed]} speed_source.change.emit() } """) slower_callback = CustomJS(args=dict(speed_source=speed_source, speed_incr=config.PLAY_SPEED_INCR), code=""" var old = speed_source.data['speed'][0] var newspeed = old + speed_incr speed_source.data = {"speed": [newspeed]} speed_source.change.emit() """) change_speed_callback = CustomJS(args=dict(slider=slider, play_buttons=play_buttons, pause=config.RESTART_PAUSE), code=""" var timeoutSet = false; function fromstart(){ timeoutSet = false if (play_buttons.active == 0){ slider.value = 0 slider.change.emit() } } function advance() { if (slider.value < slider.end) { slider.value += 1 slider.change.emit() } else if (!timeoutSet){ setTimeout(fromstart, pause) timeoutSet = true; } } if (play_buttons.active == 0){ var id = play_buttons._id clearInterval(id) id = setInterval(advance, cb_obj.data['speed'][0]) play_buttons._id = id } """) play_callback = CustomJS( args=dict(slider=slider, speed_source=speed_source, pause=config.RESTART_PAUSE), code=""" function stop() { var id = cb_obj._id clearInterval(id) cb_obj.active = 1 } var timeoutSet = false; function fromstart(){ timeoutSet = false if (cb_obj.active == 0){ slider.value = 0 slider.change.emit() } } function advance() { if (slider.value < slider.end) { slider.value += 1 slider.change.emit() } else if (!timeoutSet){ setTimeout(fromstart, pause) timeoutSet = true; } } function start() { var id = setInterval(advance, speed_source.data['speed'][0]) cb_obj._id = id } if (cb_obj.active == 0) { start() } else if (cb_obj.active == 2) { stop() slider.value = 0 slider.change.emit() } else { stop() } """, ) # ajaxdatasource to nginx list of files as json possibly on s3 # write metadata for plants to file, serve w/ nginx # new goes image triggers lambda to process sns -> sqs -> lambda map_fig.add_tile(STAMEN_TONER) map_fig.image_url(url="url", global_alpha=image_alpha, source=fig_source, **img_args) if config.SERVICE_AREA is not None: geo_source = GeoJSONDataSource( geojson=getattr(areas, config.SERVICE_AREA.upper())) map_fig.patches(xs='xs', ys='ys', source=geo_source, fill_alpha=0, line_alpha=0.9, line_color=config.BLUE) map_fig.cross(x="x", y="y", size=12, fill_alpha=0.9, source=pt_source, color=config.RED, name='sites') fig_source.js_on_change("tags", title_callback) slider.js_on_change("value", slider_callback) url_source.js_on_change("tags", newest_callback) play_buttons.js_on_change("active", play_callback) faster_button.js_on_click(faster_callback) slower_button.js_on_click(slower_callback) speed_source.js_on_change("data", change_speed_callback) doc = curdoc() for thing in (map_fig, play_button_row, slider): doc.add_root(thing) doc.title = "GOES Image Viewer" return doc
def create_bokeh_figure( corners, lon_limits, lat_limits, base_url="figs/", base_height=800, image_alpha=0.8, title="GOES GeoColor Imagery at ", ): img_args, x_range, y_range, scale = compute_image_locations_ranges( corners, lon_limits, lat_limits) map_fig = figure( plot_width=int(scale * base_height), plot_height=base_height, x_axis_type="mercator", y_axis_type="mercator", x_range=x_range, y_range=y_range, title=title, toolbar_location="right", sizing_mode="scale_width", name="map_fig", tooltips=[("Site", "@name")], ) slider = Slider( title="GOES Image", start=0, end=100, value=0, name="timeslider", sizing_mode="scale_width", ) play_buttons = RadioButtonGroup( labels=["\u25B6", "\u25FC", "\u27F3"], active=1, name="play_buttons", sizing_mode="scale_width", ) fig_source = ColumnDataSource(data=dict(url=[]), name="figsource", id="figsource") adapter = CustomJS( args=dict(slider=slider, fig_source=fig_source, base_url=base_url, title=map_fig.title), code=""" const result = {url: []} const urls = cb_data.response var pnglen = 0; for (i=0; i<urls.length; i++) { var name = urls[i]['name']; if (name.endsWith('.png')) { result.url.push(base_url + name) pnglen += 1 } } slider.end = Math.max(pnglen - 1, 1) slider.change.emit() if (fig_source.data['url'].length == 0) { fig_source.data['url'][0] = result.url[0] fig_source.tags = [''] fig_source.change.emit() } return result """, ) url_source = AjaxDataSource(data_url=base_url, polling_interval=10000, adapter=adapter) url_source.method = "GET" # url_source.if_modified = True pt_adapter = CustomJS(code=""" const result = {x: [], y: [], name: []} const pts = cb_data.response for (i=0; i<pts.length; i++) { result.x.push(pts[i]['x']) result.y.push(pts[i]['y']) result.name.push(pts[i]['name']) } return result """) pt_source = AjaxDataSource( data_url=base_url + "/metadata.json", polling_interval=int(1e5), adapter=pt_adapter, ) pt_source.method = "GET" callback = CustomJS( args=dict(fig_source=fig_source, url_source=url_source), code=""" if (cb_obj.value < url_source.data['url'].length){ var inp_url = url_source.data['url'][cb_obj.value]; fig_source.data['url'][0] = inp_url; fig_source.tags = [cb_obj.value]; fig_source.change.emit(); } """, ) title_callback = CustomJS( args=dict(title=map_fig.title, base_title=title), code=""" var url = cb_obj.data['url'][0] var date = url.split('/').pop().split('_').pop().split('.')[0] title.text = base_title + date title.change.emit() """, ) play_callback = CustomJS( args=dict(slider=slider, play_speed=config.PLAY_SPEED), code=""" function stop() { var id = cb_obj._id clearInterval(id) cb_obj.active = 1 } function advance() { if (slider.value < slider.end) { slider.value += 1 } else { slider.value = 0 } slider.change.emit() } function start() { var id = setInterval(advance, play_speed) cb_obj._id = id } if (cb_obj.active == 0) { start() } else if (cb_obj.active == 2) { stop() slider.value = 0 slider.change.emit() } else { stop() } """, ) # ajaxdatasource to nginx list of files as json possibly on s3 # write metadata for plants to file, serve w/ nginx # new goes image triggers lambda to process sns -> sqs -> lambda map_fig.add_tile(STAMEN_TONER) map_fig.image_url(url="url", global_alpha=image_alpha, source=fig_source, **img_args) fig_source.js_on_change("tags", title_callback) map_fig.cross(x="x", y="y", size=12, fill_alpha=0.9, source=pt_source, color=config.RED) slider.js_on_change("value", callback) play_buttons.js_on_change("active", play_callback) doc = curdoc() for thing in (map_fig, play_buttons, slider): doc.add_root(thing) doc.title = "GOES Image Viewer" return doc
def add_buttons_to_periodic_table(plot, source, source_allEF, color_bar): formatters = [ formatter_int, formatter_1e, formatter_1e, formatter_2f, formatter_2f, formatter_2f, formatter_2f, formatter_int, formatter_2f, formatter_2f, formatter_2f, formatter_2f, formatter_2f, ] # using radiobuttons names_rb, cmap_update_rb, formatter_rb, cname_rb, newtitle_rb = [], [], [], [], [] for index in [ 0, 3, 5, 8, 9, 11 ]: # num imps, smom, omom, percent mag, charge_doping, DOSinGap names_rb.append(names[index]) cmap_update_rb.append(color_mapper_all[index]) formatter_rb.append(formatters[index]) newtitle_rb.append(names[index]) cname_rb.append('type_color' + str(index)) callback_rb = CustomJS(args=dict(source=source, cbar=color_bar, cmap_update=cmap_update_rb, formatter=formatter_rb, newtitle=newtitle_rb, cname=cname_rb), code="""/// get index of active button var idx = cb_obj.active /// set color according to color name source.data['type_color'] = source.data[cname[idx]] /// update value of plot_component index source.data['plot_component'][0] = idx /// update color mapper cbar.color_mapper = cmap_update[idx] /// update title of color bar cbar.title = newtitle[idx] /// update color bar formatter cbar.formatter = formatter[idx] ///submit changes source.change.emit(); cbar.change.emit(); """) toggles = RadioButtonGroup(labels=names_rb, active=0) toggles.js_on_change('active', callback_rb) # using radiobuttons allsources = [ source_allEF[{ -200: 1, 0: 2, 200: 3, 'all': 4 }[index]] for index in [-200, 0, 200, 'all'] ] callback_EF = CustomJS(args=dict(source=source, allsources=allsources, colorbuttons=toggles, cbar=color_bar, cmap_update=cmap_update_rb, formatter=formatter_rb, newtitle=newtitle_rb, cname=cname_rb), code=""" /// get value of active button var idx = cb_obj.active /// save value of colorbuttons active value (store in plot_component) ///colorbuttons.active = source.data['plot_component'][0] /// now overwrite data of source with new source var newsource = allsources[idx] source.data = newsource.data /// restore value of colorbuttons active button etc. idx = colorbuttons.active /// set color according to color name source.data['type_color'] = source.data[cname[idx]] /// update value of plot_component index source.data['plot_component'][0] = idx /// update color mapper cbar.color_mapper = cmap_update[idx] /// update title of color bar cbar.title = newtitle[idx] /// update color bar formatter cbar.formatter = formatter[idx] /// finally submit changes source.change.emit(); colorbuttons.change.emit() cbar.change.emit(); """) names_EF = ['EF= ' + str(EFvalue) + 'meV' for EFvalue in [-200, 0, 200]] + ['all'] EFbuttons = RadioButtonGroup(labels=names_EF, active=3) EFbuttons.js_on_change('active', callback_EF) EFtext = Paragraph(text="""Select Fermi level:""", width=110, align='start') Colortext = Paragraph(text="""Select color scale:""", width=110, align='start') buttonrow = row([Colortext] + [toggles]) layout_periodic_table = column(row([EFtext] + [EFbuttons]), buttonrow, plot, sizing_mode='scale_both') return layout_periodic_table