def _add_cookie_saver_to_doc(self): """Adds a dummy bokeh widget to the bokeh document. This dummy widget can be used to store cookies using a JS callback. """ cookie_saver = Toggle(visible=False, name="cookie_saver") cookie_saver.js_on_change("active", CustomJS(code="")) self._doc.add_root(cookie_saver)
tbutton.js_on_change( 'active', CustomJS(args={ 'rel_path_data': rel_path_data, 'data_filenames': [k for k in dummy_data], 'p': p, 'l': l }, code=""" console.log('Hello Toggle button') var N = data_filenames.length if (cb_obj.active == false){ var ind_label = 1 var ind_data = 0 var fullrel_path_data = rel_path_data+data_filenames[ind_data]+".json" cb_obj.label = "Show:"+data_filenames[ind_label] console.log("Loading: "+fullrel_path_data) $.getJSON(fullrel_path_data, function(data) { // This will not work on local files l.data_source.data = data l.data_source.change.emit() console.log("Loaded:"+fullrel_path_data) }) } else{ var ind_label = 0 var ind_data = 1 var fullrel_path_data = rel_path_data+data_filenames[ind_data]+".json" cb_obj.label = "Show:"+data_filenames[ind_label] console.log("Loading: "+fullrel_path_data) $.getJSON(fullrel_path_data, function(data) { // This will not work on local files l.data_source.data = data l.data_source.change.emit() console.log("Loaded:"+fullrel_path_data) }) } """))
def __init__(self, sv_rt): """Initialize a stream control widget. """ doc = curdoc() self.receiver = doc.receiver self.stats = doc.stats self.jf_adapter = doc.jf_adapter self._sv_rt = sv_rt # connect toggle button def toggle_callback(_active): if _active or not self._prev_image_buffer: self.prev_image_slider.disabled = True else: self.prev_image_slider.disabled = False self._update_toggle_view() toggle = Toggle(label="Connect", button_type="primary", tags=[True], default_size=145) toggle.js_on_change("tags", CustomJS(code=js_backpressure_code)) toggle.on_click(toggle_callback) self.toggle = toggle # data type select datatype_select = Select( title="Data type:", value="Image", options=["Image", "Gains"], default_size=145 ) self.datatype_select = datatype_select # conversion options conv_opts_div = Div(text="Conversion options:", margin=(5, 5, 0, 5)) conv_opts_cbg = CheckboxGroup( labels=["Mask", "Gap pixels", "Geometry"], active=[0, 1, 2], default_size=145 ) self.conv_opts_cbg = conv_opts_cbg self.conv_opts = column(conv_opts_div, conv_opts_cbg) # double pixels handling double_pixels_div = Div(text="Double pixels:", margin=(5, 5, 0, 5)) double_pixels_rg = RadioGroup(labels=DP_LABELS, active=0, default_size=145) self.double_pixels_rg = double_pixels_rg self.double_pixels = column(double_pixels_div, double_pixels_rg) # rotate image select rotate_values = ["0", "90", "180", "270"] rotate_image = Select( title="Rotate image (deg):", value=rotate_values[0], options=rotate_values, default_size=145, ) self.rotate_image = rotate_image # show only events self.show_only_events_toggle = CheckboxGroup(labels=["Show Only Events"], default_size=145) # Previous Image slider self._prev_image_buffer = deque(maxlen=60) def prev_image_slider_callback(_attr, _old, new): sv_rt.metadata, sv_rt.image = self._prev_image_buffer[new] # TODO: fix this workaround sv_rt.aggregated_image = sv_rt.image prev_image_slider = Slider( start=0, end=59, value_throttled=0, step=1, title="Previous Image", disabled=True, ) prev_image_slider.on_change("value_throttled", prev_image_slider_callback) self.prev_image_slider = prev_image_slider doc.add_periodic_callback(self._update_toggle_view, 1000)
def make_cbd_plot(session, current_user, flight_id, width, height, return_plot=False, pageref=0, dataset='antarctica', flight_date=None): if flight_date is None: df = pd.read_sql(FilmSegment.query_visible_to_user(current_user, session=session).filter(FilmSegment.dataset == dataset) \ .filter(FilmSegment.flight == flight_id).statement, session.bind) else: df = pd.read_sql(FilmSegment.query_visible_to_user(current_user, session=session).filter(FilmSegment.dataset == dataset) \ .filter(and_(FilmSegment.flight == flight_id, FilmSegment.raw_date == flight_date)).statement, session.bind) # Add colormaps to plot unique_reels = df['reel'].unique() reel_map = {r: idx for idx, r in enumerate(unique_reels)} reel_cm = plt.cm.get_cmap('viridis', len(unique_reels)) df['Color by Reel'] = df['reel'].apply( lambda x: mcolors.to_hex(reel_cm.colors[reel_map[x]])) df['Color by Verified'] = df['is_verified'].apply(lambda x: app.config[ 'COLOR_ACCENT'] if x else app.config['COLOR_GRAY']) df['Color by Review'] = df['needs_review'].apply(lambda x: app.config[ 'COLOR_ACCENT'] if x else app.config['COLOR_GRAY']) df['Color by Frequency'] = df['instrument_type'].apply( lambda x: app.config['COLOR_REDWOOD'] if x == FilmSegment.RADAR_60MHZ else (app.config['COLOR_PALO_ALOT'] if x == FilmSegment.RADAR_300MHZ else app.config['COLOR_GRAY'])) # source = ColumnDataSource(df) toggle_verified = Toggle(label="Show only verified") toggle_junk = Toggle(label="Hide junk", active=True) toggle_z = Toggle(label="Show Z Scopes", active=True) toggle_a = Toggle(label="Show A Scopes", active=True) toggle_verified.js_on_change( 'active', CustomJS(args=dict(source=source), code="source.change.emit()")) toggle_junk.js_on_change( 'active', CustomJS(args=dict(source=source), code="source.change.emit()")) toggle_z.js_on_change( 'active', CustomJS(args=dict(source=source), code="source.change.emit()")) toggle_a.js_on_change( 'active', CustomJS(args=dict(source=source), code="source.change.emit()")) filter_verified = CustomJSFilter(args=dict(tog=toggle_verified), code=''' var indices = []; for (var i = 0; i < source.get_length(); i++){ if ((!tog.active) || source.data['is_verified'][i]){ indices.push(true); } else { indices.push(false); } } return indices; ''') filter_junk = CustomJSFilter(args=dict(tog=toggle_junk), code=''' var indices = []; for (var i = 0; i < source.get_length(); i++){ if (tog.active && source.data['is_junk'][i]){ indices.push(false); } else { indices.push(true); } } console.log(indices); return indices; ''') filter_scope = CustomJSFilter(args=dict(tog_a=toggle_a, tog_z=toggle_z), code=''' console.log('filter_scope'); var indices = []; for (var i = 0; i < source.get_length(); i++){ if (tog_a.active && (source.data['scope_type'][i] == 'a')){ indices.push(true); } else if (tog_z.active && (source.data['scope_type'][i] == 'z')) { indices.push(true); } else { indices.push(false); } } console.log(indices); return indices; ''') view = CDSView(source=source, filters=[filter_verified, filter_junk, filter_scope]) p = figure( tools=['pan,box_zoom,wheel_zoom,box_select,lasso_select,reset,tap'], active_scroll='wheel_zoom') segs = p.segment(y0='first_frame', y1='last_frame', x0='first_cbd', x1='last_cbd', color=app.config["COLOR_GRAY"], source=source, view=view) scat_first = p.scatter('first_cbd', 'first_frame', color='Color by Verified', source=source, view=view, nonselection_fill_color=app.config["COLOR_GRAY"]) scat_last = p.scatter('last_cbd', 'last_frame', color='Color by Verified', source=source, view=view, nonselection_fill_color=app.config["COLOR_GRAY"]) p.add_tools( HoverTool(renderers=[segs], tooltips=[("Reel", "@reel"), ("Scope", "@scope_type"), ("Verified", "@is_verified")])) p.xaxis.axis_label = "CBD" p.yaxis.axis_label = "Frame" p.sizing_mode = "stretch_both" if (width is not None) and (height is not None): p.width = width p.height = height p.title.text = "Film Segments" # Select matching code from https://stackoverflow.com/questions/54768576/python-bokeh-customjs-debugging-a-javascript-callback-for-the-taping-tool cb_cselect = CustomJS(args=dict(s1=scat_first, s2=scat_last, csource=source), code=""" var selected_color = cb_obj.value; s1.glyph.line_color.field = selected_color; s1.glyph.fill_color.field = selected_color; s2.glyph.line_color.field = selected_color; s2.glyph.fill_color.field = selected_color; csource.change.emit(); """) color_select = Select(value="Color by Verified", options=[ "Color by Verified", "Color by Reel", "Color by Review", "Color by Frequency" ]) color_select.js_on_change('value', cb_cselect) p.toolbar.active_scroll = p.select_one(WheelZoomTool) if return_plot: return p, column(toggle_verified, toggle_junk, toggle_z, toggle_a, color_select), source else: layout = row( p, column(toggle_verified, toggle_junk, toggle_z, toggle_a, color_select)) script, div = components(layout) return f'\n{script}\n\n{div}\n'
def liability_plot(df_base, df_reform, span, mtr_opt): df_base = ColumnDataSource(df_base) df_reform = ColumnDataSource(df_reform) tools = "pan, zoom_in, zoom_out, reset" fig = figure(plot_width=600, plot_height=500, x_range=(-10000, 300000), y_range=(-20000, 100000), tools=tools, active_drag="pan") fig.yaxis.axis_label = "Tax Liabilities" fig.yaxis.formatter = NumeralTickFormatter(format="$0,000") filer_income = Span(location=span, dimension='height', line_color='black', line_dash='dotted', line_width=1.5) fig.add_layout(filer_income) label_format = f'{span:,}' filer_income_label = Label(x=span, y=25, y_units='screen', x_offset=10, text="{}: $".format(mtr_opt) + label_format, text_color='#303030', text_font="arial", text_font_style="italic", text_font_size="10pt") fig.add_layout(filer_income_label) axis = Span(location=0, dimension='width', line_color='#bfbfbf', line_width=1.5) fig.add_layout(axis) iitax_base = fig.line(x="Axis", y="Individual Income Tax", line_color='#2b83ba', muted_color='#2b83ba', line_width=2, legend_label="Individual Income Tax Liability", muted_alpha=0.1, source=df_base) payroll_base = fig.line(x="Axis", y="Payroll Tax", line_color='#abdda4', muted_color='#abdda4', line_width=2, legend_label='Payroll Tax Liability', muted_alpha=0.1, source=df_base) iitax_reform = fig.line(x="Axis", y="Individual Income Tax", line_color='#2b83ba', muted_color='#2b83ba', line_width=2, line_dash='dashed', legend_label="Individual Income Tax Liability", muted_alpha=0.1, source=df_reform) payroll_reform = fig.line(x="Axis", y="Payroll Tax", line_color='#abdda4', muted_color='#abdda4', line_width=2, line_dash='dashed', legend_label='Payroll Tax Liability', muted_alpha=0.1, source=df_reform) iitax_base.muted = False payroll_base.muted = False iitax_reform.muted = False payroll_reform.muted = False plot_js = """ object1.visible = toggle.active object2.visible = toggle.active """ base_callback = CustomJS(code=plot_js, args={}) base_toggle = Toggle(label="Base (Solid)", button_type="default", active=True) base_callback.args = { "toggle": base_toggle, "object1": iitax_base, "object2": payroll_base } base_toggle.js_on_change('active', base_callback) reform_callback = CustomJS(code=plot_js, args={}) reform_toggle = Toggle(label="Reform (Dashed)", button_type="default", active=True) reform_callback.args = { "toggle": reform_toggle, "object1": iitax_reform, "object2": payroll_reform } reform_toggle.js_on_change('active', reform_callback) fig.xaxis.formatter = NumeralTickFormatter(format="$0,000") fig.xaxis.axis_label = mtr_opt fig.xaxis.minor_tick_line_color = None fig.legend.click_policy = "mute" layout = column(fig, row(base_toggle, reform_toggle)) data = json_item(layout) outputs = { "media_type": "bokeh", "title": "Tax Liabilities by {} (Holding Other Inputs Constant)".format( mtr_opt), "data": data } return outputs
def credit_plot(df_base, df_reform, span, mtr_opt): df_base = ColumnDataSource(df_base) df_reform = ColumnDataSource(df_reform) tools = "pan, zoom_in, zoom_out, reset" fig = figure(plot_width=600, plot_height=500, x_range=(-2500, 70000), tools=tools, active_drag="pan") filer_income = Span(location=span, dimension='height', line_color='black', line_dash='dotted', line_width=1.5) fig.add_layout(filer_income) label_format = f'{span:,}' filer_income_label = Label(x=span, y=45, y_units='screen', x_offset=10, text="{}: $".format(mtr_opt) + label_format, text_color='#303030', text_font="arial", text_font_style="italic", text_font_size="10pt") fig.add_layout(filer_income_label) axis = Span(location=0, dimension='width', line_color='#bfbfbf', line_width=1.5) fig.add_layout(axis) eitc_base = fig.line(x="Axis", y="EITC", line_color='#2b83ba', muted_color='#2b83ba', line_width=2, legend_label="Earned Income Tax Credit", muted_alpha=0.1, source=df_base) ctc_base = fig.line(x="Axis", y="CTC", line_color='#abdda4', muted_color='#abdda4', line_width=2, legend_label='Nonrefundable Child Tax Credit', muted_alpha=0.1, source=df_base) ctc_refund_base = fig.line(x="Axis", y="CTC Refundable", line_color='#fdae61', muted_color='#fdae61', line_width=2, legend_label='Refundable Child Tax Credit', muted_alpha=0.1, source=df_base) cdcc_base = fig.line(x="Axis", y="Child care credit", line_color='#d7191c', muted_color='#d7191c', line_width=2, legend_label='Child and Dependent Care Credit', muted_alpha=0.1, source=df_base) eitc_reform = fig.line(x="Axis", y="EITC", line_color='#2b83ba', muted_color='#2b83ba', line_width=2, line_dash='dashed', legend_label="Earned Income Tax Credit", muted_alpha=0.1, source=df_reform) ctc_reform = fig.line(x="Axis", y="CTC", line_color='#abdda4', muted_color='#abdda4', line_width=2, line_dash='dashed', legend_label='Nonrefundable Child Tax Credit', muted_alpha=0.1, source=df_reform) ctc_refund_reform = fig.line(x="Axis", y="CTC Refundable", line_color='#fdae61', muted_color='#fdae61', line_width=2, line_dash='dashed', legend_label='Refundable Child Tax Credit', muted_alpha=0.1, source=df_reform) cdcc_reform = fig.line(x="Axis", y="Child care credit", line_color='#d7191c', muted_color='#d7191c', line_width=2, line_dash='dashed', legend_label='Child and Dependent Care Credit', muted_alpha=0.1, source=df_reform) ctc_base.muted = True ctc_refund_base.muted = True cdcc_base.muted = True ctc_reform.muted = True ctc_refund_reform.muted = True cdcc_reform.muted = True plot_js = """ object1.visible = toggle.active object2.visible = toggle.active object3.visible = toggle.active object4.visible = toggle.active """ base_callback = CustomJS(code=plot_js, args={}) base_toggle = Toggle(label="Base (Solid)", button_type="default", active=True) base_callback.args = { "toggle": base_toggle, "object1": eitc_base, "object2": cdcc_base, "object3": ctc_base, "object4": ctc_refund_base } base_toggle.js_on_change('active', base_callback) reform_callback = CustomJS(code=plot_js, args={}) reform_toggle = Toggle(label="Reform (Dashed)", button_type="default", active=True) reform_callback.args = { "toggle": reform_toggle, "object1": eitc_reform, "object2": cdcc_reform, "object3": ctc_reform, "object4": ctc_refund_reform } reform_toggle.js_on_change('active', reform_callback) fig.yaxis.formatter = NumeralTickFormatter(format="$0,000") fig.yaxis.axis_label = "Tax Credits" fig.xaxis.formatter = NumeralTickFormatter(format="$0,000") fig.xaxis.axis_label = mtr_opt fig.xaxis.minor_tick_line_color = None fig.legend.click_policy = "mute" layout = column(fig, row(base_toggle, reform_toggle)) data = json_item(layout) outputs = { "media_type": "bokeh", "title": "Tax Credits by {} (Holding Other Inputs Constant)".format(mtr_opt), "data": data } return outputs
'Pennsylvania, US', 'Rhode Island, US', 'South Carolina, US', 'South Dakota, US', 'Tennessee, US', 'Texas, US', 'Utah, US', 'Vermont, US', 'Virginia, US', 'Washington, US', 'West Virginia, US', 'Wisconsin, US', 'Wyoming, US' ] button_continental_us_only = Toggle(label="Continental US Only", visible=True, button_type='default', name='button_continental_us_only') button_continental_us_only.js_on_change( 'active', CustomJS(args={ 'event': 'button_continental_us_only', 'mpoly': p_map_mpoly, 'ext_datafiles': ext_datafiles, 'source_map': source_map, 'p_map': p_map, 'continental_states': continental_states, }, code=callback_widgets)) # Selectors for the map selectors_map = [] opts = [ k for k in init_data.keys() if isinstance(init_data[k][0], int) or isinstance(init_data[k][0], float) ] opts = sorted(opts) select = Select(title="Data For Map Coloring:", value=p_map_mpoly.glyph.fill_color['field'],
def aggregate_plot(tb): """ Function for creating a bokeh plot that shows aggregate tax liabilities for each year the TaxBrain instance was run Parameters ---------- tb: An instance of the TaxBrain object Returns ------- Bokeh figure """ # Pull aggregate data by year and transpose it for plotting varlist = ["iitax", "payrolltax", "combined"] base_data = tb.multi_var_table(varlist, "base").transpose() base_data["calc"] = "Base" reform_data = tb.multi_var_table(varlist, "reform").transpose() reform_data["calc"] = "Reform" base_cds = ColumnDataSource(base_data) reform_cds = ColumnDataSource(reform_data) num_ticks = len(base_data) del base_data, reform_data fig = figure(title="Aggregate Tax Liability by Year", width=700, height=500, tools="save") ii_base = fig.line(x="index", y="iitax", line_width=4, line_color="#12719e", legend_label="Income Tax - Base", source=base_cds) ii_reform = fig.line(x="index", y="iitax", line_width=4, line_color="#73bfe2", legend_label="Income Tax - Reform", source=reform_cds) proll_base = fig.line(x="index", y="payrolltax", line_width=4, line_color="#408941", legend_label="Payroll Tax - Base", source=base_cds) proll_reform = fig.line(x="index", y="payrolltax", line_width=4, line_color="#98cf90", legend_label="Payroll Tax - Reform", source=reform_cds) comb_base = fig.line(x="index", y="combined", line_width=4, line_color="#a4201d", legend_label="Combined - Base", source=base_cds) comb_reform = fig.line(x="index", y="combined", line_width=4, line_color="#e9807d", legend_label="Combined - Reform", source=reform_cds) # format figure fig.legend.location = "top_left" fig.yaxis.formatter = NumeralTickFormatter(format="$0.00a") fig.yaxis.axis_label = "Aggregate Tax Liability" fig.xaxis.minor_tick_line_color = None fig.xaxis[0].ticker.desired_num_ticks = num_ticks # Add hover tool tool_str = """ <p><b>@calc - {}</b></p> <p>${}</p> """ ii_hover = HoverTool(tooltips=tool_str.format("Individual Income Tax", "@iitax{0,0}"), renderers=[ii_base, ii_reform]) proll_hover = HoverTool(tooltips=tool_str.format("Payroll Tax", "@payrolltax{0,0}"), renderers=[proll_base, proll_reform]) combined_hover = HoverTool(tooltips=tool_str.format( "Combined Tax", "@combined{0,0}"), renderers=[comb_base, comb_reform]) fig.add_tools(ii_hover, proll_hover, combined_hover) # toggle which lines are shown plot_js = """ object1.visible = toggle.active object2.visible = toggle.active object3.visible = toggle.active """ base_callback = CustomJS(code=plot_js, args={}) base_toggle = Toggle(label="Base", button_type="primary", active=True) base_callback.args = { "toggle": base_toggle, "object1": ii_base, "object2": proll_base, "object3": comb_base } base_toggle.js_on_change('active', base_callback) reform_callback = CustomJS(code=plot_js, args={}) reform_toggle = Toggle(label="Reform", button_type="primary", active=True) reform_callback.args = { "toggle": reform_toggle, "object1": ii_reform, "object2": proll_reform, "object3": comb_reform } fig_layout = layout([fig], [base_toggle, reform_toggle]) reform_toggle.js_on_change('active', reform_callback) # Components needed to embed the figure data = json_item(fig_layout) outputs = { "media_type": "bokeh", "title": "", "data": data, } return outputs