def modify_doc(doc): with open('window_size.pickle', 'rb') as handle: project_dict = pickle.load(handle) data = project_dict['rollbar-gem'][1] source = ColumnDataSource(data) plot = figure(x_axis_type='linear', y_range=(0, 55), y_axis_label='Improvement (%)', x_axis_label='Risk Threshold') plot.line('x', 'y', source=source) def callback(attr, old, new): global project_name if attr == 'active': data = project_dict[project_name_dict[new]][1] project_name = project_name_dict[new] else: data = project_dict[project_name][new] source.data = ColumnDataSource(data=data).data slider = Slider(start=1, end=100, value=1, step=1, title="Window Size") slider.on_change('value', callback) radio_button_group = RadioButtonGroup(labels=project_list, active=0) radio_button_group.on_change('active', callback) doc.add_root(column(radio_button_group, slider, plot)) doc.theme = Theme(filename="../../theme.yaml")
def modify_doc(doc): with open('er_batch_size.pickle', 'rb') as handle: project_dict = pickle.load(handle) data = project_dict['bb'][0.1] source = ColumnDataSource(data) plot = figure(x_axis_type='linear', y_range=(-200, 200), y_axis_label='Improvement (%)', x_axis_label='Batch Size') plot.line('x', 'y', source=source) def callback(attr, old, new): global project_name if attr == 'active': data = project_dict[project_name_dict[new]][0.1] project_name = project_name_dict[new] else: new = float('{:2f}'.format(new)) data = project_dict[project_name][new] source.data = ColumnDataSource(data=data).data slider = Slider(start=0.1, end=1, value=0.1, step=0.01, title="Risk Threshold") slider.on_change('value', callback) radio_button_group = RadioButtonGroup( labels=er_project_list, active=0) radio_button_group.on_change('active', callback) doc.add_root(column(radio_button_group, slider, plot)) doc.theme = Theme(filename="../theme.yaml")
def create_orientation_group(self) -> RadioButtonGroup: orientation = self.legend.orientation.title() active = self.ORIENTATION_LABELS.index(orientation) button_group = RadioButtonGroup(labels=self.ORIENTATION_LABELS, active=active, width=210) button_group.on_change("active", self.handle_orientation_change) return button_group
def startserver(doc): file_input = FileInput(accept=".ulg, .csv") file_input.on_change('value', upload_new_data_sim) file_input2 = FileInput(accept=".ulg, .csv") file_input2.on_change('value', upload_new_data_real) intro_text = Div(text="""<H2>Sim/Real Thiel Coefficient Calculator</H2>""", width=500, height=100, align="center") sim_upload_text = Paragraph(text="Upload a simulator datalog:", width=500, height=15) real_upload_text = Paragraph( text="Upload a corresponding real-world datalog:", width=500, height=15) #checkbox_group = CheckboxGroup(labels=["x", "y", "vx","vy","lat","lon"], active=[0, 1]) sim_reverse_button = RadioButtonGroup(labels=["Sim Default", "Reversed"], active=0) sim_reverse_button.on_change('active', lambda attr, old, new: reverse_sim()) real_reverse_button = RadioButtonGroup(labels=["Real Default", "Reversed"], active=0) real_reverse_button.on_change('active', lambda attr, old, new: reverse_real()) simsource_static.selected.on_change('indices', simselection_change) # The below are in case you want to see the x axis range change as you pan. Poorly documented elsewhere! #ts1.x_range.on_change('end', lambda attr, old, new: print ("TS1 X range = ", ts1.x_range.start, ts1.x_range.end)) #ts2.x_range.on_change('end', lambda attr, old, new: print ("TS2 X range = ", ts2.x_range.start, ts2.x_range.end)) ts1.x_range.on_change( 'end', lambda attr, old, new: change_sim_scale(ts1.x_range.start)) ts2.x_range.on_change( 'end', lambda attr, old, new: change_real_scale(ts2.x_range.start)) # set up layout widgets = column(datatype, stats) sim_button = column(sim_reverse_button) real_button = column(real_reverse_button) main_row = row(widgets) series = column(ts1, sim_button, ts2, real_button) layout = column(main_row, series) # initialize update() doc.add_root(intro_text) doc.add_root(sim_upload_text) doc.add_root(file_input) doc.add_root(real_upload_text) doc.add_root(file_input2) doc.add_root(layout) doc.title = "Flight data"
def create_horizontal_alignment_select(self) -> RadioButtonGroup: value = HorizontalAlignment[self.text_align] active = self.HORIZONTAL_ALIGNMENT.index(value) h_align_select = RadioButtonGroup( labels=["Left", "Center", "Right"], active=active, width=210, disabled=isinstance(self.model, Axis), ) h_align_select.on_change("active", self.handle_horizontal_align_change) return h_align_select
def sales_timeline(dataset): global selected_store_id, selected_dept_id div_heading = generate_header_div("Weekly, Monthly, & Quarterly Sales Timeline") div_spinner = generate_spinner_div() show_spinner(div_spinner) store_id_selector = generate_store_id_selector(dataset) dept_id_options_int = sorted(dataset.Dept.unique().tolist()) dept_id_options = list(map(str, dept_id_options_int)) dept_id_selector = Select(title="Department Id:", value=dept_id_options[0], options=dept_id_options) div_toggle_button = Div(text="Display CPI", width=80, height=7) cpi_toggle_button = RadioButtonGroup(labels=["Off", "On"], active=0) store_wise_dataset = {} for store_id in range(dataset['Store'].min(), dataset['Store'].max() + 1): store_wise_dataset[store_id] = dataset[dataset['Store'] == store_id] selected_store_id = store_id_selector.value selected_dept_id = dept_id_selector.value # ----------------------------------------------------------------------------------------------------------------- # ---------------------------------------- CPI Line Plot Data Starts Here ----------------------------------------- def get_cpi_line_plot_data_dict(sales_line_plot_data): return dict(sales_line_plot_data.data) # ----------------------------------------- CPI Line Plot Data Ends Here ------------------------------------------ # ----------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------- # -------------------------------------------- Weekly Plot Starts Here -------------------------------------------- def get_weekly_sales_data(store_id, dept_id): store_weekly_dataset = store_wise_dataset[int(store_id)] store_dept_weekly_dataset = \ store_weekly_dataset[store_weekly_dataset['Dept'] == int(dept_id)] if store_dept_weekly_dataset.empty: return None, None def date_formatter(single_row, date_type): year, month, day = single_row['Date'].split('-') if date_type == 'y': return year if date_type == 'm': return int(month) if date_type == 'd': return int(day) store_dept_weekly_dataset['year_month_week'] = store_dept_weekly_dataset.apply( lambda row: ( date_formatter(row, 'y'), calendar.month_abbr[date_formatter(row, 'm')], str(math.ceil(date_formatter(row, 'd') / 7.0))), axis=1) store_dept_sales_on_holiday_dataset = store_dept_weekly_dataset.filter( ['Date', 'year_month_week', 'Weekly_Sales', 'IsHoliday', 'CPI'], axis=1) store_dept_sales_on_holiday_dataset = store_dept_sales_on_holiday_dataset[ store_dept_sales_on_holiday_dataset['IsHoliday'] == True] return store_dept_weekly_dataset, store_dept_sales_on_holiday_dataset def get_weekly_sales_line_plot_data_dict(store_dept_weekly_dataset): return dict( year_month_week=store_dept_weekly_dataset.year_month_week.tolist(), weekly_sales=store_dept_weekly_dataset.Weekly_Sales.tolist(), is_holiday=store_dept_weekly_dataset.IsHoliday.tolist(), cpi=store_dept_weekly_dataset.CPI.tolist() ) def get_weekly_sales_circle_plot_data_dict(store_dept_sales_on_holiday_dataset): return dict( year_month_week=store_dept_sales_on_holiday_dataset.year_month_week.tolist(), weekly_sales=store_dept_sales_on_holiday_dataset.Weekly_Sales.tolist(), is_holiday=store_dept_sales_on_holiday_dataset.IsHoliday.tolist(), cpi=store_dept_sales_on_holiday_dataset.CPI.tolist() ) selected_store_dept_weekly_dataset, selected_store_dept_sales_on_holiday_dataset = \ get_weekly_sales_data(selected_store_id, selected_dept_id) weekly_sales_line_plot_data = ColumnDataSource( data=get_weekly_sales_line_plot_data_dict(selected_store_dept_weekly_dataset) ) weekly_cpi_line_plot_data = ColumnDataSource(data=get_cpi_line_plot_data_dict(weekly_sales_line_plot_data)) weekly_sales_circle_plot_data = ColumnDataSource( data=get_weekly_sales_circle_plot_data_dict(selected_store_dept_sales_on_holiday_dataset) ) weekly_sales_figure = figure( title="Weekly Sales", x_range=FactorRange(*selected_store_dept_weekly_dataset.year_month_week.tolist()), plot_width=1400, plot_height=300, tools="box_zoom,reset") weekly_sales_figure.yaxis.axis_label = 'Sales in USD' weekly_sales_figure.extra_y_ranges['CPI'] = Range1d(start=0, end=300) weekly_sales_figure.add_layout(LinearAxis(y_range_name='CPI', axis_label='CPI'), 'right') weekly_sales_line_plot = weekly_sales_figure.line( source=weekly_sales_line_plot_data, x='year_month_week', y='weekly_sales', legend_label='Sales', line_width=2, color="red") weekly_sales_circle_plot = weekly_sales_figure.circle( source=weekly_sales_circle_plot_data, x='year_month_week', y='weekly_sales', legend_label='Holiday', size=10, fill_color="blue", line_color="red", alpha=0.7) weekly_cpi_line_plot = weekly_sales_figure.line( source=weekly_cpi_line_plot_data, x='year_month_week', y='cpi', legend_label='CPI', y_range_name='CPI', line_width=2, color="green") # Adding hover tool weekly_sales_hover = HoverTool( tooltips=[ ('Holiday', '@is_holiday'), ('Sales', '$' + '@weekly_sales{0.00}'), ('CPI', '@cpi')], mode='vline') weekly_sales_figure.add_tools(weekly_sales_hover) weekly_sales_figure.xgrid.grid_line_color = None weekly_sales_line_plot_data_source = weekly_sales_line_plot.data_source weekly_sales_circle_plot_data_source = weekly_sales_circle_plot.data_source weekly_cpi_line_plot_data_source = weekly_cpi_line_plot.data_source # --------------------------------------------- Weekly Plot Ends Here --------------------------------------------- # ----------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------- # ----------------------------------------- Monthly Avg Plot Starts Here ------------------------------------------ def get_monthly_avg_sales_data(store_dept_weekly_dataset): if store_dept_weekly_dataset.empty: return store_dept_weekly_dataset store_dept_avg_monthly_dataset = store_dept_weekly_dataset store_dept_avg_monthly_dataset['Date'] = pd.to_datetime( store_dept_avg_monthly_dataset['Date']) store_dept_avg_monthly_dataset.index = pd.DatetimeIndex( store_dept_avg_monthly_dataset['Date']) store_dept_avg_monthly_dataset = store_dept_avg_monthly_dataset.groupby( pd.Grouper(freq="M")).agg( Store=('Store', 'first'), Dept=('Dept', 'first'), Avg_Monthly_Sales=('Weekly_Sales', 'mean'), Type=('Type', 'first'), Size=('Size', 'first'), Avg_Temperature=('Temperature', 'mean'), Avg_Fuel_Price=('Fuel_Price', 'mean'), Avg_CPI=('CPI', 'mean'), Unemployment=('Unemployment', 'first') ) store_dept_avg_monthly_dataset.reset_index(level=0, inplace=True) store_dept_avg_monthly_dataset['Date'] = store_dept_avg_monthly_dataset['Date'].dt.strftime( '%Y-%m') def date_formatter(single_row, date_type): year, month = single_row['Date'].split('-') if date_type == 'y': return year if date_type == 'm': return int(month) store_dept_avg_monthly_dataset['year_month'] = store_dept_avg_monthly_dataset.apply( lambda row: (date_formatter(row, 'y'), calendar.month_abbr[date_formatter(row, 'm')]), axis=1) return store_dept_avg_monthly_dataset def get_monthly_sales_line_plot_data_dict(store_dept_avg_monthly_dataset): return dict( year_month=store_dept_avg_monthly_dataset.year_month.tolist(), monthly_avg_sales=store_dept_avg_monthly_dataset.Avg_Monthly_Sales.tolist(), avg_cpi=store_dept_avg_monthly_dataset.Avg_CPI.tolist() ) selected_store_dept_avg_monthly_dataset = get_monthly_avg_sales_data(selected_store_dept_weekly_dataset) monthly_sales_line_plot_data = ColumnDataSource( data=get_monthly_sales_line_plot_data_dict(selected_store_dept_avg_monthly_dataset) ) monthly_cpi_line_plot_data = ColumnDataSource(data=get_cpi_line_plot_data_dict(monthly_sales_line_plot_data)) monthly_sales_figure = figure( title="Monthly Avg Sales", x_range=FactorRange(*selected_store_dept_avg_monthly_dataset.year_month.tolist()), plot_width=1400, plot_height=300, tools="box_zoom,reset") monthly_sales_figure.yaxis.axis_label = 'Sales in USD' monthly_sales_figure.extra_y_ranges['CPI'] = Range1d(start=0, end=300) monthly_sales_figure.add_layout(LinearAxis(y_range_name='CPI', axis_label='CPI'), 'right') monthly_sales_line_plot = monthly_sales_figure.line( source=monthly_sales_line_plot_data, x='year_month', y='monthly_avg_sales', legend_label='Sales', line_width=2, color="red") monthly_cpi_line_plot = monthly_sales_figure.line( source=monthly_cpi_line_plot_data, x='year_month', y='avg_cpi', legend_label='CPI', y_range_name='CPI', line_width=2, color="green") monthly_sales_hover = HoverTool( tooltips=[ ('Avg Sales', '$' + '@monthly_avg_sales{0.00}'), ('Avg CPI', '@avg_cpi')], mode='vline') monthly_sales_figure.add_tools(monthly_sales_hover) monthly_sales_figure.xgrid.grid_line_color = None monthly_sales_line_plot_data_source = monthly_sales_line_plot.data_source monthly_cpi_line_plot_data_source = monthly_cpi_line_plot.data_source # ------------------------------------------ Monthly Avg Plot Ends Here ------------------------------------------- # ----------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------- # ---------------------------------------- Quarterly Avg Plot Starts Here ----------------------------------------- def get_quarterly_avg_sales_data(store_dept_weekly_dataset): store_dept_avg_quarterly_dataset = store_dept_weekly_dataset store_dept_avg_quarterly_dataset['Date'] = pd.to_datetime( store_dept_avg_quarterly_dataset['Date']) store_dept_avg_quarterly_dataset.index = pd.DatetimeIndex( store_dept_avg_quarterly_dataset['Date']) store_dept_avg_quarterly_dataset = store_dept_avg_quarterly_dataset.groupby( pd.Grouper(freq="Q")).agg( Store=('Store', 'first'), Dept=('Dept', 'first'), Avg_Quarterly_Sales=('Weekly_Sales', 'mean'), Type=('Type', 'first'), Size=('Size', 'first'), Avg_Quarterly_CPI=('CPI', 'mean') ) store_dept_avg_quarterly_dataset.reset_index(level=0, inplace=True) store_dept_avg_quarterly_dataset['Date'] = store_dept_avg_quarterly_dataset[ 'Date'].dt.strftime('%Y-%m') def date_formatter(single_row, date_type): year, month = single_row['Date'].split('-') if date_type == 'y': return year if date_type == 'm': return int(month) if date_type == 'q': return "Q" + str(math.ceil(int(month) / 3.0)) store_dept_avg_quarterly_dataset['year_quarter'] = store_dept_avg_quarterly_dataset.apply( lambda row: (date_formatter(row, 'y'), date_formatter(row, 'q')), axis=1) return store_dept_avg_quarterly_dataset def get_quarterly_sales_line_plot_data(store_dept_avg_quarterly_dataset): return dict( year_quarter=store_dept_avg_quarterly_dataset.year_quarter.tolist(), quarterly_avg_sales=store_dept_avg_quarterly_dataset.Avg_Quarterly_Sales.tolist(), quarterly_avg_cpi=store_dept_avg_quarterly_dataset.Avg_Quarterly_CPI.tolist() ) selected_store_dept_avg_quarterly_dataset = get_quarterly_avg_sales_data(selected_store_dept_weekly_dataset) quarterly_sales_line_plot_data = ColumnDataSource( data=get_quarterly_sales_line_plot_data(selected_store_dept_avg_quarterly_dataset) ) quarterly_cpi_line_plot_data = ColumnDataSource(data=get_cpi_line_plot_data_dict(quarterly_sales_line_plot_data)) quarterly_sales_figure = figure( title="Quarterly Avg Sales", x_range=FactorRange(*selected_store_dept_avg_quarterly_dataset.year_quarter.tolist()), plot_width=1400, plot_height=300, tools="box_zoom,reset") quarterly_sales_figure.yaxis.axis_label = 'Sales in USD' quarterly_sales_figure.extra_y_ranges['CPI'] = Range1d(start=0, end=300) quarterly_sales_figure.add_layout(LinearAxis(y_range_name='CPI', axis_label='CPI'), 'right') quarterly_sales_line_plot = quarterly_sales_figure.line( source=quarterly_sales_line_plot_data, x='year_quarter', y='quarterly_avg_sales', legend_label='Sales', line_width=2, color="red") quarterly_cpi_line_plot = quarterly_sales_figure.line( source=quarterly_cpi_line_plot_data, x='year_quarter', y='quarterly_avg_cpi', legend_label='CPI', y_range_name='CPI', line_width=2, color="green") quarterly_sales_hover = HoverTool( tooltips=[ ('Avg Sales', '$' + '@quarterly_avg_sales{0.00}'), ('Avg CPI', '@quarterly_avg_cpi')], mode='vline') quarterly_sales_figure.add_tools(quarterly_sales_hover) quarterly_sales_figure.xgrid.grid_line_color = None quarterly_sales_line_plot_data_source = quarterly_sales_line_plot.data_source quarterly_cpi_line_plot_data_source = quarterly_cpi_line_plot.data_source # ----------------------------------------- Quarterly Avg Plot Ends Here ------------------------------------------ # ----------------------------------------------------------------------------------------------------------------- hide_spinner(div_spinner) def clear_cpi_plot_data_sources(): weekly_cpi_line_plot_data_source.data = {k: [] for k in weekly_cpi_line_plot_data_source.data} monthly_cpi_line_plot_data_source.data = {k: [] for k in monthly_cpi_line_plot_data_source.data} quarterly_cpi_line_plot_data_source.data = {k: [] for k in quarterly_cpi_line_plot_data_source.data} # ----------------------------------------------------------------------------------------------------------------- # ------------------------------------------ CPI Plots Default Starts here ---------------------------------------- # Clear CPI plot if cpi toggle button is set to off by default if cpi_toggle_button.active == 0: clear_cpi_plot_data_sources() # -------------------------------------------- CPI Plots Default Ends here ---------------------------------------- # ----------------------------------------------------------------------------------------------------------------- def clear_all_plot_data_sources(): weekly_sales_line_plot_data_source.data = {k: [] for k in weekly_sales_line_plot_data_source.data} weekly_sales_circle_plot_data_source.data = {k: [] for k in weekly_sales_circle_plot_data_source.data} monthly_sales_line_plot_data_source.data = {k: [] for k in monthly_sales_line_plot_data_source.data} quarterly_sales_line_plot_data_source.data = {k: [] for k in quarterly_sales_line_plot_data_source.data} clear_cpi_plot_data_sources() def update_cpi_plots(): weekly_cpi_line_plot_data_source.data = dict(weekly_sales_line_plot_data.data) monthly_cpi_line_plot_data_source.data = dict(monthly_sales_line_plot_data.data) quarterly_cpi_line_plot_data_source.data = dict(quarterly_sales_line_plot_data.data) def update_all_plots(attr, old, new): show_spinner(div_spinner) global selected_store_id, selected_dept_id old_store_id = selected_store_id old_dept_id = selected_dept_id updated_store_id = store_id_selector.value updated_dept_id = dept_id_selector.value # ------------------------------------------------------------------------------------------------------------- # ----------------------------------------- Weekly Plot Update Starts Here ------------------------------------ new_selected_store_dept_weekly_dataset, new_selected_store_dept_weekly_sales_on_holiday_dataset = \ get_weekly_sales_data(updated_store_id, updated_dept_id) if new_selected_store_dept_weekly_dataset is None: hide_spinner(div_spinner, "Sorry! Data not available") clear_all_plot_data_sources() return updated_weekly_sales_line_plot_data_dict = \ get_weekly_sales_line_plot_data_dict(new_selected_store_dept_weekly_dataset) updated_weekly_circle_plot_data_dict = \ get_weekly_sales_circle_plot_data_dict(new_selected_store_dept_weekly_sales_on_holiday_dataset) weekly_sales_figure.x_range.factors = new_selected_store_dept_weekly_dataset.year_month_week.tolist() weekly_sales_line_plot_data_source.data = updated_weekly_sales_line_plot_data_dict weekly_sales_circle_plot_data_source.data = updated_weekly_circle_plot_data_dict # ------------------------------------------ Weekly Plot Update Ends Here ------------------------------------- # ------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------------------------------------- # ---------------------------------------- Monthly Avg Plot Update Starts Here -------------------------------- new_selected_store_dept_avg_monthly_dataset = \ get_monthly_avg_sales_data(new_selected_store_dept_weekly_dataset) updated_monthly_sales_line_plot_data_dict = \ get_monthly_sales_line_plot_data_dict(new_selected_store_dept_avg_monthly_dataset) monthly_sales_figure.x_range.factors = new_selected_store_dept_avg_monthly_dataset.year_month.tolist() monthly_sales_line_plot_data_source.data = updated_monthly_sales_line_plot_data_dict # ----------------------------------------- Monthly Avg Plot Update Ends Here --------------------------------- # ------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------------------------------------- # --------------------------------------- Quarterly Avg Plot Update Starts Here ------------------------------- new_selected_store_dept_avg_quarterly_dataset = \ get_quarterly_avg_sales_data(new_selected_store_dept_weekly_dataset) updated_quarterly_sales_line_plot_data_dict = \ get_quarterly_sales_line_plot_data(new_selected_store_dept_avg_quarterly_dataset) quarterly_sales_figure.x_range.factors = new_selected_store_dept_avg_quarterly_dataset.year_quarter.tolist() quarterly_sales_line_plot_data_source.data = updated_quarterly_sales_line_plot_data_dict # ---------------------------------------- Quarterly Avg Plot Update Ends Here -------------------------------- # ------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------------------------------------- # ------------------------------------------ CPI Plots Update Starts here ------------------------------------- update_cpi_plots() # Clear CPI plot if cpi toggle button is set to off if cpi_toggle_button.active == 0: clear_cpi_plot_data_sources() # ------------------------------------------- CPI Plots Update Ends here -------------------------------------- # ------------------------------------------------------------------------------------------------------------- selected_store_id = updated_store_id selected_dept_id = updated_dept_id hide_spinner(div_spinner) def toggle_cpi_plot(attr, old, new): show_spinner(div_spinner) if cpi_toggle_button.active == 0: clear_cpi_plot_data_sources() if cpi_toggle_button.active == 1: weekly_cpi_line_plot_data_source.data = get_cpi_line_plot_data_dict(weekly_sales_line_plot_data) monthly_cpi_line_plot_data_source.data = get_cpi_line_plot_data_dict(monthly_sales_line_plot_data) quarterly_cpi_line_plot_data_source.data = get_cpi_line_plot_data_dict(quarterly_sales_line_plot_data) hide_spinner(div_spinner) store_id_selector.on_change("value", update_all_plots) dept_id_selector.on_change("value", update_all_plots) cpi_toggle_button.on_change('active', toggle_cpi_plot) layout = column(row(div_heading, div_spinner), row( store_id_selector, dept_id_selector, column(div_toggle_button, cpi_toggle_button) ), weekly_sales_figure, monthly_sales_figure, quarterly_sales_figure) tab = Panel(child=layout, title='Weekly, Monthly, & Quarterly Sales Timeline') return tab
def bkapp(doc): ### Functions ### # functions for user dialogs def open_file(ftype): root = Tk() root.withdraw() file = askopenfilename(filetypes=ftype, title='Open File', initialdir=os.getcwd()) root.destroy() return file def choose_directory(): root = Tk() root.withdraw() out_dir = askdirectory() root.destroy() return out_dir def write_output_directory(output_dir): root = Tk() root.withdraw() makeDir = askquestion('Make Directory','Output directory not set. Make directory: ' +output_dir+'? If not, you\'ll be prompted to change directories.',icon = 'warning') root.destroy() return makeDir def overwrite_file(): root = Tk() root.withdraw() overwrite = askquestion('Overwrite File','File already exits. Do you want to overwrite?',icon = 'warning') root.destroy() return overwrite def update_filename(): filetype = [("Video files", "*.mp4")] fname = open_file(filetype) if fname: #print('Successfully loaded file: '+fname) load_data(filename=fname) def change_directory(): out_dir = choose_directory() if out_dir: source.data["output_dir"] = [out_dir] outDir.text = out_dir return out_dir # load data from file def load_data(filename): vidcap = cv2.VideoCapture(filename) success,frame = vidcap.read() img_tmp,_,__ = cv2.split(frame) h,w = np.shape(img_tmp) img = np.flipud(img_tmp) radio_button_gp.active = 0 fname = os.path.split(filename)[1] input_dir = os.path.split(filename)[0] if source.data['output_dir'][0]=='': output_dir = os.path.join(input_dir,fname.split('.')[0]) else: output_dir = source.data['output_dir'][0] if not os.path.isdir(output_dir): makeDir = write_output_directory(output_dir) if makeDir=='yes': os.mkdir(output_dir) else: output_dir = change_directory() if output_dir: source.data = dict(image_orig=[img], image=[img], bin_img=[0], x=[0], y=[0], dw=[w], dh=[h], num_contours=[0], roi_coords=[0], img_name=[fname], input_dir=[input_dir], output_dir=[output_dir]) curr_img = p.select_one({'name':'image'}) if curr_img: p.renderers.remove(curr_img) p.image(source=source, image='image', x='x', y='y', dw='dw', dh='dh', color_mapper=cmap,level='image',name='image') p.plot_height=int(h/2) p.plot_width=int(w/2) #p.add_tools(HoverTool(tooltips=IMG_TOOLTIPS)) inFile.text = fname outDir.text = output_dir else: print('Cancelled. To continue please set output directory.{:<100}'.format(' '),end="\r") # resetting sources for new data or new filters/contours def remove_plot(): source.data["num_contours"]=[0] contours_found.text = 'Droplets Detected: 0' source_contours.data = dict(xs=[], ys=[]) source_label.data = dict(x=[], y=[], label=[]) # apply threshold filter and display binary image def apply_filter(): if source.data['input_dir'][0] == '': print('No image loaded! Load image first.{:<100}'.format(' '),end="\r") else: img = np.squeeze(source.data['image_orig']) # remove contours if present if source.data["num_contours"]!=[0]: remove_plot() if radio_button_gp.active == 1: thresh = filters.threshold_otsu(img) binary = img > thresh bin_img = binary*255 source.data["bin_img"] = [bin_img] elif radio_button_gp.active == 2: thresh = filters.threshold_isodata(img) binary = img > thresh bin_img = binary*255 source.data["bin_img"] = [bin_img] elif radio_button_gp.active == 3: thresh = filters.threshold_mean(img) binary = img > thresh bin_img = binary*255 source.data["bin_img"] = [bin_img] elif radio_button_gp.active == 4: thresh = filters.threshold_li(img) binary = img > thresh bin_img = binary*255 source.data["bin_img"] = [bin_img] elif radio_button_gp.active == 5: thresh = filters.threshold_yen(img) binary = img > thresh bin_img = binary*255 source.data["bin_img"] = [bin_img] elif radio_button_gp.active == 6: off = offset_spinner.value block_size = block_spinner.value thresh = filters.threshold_local(img,block_size,offset=off) binary = img > thresh bin_img = binary*255 source.data["bin_img"] = [bin_img] else: bin_img = img source.data['image'] = [bin_img] # image functions for adjusting the binary image def close_img(): if source.data["num_contours"]!=[0]: remove_plot() if radio_button_gp.active == 0: print("Please Select Filter for Threshold{:<100}".format(' '),end="\r") else: source.data["image"] = source.data["bin_img"] img = np.squeeze(source.data['bin_img']) closed_img = binary_closing(255-img)*255 source.data['image'] = [255-closed_img] source.data['bin_img'] = [255-closed_img] def dilate_img(): if source.data["num_contours"]!=[0]: remove_plot() if radio_button_gp.active == 0: print("Please Select Filter for Threshold{:<100}".format(' '),end="\r") else: img = np.squeeze(source.data['bin_img']) dilated_img = binary_dilation(255-img)*255 source.data['image'] = [255-dilated_img] source.data['bin_img'] = [255-dilated_img] def erode_img(): if source.data["num_contours"]!=[0]: remove_plot() if radio_button_gp.active == 0: print("Please Select Filter for Threshold{:<100}".format(' '),end="\r") else: img = np.squeeze(source.data['bin_img']) eroded_img = binary_erosion(255-img)*255 source.data['image'] = [255-eroded_img] source.data['bin_img'] = [255-eroded_img] # the function for identifying closed contours in the image def find_contours(level=0.8): min_drop_size = contour_rng_slider.value[0] max_drop_size = contour_rng_slider.value[1] min_dim = 20 max_dim = 200 if radio_button_gp.active == 0: print("Please Select Filter for Threshold{:<100}".format(' '),end="\r") elif source.data['input_dir'][0] == '': print('No image loaded! Load image first.{:<100}'.format(' '),end="\r") else: img = np.squeeze(source.data['bin_img']) h,w = np.shape(img) contours = measure.find_contours(img, level) length_cnt_x = [cnt[:,1] for cnt in contours if np.shape(cnt)[0] < max_drop_size and np.shape(cnt)[0] > min_drop_size] length_cnt_y = [cnt[:,0] for cnt in contours if np.shape(cnt)[0] < max_drop_size and np.shape(cnt)[0] > min_drop_size] matched_cnt_x = [] matched_cnt_y = [] roi_coords = [] label_text = [] label_y = np.array([]) count=0 for i in range(len(length_cnt_x)): cnt_x = length_cnt_x[i] cnt_y = length_cnt_y[i] width = np.max(cnt_x)-np.min(cnt_x) height = np.max(cnt_y)-np.min(cnt_y) if width>min_dim and width<max_dim and height>min_dim and height<max_dim: matched_cnt_x.append(cnt_x) matched_cnt_y.append(cnt_y) roi_coords.append([round(width),round(height),round(np.min(cnt_x)),round(h-np.max(cnt_y))]) label_text.append(str(int(count)+1)) label_y = np.append(label_y,np.max(cnt_y)) count+=1 curr_contours = p.select_one({'name':'overlay'}) if curr_contours: p.renderers.remove(curr_contours) #if source.data["num_contours"]==[0]: #remove_plot() #p.image(source=source, image='image_orig', x=0, y=0, dw=w, dh=h, color_mapper=cmap, name='overlay',level='underlay') source.data["image"] = source.data["image_orig"] source.data["num_contours"] = [count] #source.data["cnt_x"] = [matched_cnt_x] #source.data["cnt_y"] = [matched_cnt_y] source.data["roi_coords"] = [roi_coords] source_contours.data = dict(xs=matched_cnt_x, ys=matched_cnt_y) p.multi_line(xs='xs',ys='ys',source=source_contours, color=(255,127,14),line_width=2, name="contours",level='glyph') if len(np.array(roi_coords).shape)<2: if len(np.array(roi_coords)) <4: print('No contours found. Try adjusting parameters or filter for thresholding.{:<100}'.format(' '),end="\r") source_label.data = dict(x=[],y=[],label=[]) else: source_label.data = dict(x=np.array(roi_coords)[2], y=label_y, label=label_text) else: source_label.data = dict(x=np.array(roi_coords)[:,2], y=label_y, label=label_text) contours_found.text = 'Droplets Detected: '+str(len(matched_cnt_x)) # write the contours and parameters to files def export_ROIs(): if source.data["num_contours"]==[0]: print("No Contours Found! Find contours first.{:<100}".format(' '),end="\r") else: hdr = 'threshold filter,contour min,contour max' thresh_filter = radio_button_gp.active cnt_min = contour_rng_slider.value[0] cnt_max = contour_rng_slider.value[1] params = [thresh_filter,cnt_min,cnt_max] if radio_button_gp.active == 6: off = offset_spinner.value block_size = block_spinner.value hdr = hdr + ',local offset,local block size' params.append(off,block_size) params_fname = 'ContourParams.csv' params_out = os.path.join(source.data['output_dir'][0],params_fname) overwrite = 'no' if os.path.exists(params_out): overwrite = overwrite_file() if overwrite == 'yes' or not os.path.exists(params_out): np.savetxt(params_out,np.array([params]),delimiter=',',header=hdr,comments='') roi_coords = np.array(source.data["roi_coords"][0]) out_fname = 'ROI_coords.csv' out_fullpath = os.path.join(source.data['output_dir'][0],out_fname) if overwrite == 'yes' or not os.path.exists(out_fullpath): hdr = 'width,height,x,y' np.savetxt(out_fullpath,roi_coords,delimiter=',',header=hdr,comments='') print('Successfully saved ROIs coordinates as: '+out_fullpath,end='\r') source.data['roi_coords'] = [roi_coords] # function for loading previously made files or error handling for going out of order def check_ROI_files(): coords_file = os.path.join(source.data["output_dir"][0],'ROI_coords.csv') n_cnt_curr = source.data["num_contours"][0] roi_coords_curr = source.data["roi_coords"][0] if os.path.exists(coords_file): df_tmp=pd.read_csv(coords_file, sep=',') roi_coords = np.array(df_tmp.values) n_cnt = len(roi_coords) if n_cnt_curr != n_cnt or not np.array_equal(roi_coords_curr,roi_coords): print('Current ROIs are different from saved ROI file! ROIs from saved file will be used instead and plot updated.',end="\r") source.data["num_contours"] = [n_cnt] source.data["roi_coords"] = [roi_coords] params_file = os.path.join(source.data['output_dir'][0],'ContourParams.csv') params_df = pd.read_csv(params_file) thresh_ind = params_df["threshold filter"].values[0] radio_button_gp.active = int(thresh_ind) if thresh_ind == 6: offset_spinner.value = int(params_df["local offset"].values[0]) block_spinner.value = int(params_df["local block size"].values[0]) contour_rng_slider.value = tuple([int(params_df["contour min"].values[0]),int(params_df["contour max"].values[0])]) find_contours() else: print("ROI files not found! Check save directory or export ROIs.{:<100}".format(' '),end="\r") # use FFMPEG to crop out regions from original mp4 and save to file def create_ROI_movies(): if source.data['input_dir'][0] == '': print('No image loaded! Load image first.{:<100}'.format(' '),end="\r") else: check_ROI_files() side = 100 # for square ROIs, replace first two crop parameters with side & uncomment padding = 20 roi_coords_file = os.path.join(source.data['output_dir'][0],'ROI_coords.csv') if source.data["num_contours"]==[0]: print("No contours found! Find contours first.{:<100}".format(' '),end="\r") elif not os.path.exists(roi_coords_file): print("ROI file does not exist! Check save directory or export ROIs.{:<100}".format(' '),end="\r") else: print('Creating Movies...{:<100}'.format(' '),end="\r") pbar = tqdm(total=source.data["num_contours"][0]) for i in range(source.data["num_contours"][0]): roi_coords = np.array(source.data["roi_coords"][0]) inPath = os.path.join(source.data['input_dir'][0],source.data['img_name'][0]) #out_fname = source.data['filename'][0].split('.')[0] +'_ROI'+str(i+1)+'.mp4' out_fname = 'ROI'+str(i+1)+'.mp4' outPath = os.path.join(source.data['output_dir'][0],out_fname) #command = f"ffmpeg -i \'{(inPath)}\' -vf \"crop={(roi_coords[i,0]+padding*2)}:{(roi_coords[i,1]+padding*2)}:{(roi_coords[i,2]-padding)}:{(roi_coords[i,3]+padding)}\" -y \'{(outPath)}\'" command = f"ffmpeg -i \'{(inPath)}\' -vf \"crop={side}:{side}:{(roi_coords[i,2]-padding)}:{(roi_coords[i,3]-padding)}\" -y \'{(outPath)}\'" overwrite = 'no' if os.path.exists(outPath): overwrite = overwrite_file() if overwrite == 'yes' or not os.path.exists(outPath): saved = subprocess.check_call(command,shell=True) if saved != 0: print('An error occurred while creating movies! Check terminal window.{:<100}'.format(' '),end="\r") pbar.update() # change the display range on images from slider values def update_image(): cmap.low = display_range_slider.value[0] cmap.high = display_range_slider.value[1] # create statistics files for each mp4 region specific file def process_ROIs(): if source.data['input_dir'][0] == '': print('No image loaded! Load image first.{:<100}'.format(' '),end="\r") else: check_ROI_files() hdr = 'roi,time,area,mean,variance,min,max,median,skewness,kurtosis,rawDensity,COMx,COMy' cols = hdr.split(',') all_stats = np.zeros((0,13)) n_cnt = source.data["num_contours"][0] if n_cnt == 0: print("No contours found! Find contours first.{:<100}".format(' '),end="\r") for i in range(n_cnt): #in_fname = source.data['filename'][0].split('.')[0] +'_ROI'+str(i+1)+'.mp4' in_fname = 'ROI'+str(i+1)+'.mp4' inPath = os.path.join(source.data['output_dir'][0],in_fname) #out_fname = source.data['filename'][0].split('.')[0] +'_ROI'+str(i+1)+'_stats.csv' out_fname = 'stats_ROI'+str(i+1)+'.csv' outPath = os.path.join(source.data['output_dir'][0],out_fname) if not os.path.exists(inPath): print('ROI movie not found! Create ROI movie first.{:<100}'.format(' '),end="\r") break vidcap = cv2.VideoCapture(inPath) last_frame = int(vidcap.get(cv2.CAP_PROP_FRAME_COUNT)) if i==0: pbar = tqdm(total=last_frame*n_cnt) success,frame = vidcap.read() img_tmp,_,__ = cv2.split(frame) h,w = np.shape(img_tmp) img = np.zeros((last_frame,h,w)) img_stats = np.zeros((last_frame,13)) stats = describe(img_tmp,axis=None) median = np.median(img_tmp) density = np.sum(img_tmp) cx, cy = center_of_mass(img_tmp) img_stats[0,0:13] = [i,0,stats.nobs,stats.mean,stats.variance, stats.minmax[0],stats.minmax[1],median,stats.skewness, stats.kurtosis,density,cx,cy] img[0,:,:] = np.flipud(img_tmp) pbar.update() overwrite = 'no' if os.path.exists(outPath): overwrite = overwrite_file() if overwrite=='no': pbar.update(last_frame-1) if overwrite == 'yes' or not os.path.exists(outPath): for j in range(1,last_frame): vidcap.set(1, j) success,frame = vidcap.read() img_tmp,_,__ = cv2.split(frame) stats = describe(img_tmp,axis=None) t = j*5/60 density = np.sum(img_tmp) cx, cy = center_of_mass(img_tmp) median = np.median(img_tmp) img_stats[j,0:13] = [i,t,stats.nobs,stats.mean,stats.variance, stats.minmax[0],stats.minmax[1],median,stats.skewness, stats.kurtosis,density,cx,cy] img[j,:,:] = np.flipud(img_tmp) pbar.update(1) all_stats = np.append(all_stats,img_stats,axis=0) np.savetxt(outPath,img_stats,delimiter=',',header=hdr,comments='') if i==(n_cnt-1): df = pd.DataFrame(all_stats,columns=cols) group = df.groupby('roi') for i in range(len(group)): sources_stats[i] = ColumnDataSource(group.get_group(i)) # load statistics CSVs and first ROI mp4 files and display in plots def load_ROI_files(): if source.data['input_dir'][0] == '': print('No image loaded! Load image first.{:<100}'.format(' '),end="\r") else: check_ROI_files() n_cnt = source.data["num_contours"][0] basepath = os.path.join(source.data["output_dir"][0],'stats') all_files = [basepath+'_ROI'+str(i+1)+'.csv' for i in range(n_cnt)] files_exist = [os.path.exists(f) for f in all_files] if all(files_exist) and n_cnt != 0: df = pd.concat((pd.read_csv(f) for f in all_files), ignore_index=True) group = df.groupby('roi') OPTIONS = [] LABELS = [] pbar = tqdm(total=len(stats)*len(group)) j=0 colors_ordered = list(Category20[20]) idx_reorder = np.append(np.linspace(0,18,10),np.linspace(1,19,10)) idx = idx_reorder.astype(int) colors = [colors_ordered[i] for i in idx] for roi, df_roi in group: sources_stats[roi] = ColumnDataSource(df_roi) OPTIONS.append([str(int(roi)+1),'ROI '+(str(int(roi)+1))]) LABELS.append('ROI '+str(int(roi)+1)) color = colors[j] j+=1 if j>=20: j=0 for i in range(3,len(df.columns)): name = 'ROI '+str(int(roi)+1) plot_check = p_stats[i-3].select_one({'name':name}) if not plot_check: p_stats[i-3].line(x='time',y=str(df.columns[i]),source=sources_stats[roi], name=name,visible=False,line_color=color) p_stats[i-3].xaxis.axis_label = "Time [h]" p_stats[i-3].yaxis.axis_label = str(df.columns[i]) p_stats[i-3].add_tools(HoverTool(tooltips=TOOLTIPS)) p_stats[i-3].toolbar_location = "left" pbar.update(1) ROI_multi_select.options = OPTIONS ROI_multi_select.value = ["1"] ROI_movie_radio_group.labels = LABELS ROI_movie_radio_group.active = 0 else: print('Not enough files! Check save directory or calculate new stats.{:<100}'.format(' '),end="\r") # show/hide curves from selected/deselected labels for ROIs in statistics plots def update_ROI_plots(): n_cnt = source.data["num_contours"][0] pbar = tqdm(total=len(stats)*n_cnt) for j in range(n_cnt): for i in range(len(stats)): name = 'ROI '+str(int(j)+1) glyph = p_stats[i].select_one({'name': name}) if str(j+1) in ROI_multi_select.value: glyph.visible = True else: glyph.visible = False pbar.update(1) # load and display the selected ROI's mp4 def load_ROI_movie(): idx = ROI_movie_radio_group.active in_fname = 'ROI'+str(idx+1)+'.mp4' inPath = os.path.join(source.data['output_dir'][0],in_fname) if not os.path.exists(inPath): print('ROI movie not found! Check save directory or create ROI movie.',end="\r") else: old_plot = p_ROI.select_one({'name': sourceROI.data['img_name'][0]}) if old_plot: p_ROI.renderers.remove(old_plot) vidcap = cv2.VideoCapture(inPath) last_frame = int(vidcap.get(cv2.CAP_PROP_FRAME_COUNT)) ROI_movie_slider.end = (last_frame-1)*5/60 ROI_movie_slider.value = 0 vidcap.set(1, 0) success,frame = vidcap.read() img_tmp,_,__ = cv2.split(frame) h,w = np.shape(img_tmp) img = np.flipud(img_tmp) name = 'ROI'+str(idx+1) sourceROI.data = dict(image=[img],x=[0], y=[0], dw=[w], dh=[h], img_name=[name]) p_ROI.image(source=sourceROI, image='image', x='x', y='y', dw='dw', dh='dh', color_mapper=cmap, name='img_name') # change the displayed frame from slider movement def update_ROI_movie(): frame_idx = round(ROI_movie_slider.value*60/5) in_fname = sourceROI.data['img_name'][0]+'.mp4' inPath = os.path.join(source.data['output_dir'][0],in_fname) vidcap = cv2.VideoCapture(inPath) vidcap.set(1, frame_idx) success,frame = vidcap.read() img_tmp,_,__ = cv2.split(frame) img = np.flipud(img_tmp) sourceROI.data['image'] = [img] # the following 2 functions are used to animate the mp4 def update_ROI_slider(): time = ROI_movie_slider.value + 5/60 end = ROI_movie_slider.end if time > end: animate_ROI_movie() else: ROI_movie_slider.value = time return callback_id def animate_ROI_movie(): global callback_id if ROI_movie_play_button.label == '► Play': ROI_movie_play_button.label = '❚❚ Pause' callback_id = curdoc().add_periodic_callback(update_ROI_slider, 10) else: ROI_movie_play_button.label = '► Play' curdoc().remove_periodic_callback(callback_id) return callback_id ### Application Content ### # main plot for segmentation and contour finding cmap = LinearColorMapper(palette="Greys256", low=0, high=255) TOOLS = "pan,wheel_zoom,box_zoom,reset,save,box_select,lasso_select" IMG_TOOLTIPS = [('name', "@img_name"),("x", "$x"),("y", "$y"),("value", "@image")] source = ColumnDataSource(data=dict(image=[0],bin_img=[0],image_orig=[0], x=[0], y=[0], dw=[0], dh=[0], num_contours=[0], roi_coords=[0], input_dir=[''],output_dir=[''],img_name=[''])) source_label = ColumnDataSource(data=dict(x=[0], y=[0], label=[''])) source_contours = ColumnDataSource(data=dict(xs=[0], ys=[0])) roi_labels = LabelSet(x='x', y='y', text='label',source=source_label, level='annotation',text_color='white',text_font_size='12pt') # create a new plot and add a renderer p = figure(tools=TOOLS, toolbar_location=("right")) p.add_layout(roi_labels) p.x_range.range_padding = p.y_range.range_padding = 0 # turn off gridlines p.xgrid.grid_line_color = None p.ygrid.grid_line_color = None p.axis.visible = False # ROI plots sourceROI = ColumnDataSource(data=dict(image=[0], x=[0], y=[0], dw=[0], dh=[0], img_name=[0])) sources_stats = {} TOOLTIPS = [('name','$name'),('time', '@time'),('stat', "$y")] stats = np.array(['mean','var','min','max','median','skew','kurt','rawDensity','COMx','COMy']) p_stats = [] tabs = [] for i in range(len(stats)): p_stats.append(figure(tools=TOOLS, plot_height=300, plot_width=600)) p_stats[i].x_range.range_padding = p_stats[i].y_range.range_padding = 0 tabs.append(Panel(child=p_stats[i], title=stats[i])) # create a new plot and add a renderer p_ROI = figure(tools=TOOLS, toolbar_location=("right"), plot_height=300, plot_width=300) p_ROI.x_range.range_padding = p_ROI.y_range.range_padding = 0 # turn off gridlines p_ROI.xgrid.grid_line_color = p_ROI.ygrid.grid_line_color = None p_ROI.axis.visible = False # Widgets - Buttons, Sliders, Text, Etc. intro = Div(text="""<h2>Droplet Recognition and Analysis with Bokeh</h2> This application is designed to help segment a grayscale image into regions of interest (ROIs) and perform analysis on those regions.<br> <h4>How to Use This Application:</h4> <ol> <li>Load in a grayscale mp4 file and choose a save directory.</li> <li>Apply various filters for thresholding. Use <b>Close</b>, <b>Dilate</b> and <b>Erode</b> buttons to adjust each binary image further.</li> <li>Use <b>Find Contours</b> button to search the image for closed shape. The <b>Contour Size Range</b> slider will change size of the perimeter to be identified. You can apply new thresholds and repeat until satisfied with the region selection. Total regions detected is displayed next to the button.</li> <li>When satisfied, use <b>Export ROIs</b> to write ROI locations and contour finding parameters to file.</li> <li><b>Create ROI Movies</b> to write mp4s of the selected regions.</li> <li>Use <b>Calculate ROI Stats</b> to perform calculations on the newly created mp4 files.</li> <li>Finally, use <b>Load ROI Files</b> to load in the data that you just created and view the plots. The statistics plots can be overlaid by selecting multiple labels. Individual ROI mp4s can be animated or you can use the slider to move through the frames.</li> </ol> Note: messages and progress bars are displayed below the GUI.""", style={'font-size':'10pt'},width=1000) file_button = Button(label="Choose File",button_type="primary") file_button.on_click(update_filename) inFile = PreText(text='Input File:\n'+source.data["img_name"][0], background=(255,255,255,0.5), width=500) filter_LABELS = ["Original","OTSU", "Isodata", "Mean", "Li","Yen","Local"] radio_button_gp = RadioButtonGroup(labels=filter_LABELS, active=0, width=600) radio_button_gp.on_change('active', lambda attr, old, new: apply_filter()) offset_spinner = Spinner(low=0, high=500, value=1, step=1, width=100, title="Local: Offset", background=(255,255,255,0.5)) offset_spinner.on_change('value', lambda attr, old, new: apply_filter()) block_spinner = Spinner(low=1, high=101, value=25, step=2, width=100, title="Local: Block Size", background=(255,255,255,0.5)) block_spinner.on_change('value', lambda attr, old, new: apply_filter()) closing_button = Button(label="Close",button_type="default", width=100) closing_button.on_click(close_img) dilation_button = Button(label="Dilate",button_type="default", width=100) dilation_button.on_click(dilate_img) erosion_button = Button(label="Erode",button_type="default", width=100) erosion_button.on_click(erode_img) contour_rng_slider = RangeSlider(start=10, end=500, value=(200,350), step=1, width=300, title="Contour Size Range", background=(255,255,255,0.5), bar_color='gray') contour_button = Button(label="Find Contours", button_type="success") contour_button.on_click(find_contours) contours_found = PreText(text='Droplets Detected: '+str(source.data["num_contours"][0]), background=(255,255,255,0.5)) exportROIs_button = Button(label="Export ROIs", button_type="success", width=200) exportROIs_button.on_click(export_ROIs) changeDir_button = Button(label="Change Directory",button_type="primary", width=150) changeDir_button.on_click(change_directory) outDir = PreText(text='Save Directory:\n'+source.data["output_dir"][0], background=(255,255,255,0.5), width=500) create_ROIs_button = Button(label="Create ROI Movies",button_type="success", width=200) create_ROIs_button.on_click(create_ROI_movies) process_ROIs_button = Button(label="Calculate ROI Stats",button_type="success") process_ROIs_button.on_click(process_ROIs) display_rng_text = figure(title="Display Range", title_location="left", width=40, height=300, toolbar_location=None, min_border=0, outline_line_color=None) display_rng_text.title.align="center" display_rng_text.title.text_font_size = '10pt' display_rng_text.x_range.range_padding = display_rng_text.y_range.range_padding = 0 display_range_slider = RangeSlider(start=0, end=255, value=(0,255), step=1, orientation='vertical', direction='rtl', bar_color='gray', width=40, height=300, tooltips=True) display_range_slider.on_change('value', lambda attr, old, new: update_image()) load_ROIfiles_button = Button(label="Load ROI Files",button_type="primary") load_ROIfiles_button.on_click(load_ROI_files) ROI_multi_select = MultiSelect(value=[], width=100, height=300) ROI_multi_select.on_change('value', lambda attr, old, new: update_ROI_plots()) ROI_movie_radio_group = RadioGroup(labels=[],width=60) ROI_movie_radio_group.on_change('active', lambda attr, old, new: load_ROI_movie()) ROI_movie_slider = Slider(start=0,end=100,value=0,step=5/60,title="Time [h]", width=280) ROI_movie_slider.on_change('value', lambda attr, old, new: update_ROI_movie()) callback_id = None ROI_movie_play_button = Button(label='► Play',width=50) ROI_movie_play_button.on_click(animate_ROI_movie) # initialize some data without having to choose file # fname = os.path.join(os.getcwd(),'data','Droplets.mp4') # load_data(filename=fname) ### Layout & Initialize application ### ROI_layout = layout([ [ROI_movie_radio_group, p_ROI], [ROI_movie_slider,ROI_movie_play_button] ]) app = layout(children=[ [intro], [file_button,inFile], [radio_button_gp, offset_spinner, block_spinner], [closing_button, dilation_button, erosion_button], [contour_rng_slider, contour_button, contours_found], [exportROIs_button, outDir, changeDir_button], [create_ROIs_button, process_ROIs_button], [display_rng_text, display_range_slider, p], [load_ROIfiles_button], [ROI_layout, ROI_multi_select, Tabs(tabs=tabs)] ]) doc.add_root(app)
all_waves=all_waves, local_field=local_field, far_field=far_field, local_P=local_P, test=args.test)) rangeslider.on_change( 'value', partial(src.change_range, rangeslider=rangeslider, leads=leads)) waveselector.on_change( 'active', partial(src.wave_change, args=args, all_waves=all_waves, file_selector=file_selector, local_field=local_field, far_field=far_field, local_P=local_P, previous_local_P=previous_local_P, boxes_local_P=boxes_local_P, sources=sources, current_keys=current_keys, previous_local_field=previous_local_field, previous_far_field=previous_far_field, boxes_local_field=boxes_local_field, boxes_far_field=boxes_far_field, textbox=textbox)) delineatebutton.on_click( partial(src.predict, args=args, span_Pon=span_Pon, span_Poff=span_Poff, span_QRSon=span_QRSon, span_QRSoff=span_QRSoff,
def build_lockdown_tab(): # Get data for lockdown tab lockdown_data = get_lockdown_data() lockdown_data = prep_lockdown_data(lockdown_data) source_gantt = ColumnDataSource(lockdown_data.dropna()) source_points = ColumnDataSource(lockdown_data) # Create lockdown figure lockdown_fig = figure( y_range=FactorRange(factors=lockdown_data.Country.unique().tolist()), x_axis_type='datetime', title="Lockdown Status by Nation", x_range=(lockdown_data['start_date'].min() - timedelta(days=3), lockdown_data['end_date'].max() + timedelta(days=3)), outline_line_color=None, width=1000, height=650) # Adding hbar glyph of lockdown dates gantt_plot = lockdown_fig.hbar(y="Country", left='start_date', right='end_date', height=0.4, source=source_gantt, color='color') # Adding start point circle glyph start_point = lockdown_fig.circle(x='start_date', y='Country', source=source_points, size=5, line_color='blue', fill_color='white') # Adding end point circle glyph end_point = lockdown_fig.circle(x='end_date', y='Country', source=source_points, size=5, line_color='blue', fill_color='white') # Formatting x-axis lockdown_fig.xaxis.axis_label = "Date" lockdown_fig.xaxis.formatter = DatetimeTickFormatter(days='%d/%m/%Y') lockdown_fig.xaxis.ticker = DaysTicker(days=np.arange(5, 365, 7)) lockdown_fig.xaxis.major_label_orientation = math.pi / 6 # Formatting y-axis lockdown_fig.yaxis.axis_label = "Country" lockdown_fig.yaxis.major_label_orientation = math.pi / 12 lockdown_fig.yaxis.major_label_text_font_size = "7pt" lockdown_fig.yaxis.major_label_text_font_style = "bold" lockdown_fig.ygrid.grid_line_color = None lockdown_fig.y_range.range_padding = 0.05 # Align grid and axis tickers lockdown_fig.xgrid[0].ticker = lockdown_fig.xaxis[0].ticker # Adding hover tools gantt_hover = HoverTool(renderers=[gantt_plot], tooltips=[('Country', '@Country'), ('Start Date', '@start_date{%d/%m/%Y}'), ('End Date', '@end_date{%d/%m/%Y}'), ('Length', '@length{%d days}')], formatters={ '@start_date': 'datetime', '@end_date': 'datetime', '@length': 'printf' }) start_hover = HoverTool(renderers=[start_point], tooltips=[('Country', '@Country'), ('Start Date', '@start_date{%d/%m/%Y}')], formatters={'@start_date': 'datetime'}) end_hover = HoverTool(renderers=[end_point], tooltips=[('Country', '@Country'), ('End Date', '@end_date{%d/%m/%Y}')], formatters={'@end_date': 'datetime'}) lockdown_fig.add_tools(gantt_hover, start_hover, end_hover) # Adding vertical span for today's date today_date_span = Span(location=datetime.today(), dimension='height', line_color='blue', line_width=3, line_dash=[6, 6]) lockdown_fig.add_layout(today_date_span) # Labelling span span_label = Label(x=datetime.today() + timedelta(hours=12), y=-1.2, y_units='screen', text='Current Date', text_font_size='12pt') lockdown_fig.add_layout(span_label) # Adding CheckboxButtonGroup for continents continents = lockdown_data['continent'].unique().tolist() continent_rbg = RadioButtonGroup(labels=continents, active=None, width=500) def continent_rbg_callback(attr, old, new): if continent_rbg.active != None: selected_continent = continent_rbg.labels[continent_rbg.active] filtered_df = lockdown_data.loc[lockdown_data.continent == selected_continent] gantt_cds = ColumnDataSource(filtered_df.dropna()) points_cds = ColumnDataSource(filtered_df) source_gantt.data.update(gantt_cds.data) source_points.data.update(points_cds.data) lockdown_fig.y_range.factors = filtered_df.Country.unique().tolist( ) # Synchronise country filter country_multiselect.options = filtered_df['Country'].unique( ).tolist() country_multiselect.value = filtered_df['Country'].unique().tolist( ) continent_rbg.on_change('active', continent_rbg_callback) # Adding MultiSelect Widget for filtering by country countries = lockdown_data['Country'].unique().tolist() country_multiselect = MultiSelect(title='Countries:', options=countries, value=countries, height=500) def country_multiselect_callback(attr, old, new): selected_countries = country_multiselect.value filter_condition = lockdown_data.Country.isin(selected_countries) filtered_df = lockdown_data.loc[filter_condition] gantt_cds = ColumnDataSource(filtered_df.dropna()) points_cds = ColumnDataSource(filtered_df) source_gantt.data.update(gantt_cds.data) source_points.data.update(points_cds.data) lockdown_fig.y_range.factors = filtered_df.Country.unique().tolist() # Synchronise continent filter continent_rbg.active = None country_multiselect.on_change('value', country_multiselect_callback) # Creating Clear All, Select All Buttons def clear_button_callback(event): country_multiselect.options = countries country_multiselect.value = [] continent_rbg.active = None lockdown_fig.y_range.factors = lockdown_data.Country.unique().tolist() def select_all_button_callback(event): country_multiselect.options = countries country_multiselect.value = countries continent_rbg.active = None lockdown_fig.y_range.factors = lockdown_data.Country.unique().tolist() clear_button = Button(label="Clear Selection", button_type="success") clear_button.on_click(clear_button_callback) select_all_button = Button(label="Select All", button_type="success") select_all_button.on_click(select_all_button_callback) # Add the plot to the current document and add a title layout = row( widgetbox(clear_button, select_all_button, continent_rbg, country_multiselect), lockdown_fig) layout.sizing_mode = 'scale_width' # Creating lockdown tab lockdown_tab = Panel(child=layout, title='Lockdown') return (lockdown_tab)
config = [ default_simname, default_realname, sim_metric, real_metric, simdescription, realdescription, 1, 1 ] # this is just a placeholder in case you don't already have # def kill(): # # this is just for debugging. It creates an error so we can watch crash handling # sys.exit() # # raise RuntimeError("Fake error") # kill_mode_button = Button(label="Kill") # This is just a debugging tool to make sure the web app can handle crashes # kill_mode_button.on_click(kill) mission_mode_button = RadioButtonGroup( labels=["Show all flight modes", "Show only Mission mode"], active=0) mission_mode_button.on_change('active', lambda attr, old, new: mission_mode()) normalize_mode_button = RadioButtonGroup( labels=["Raw data", "Normalized data"], active=0) normalize_mode_button.on_change('active', lambda attr, old, new: normalize()) sim_reverse_button = RadioButtonGroup( labels=["Sim Default Orientation", "Reversed Orientation"], active=0) sim_reverse_button.on_change('active', lambda attr, old, new: reverse_sim()) real_reverse_button = RadioButtonGroup( labels=["Real Default Orientation", "Reversed Orientation"], active=0) real_reverse_button.on_change('active', lambda attr, old, new: reverse_real()) sim_swap_button = RadioButtonGroup(labels=["Sim Default X/Y", "Swapped X/Y"], active=0) sim_swap_button.on_change('active', lambda attr, old, new: swap_sim()) real_swap_button = RadioButtonGroup(labels=["Real Default X/Y", "Swapped X/Y"], active=0) real_swap_button.on_change('active', lambda attr, old, new: swap_real())
glob_fun_getCurrentXY.data = dict(fun=[getCurrentXY]) # /output glob_fun_moveTo.data = dict(fun=[moveTo]) # /output glob_fun_getKinEng.data = dict(fun=[getKinEng]) # /output glob_theta.data = dict(val=[0]) # /output glob_dTheta.data = dict(val=[0]) # /output TotEng = getTotEng() glob_TotEng.data = dict(val=[TotEng]) # /output plot() if (not Active): drawPhiAngle() pendulum_type_input = RadioButtonGroup( labels=["Single pendulum", "Double pendulum"], active=0) pendulum_type_input.on_change('active', swapPendulumType) ###################################### # Change language ###################################### def changeLanguage(): [lang] = flags.data["lang"] if lang == "en": setDocumentLanguage('de') elif lang == "de": setDocumentLanguage('en') def setDocumentLanguage(lang):
# Document to keep the objects in the server doc = curdoc() # Initilizes some usefull variables list_files = listdir("Policies/IPv4") selected_prefix_type = "IPv4" selected_year = ListYears()[0] selected_month = ListMonths(selected_year)[0] selected_day = ListDays(selected_year, selected_month)[0] plot_type = 0 selected_policy = None # Choose between IPv4 and IPv6. LABELS_IPV4_IPV6 = ["IPv4", "IPv6"] ipv4_ipv6_radio_button = RadioButtonGroup(labels=LABELS_IPV4_IPV6, active=0) ipv4_ipv6_radio_button.on_change( "active", OnChangeIPv4IPv6RadioButton) # Change the selected prefix. # Dropdown to select the year. # Dropdown list is based on the chosen prefix type, for example, if IPv4 is selected, only years with IPv4 files will be shown. year_dropdown = Dropdown(label="Select year", menu=ListYears()) year_dropdown.on_click(OnClickYearDropdown) # Change the selected year. # Dropdown to select the month. The months that will be shown is based os the selected prefix and the selected year. month_dropdown = Dropdown(label="Select month", menu=ListMonths(selected_year)) month_dropdown.on_click(OnClickMonthDropdown) # Change the selected month. month_dropdown.disabled = True # It will only let the user select the month if the year was already selected. # Dropdown to select the day. The days that will be shown is based os the selected prefix, the selected year and the selected month. day_dropdown = Dropdown(label="Select day", menu=ListDays(selected_year, selected_month)) day_dropdown.on_click(OnClickDayDropdown) # Change the selected day.
# p.plot_height = num_subt * 12 div.text = '\n'.join([textwrap.fill('Q: ' + new_ins['question'], 70)] + [ textwrap.fill(('%d: ' % idx) + ans, 70) for idx, ans in enumerate(new_ins['answers']) ]) def b_update(): qa_slider.end = len(qa[button.active]) - 1 qa_slider.value = 0 update() qa_slider = Slider(start=0, end=len(train_qa) - 1, value=0, step=1, title='qa #', width=1200) qa_slider.on_change('value', lambda attr, old, new: update()) button = RadioButtonGroup(labels=['train', 'validation'], active=0) button.on_change('active', lambda attr, old, new: b_update()) control = widgetbox(button, qa_slider) curdoc().add_root(layout([[control], [box]])) # curdoc().add_root(control) # curdoc().add_root(box) curdoc().title = "Visualize" update()
class TrimerFigure: order_functions: Dict[str, Any] = { "None": None, "Orient": create_orient_ordering(threshold=0.75), "Num Neighs": create_neigh_ordering(neighbours=6), } controls_width = 400 _frame = None plot = None _temperatures = None _pressures = None _crystals = None _iter_index = None _callback = None def __init__(self, doc, directory: Path = None, models=None) -> None: self._doc = doc self._trajectory = [None] if directory is None: directory = Path.cwd() self._source = ColumnDataSource({ "x": [], "y": [], "orientation": [], "colour": [], "radius": [] }) if models is not None: if not isinstance(models, (list, tuple)): raise ValueError( "The argument models has to have type list or tuple") logger.debug("Found additional models: %s", models) for model in models: model = Path(model) self.order_functions[model.stem] = create_ml_ordering(model) self.directory = directory self.initialise_directory() self._filename_div = Div(text="", width=self.controls_width) self.initialise_trajectory_interface() self.update_current_trajectory(None, None, None) self._playing = False # Initialise user interface self.initialise_media_interface() self.initialise_doc() def initialise_directory(self) -> None: self.variable_selection = parse_directory(self.directory, glob="dump*.gsd") logger.debug("Pressures present: %s", self.variable_selection.keys()) self._pressures = sorted(list(self.variable_selection.keys())) self._pressure_button = RadioButtonGroup( name="Pressure ", labels=self._pressures, active=0, width=self.controls_width, ) self._pressure_button.on_change("active", self.update_temperature_button) pressure = self._pressures[self._pressure_button.active] self._temperatures = sorted( list(self.variable_selection[pressure].keys())) self._temperature_button = Select( name="Temperature", options=self._temperatures, value=self._temperatures[0], width=self.controls_width, ) self._temperature_button.on_change("value", self.update_crystal_button) temperature = self._temperature_button.value self._crystals = sorted( list(self.variable_selection[pressure][temperature].keys())) self._crystal_button = RadioButtonGroup(name="Crystal", labels=self._crystals, active=0, width=self.controls_width) self._crystal_button.on_change("active", self.update_index_button) crystal = self._crystals[self._crystal_button.active] self._iter_index = sorted( list(self.variable_selection[pressure][temperature] [crystal].keys())) self._iter_index_button = Select( name="Iteration Index", options=self._iter_index, value=self._iter_index[0], width=self.controls_width, ) self._iter_index_button.on_change("value", self.update_current_trajectory) @property def pressure(self) -> Optional[str]: if self._pressures is None: return None return self._pressures[self._pressure_button.active] @property def temperature(self) -> Optional[str]: if self._temperatures is None: return None return self._temperature_button.value @property def crystal(self) -> Optional[str]: logger.debug("Current crystal %s from %s", self._crystal_button.active, self._crystals) if self._crystals is None: return None return self._crystals[self._crystal_button.active] @property def iter_index(self) -> Optional[str]: logger.debug("Current index %s from %s", self._iter_index_button.value, self._iter_index) return self._iter_index_button.value def update_temperature_button(self, attr, old, new): self._temperatures = sorted( list(self.variable_selection[self.pressure].keys())) self._temperature_button.options = self._temperatures self._temperature_button.value = self._temperatures[0] self.update_crystal_button(None, None, None) def update_crystal_button(self, attr, old, new): self._crystals = sorted( list(self.variable_selection[self.pressure][ self.temperature].keys())) self._crystal_button.labels = self._crystals self._crystal_button.active = 0 self.update_index_button(None, None, None) def update_index_button(self, attr, old, new): self._iter_index = sorted( list(self.variable_selection[self.pressure][self.temperature][ self.crystal].keys())) self._iter_index_button.options = self._iter_index self._iter_index_button.value = self._iter_index[0] self.update_current_trajectory(None, None, None) def create_files_interface(self) -> None: directory_name = Div( text=f"<b>Current Directory:</b><br/>{self.directory}", width=self.controls_width, ) self._filename_div = Div(text="", width=self.controls_width) current_file = self.get_selected_file() if current_file is not None: self._filename_div.text = f"<b>Current File:</b><br/>{current_file.name}" file_selection = column( directory_name, self._filename_div, Div(text="<b>Pressure:</b>"), self._pressure_button, Div(text="<b>Temperature:</b>"), self._temperature_button, Div(text="<b>Crystal Structure:</b>"), self._crystal_button, Div(text="<b>Iteration Index:</b>"), self._iter_index_button, ) return file_selection def get_selected_file(self) -> Optional[Path]: if self.pressure is None: return None if self.temperature is None: return None return self.variable_selection[self.pressure][self.temperature][ self.crystal][self.iter_index] def update_frame(self, attr, old, new) -> None: self._frame = HoomdFrame(self._trajectory[self.index]) self.update_data(None, None, None) def radio_update_frame(self, attr) -> None: self.update_frame(attr, None, None) @property def index(self) -> int: try: return self._trajectory_slider.value except AttributeError: return 0 def initialise_trajectory_interface(self) -> None: logger.debug("Loading Models: %s", self.order_functions.keys()) self._order_parameter = RadioButtonGroup( name="Classification algorithm:", labels=list(self.order_functions.keys()), active=0, width=self.controls_width, ) self._order_parameter.on_click(self.radio_update_frame) def create_trajectory_interface(self) -> None: return column( Div(text="<b>Classification Algorithm:<b>"), self._order_parameter, Div(text="<hr/>", width=self.controls_width, height=10), height=120, ) def update_current_trajectory(self, attr, old, new) -> None: if self.get_selected_file() is not None: logger.debug("Opening %s", self.get_selected_file()) self._trajectory = gsd.hoomd.open(str(self.get_selected_file()), "rb") num_frames = len(self._trajectory) try: if self._trajectory_slider.value > num_frames: self._trajectory_slider.value = num_frames - 1 self._trajectory_slider.end = len(self._trajectory) - 1 except AttributeError: pass self.update_frame(attr, old, new) current_file = self.get_selected_file() if current_file is not None: self._filename_div.text = ( f"<b>Current File:</b><br/>{current_file.name}") else: self._filename_div.text = f"<b>Current File:</b><br/>None" def initialise_media_interface(self) -> None: self._trajectory_slider = Slider( title="Trajectory Index", value=0, start=0, end=max(len(self._trajectory), 1), step=1, width=self.controls_width, ) self._trajectory_slider.on_change("value", self.update_frame) self._play_pause = Toggle(name="Play/Pause", label="Play/Pause", width=int(self.controls_width / 3)) self._play_pause.on_click(self._play_pause_toggle) self._nextFrame = Button(label="Next", width=int(self.controls_width / 3)) self._nextFrame.on_click(self._incr_index) self._prevFrame = Button(label="Previous", width=int(self.controls_width / 3)) self._prevFrame.on_click(self._decr_index) self._increment_size = Slider( title="Increment Size", value=10, start=1, end=100, step=1, width=self.controls_width, ) def _incr_index(self) -> None: if self._trajectory_slider.value < self._trajectory_slider.end: self._trajectory_slider.value = min( self._trajectory_slider.value + self._increment_size.value, self._trajectory_slider.end, ) def _decr_index(self) -> None: if self._trajectory_slider.value > self._trajectory_slider.start: self._trajectory_slider.value = max( self._trajectory_slider.value - self._increment_size.value, self._trajectory_slider.start, ) def create_media_interface(self): # return widgetbox([prevFrame, play_pause, nextFrame, increment_size], width=300) return column( Div(text="<b>Media Controls:</b>"), self._trajectory_slider, row( [self._prevFrame, self._play_pause, self._nextFrame], width=int(self.controls_width), ), self._increment_size, ) # When using webgl as the backend the save option doesn't work for some reason. def _update_source(self, data): logger.debug("Data Keys: %s", data.keys()) self._source.data = data def get_order_function(self) -> Optional[Callable]: return self.order_functions[list( self.order_functions.keys())[self._order_parameter.active]] def update_data(self, attr, old, new): if self.plot and self._frame is not None: self.plot.title.text = f"Timestep {self._frame.timestep:,}" if self._frame is not None: data = frame2data(self._frame, order_function=self.get_order_function(), molecule=Trimer()) self._update_source(data) def update_data_attr(self, attr): self.update_data(attr, None, None) def _play_pause_toggle(self, attr): if self._playing: self._doc.remove_periodic_callback(self._callback) self._playing = False else: self._callback = self._doc.add_periodic_callback( self._incr_index, 100) self._playing = True @staticmethod def create_legend(): cm_orient = LinearColorMapper(palette=DARK_COLOURS, low=-np.pi, high=np.pi) cm_class = LinearColorMapper( palette=[hpluv_to_hex((0, 0, 60)), hpluv_to_hex((0, 0, 80))], low=0, high=2) plot = figure(width=200, height=250) plot.toolbar_location = None plot.border_fill_color = "#FFFFFF" plot.outline_line_alpha = 0 cb_orient = ColorBar( title="Orientation", major_label_text_font_size="10pt", title_text_font_style="bold", color_mapper=cm_orient, orientation="horizontal", ticker=FixedTicker(ticks=[-np.pi, 0, np.pi]), major_label_overrides={ -np.pi: "-π", 0: "0", np.pi: "π" }, width=100, major_tick_line_color=None, location=(0, 120), ) cb_class = ColorBar( color_mapper=cm_class, title="Classification", major_label_text_font_size="10pt", title_text_font_style="bold", orientation="vertical", ticker=FixedTicker(ticks=[0.5, 1.5]), major_label_overrides={ 0.5: "Crystal", 1.5: "Liquid" }, label_standoff=15, major_tick_line_color=None, width=20, height=80, location=(0, 0), ) plot.add_layout(cb_orient) plot.add_layout(cb_class) return plot def initialise_doc(self): self.plot = figure( width=920, height=800, aspect_scale=1, match_aspect=True, title=f"Timestep {0:.5g}", output_backend="webgl", active_scroll="wheel_zoom", ) self.plot.xgrid.grid_line_color = None self.plot.ygrid.grid_line_color = None self.plot.x_range.start = -30 self.plot.x_range.end = 30 self.plot.y_range.start = -30 self.plot.y_range.end = 30 plot_circles(self.plot, self._source) def create_doc(self): self.update_data(None, None, None) controls = column( [ self.create_files_interface(), self.create_trajectory_interface(), self.create_media_interface(), ], width=int(self.controls_width * 1.1), ) self._doc.add_root(row(controls, self.plot, self.create_legend())) self._doc.title = "Configurations"
dates = ['ALL'] temp = list(pd.unique(dt['year']).astype(str)) temp.sort() dates.extend(temp) df_temp = pd.DataFrame() df_temp['dates'] = dates hover_tool = HoverTool(tooltips=[('District', '@DISTRICT'), ('Number of Deeds', '@RECORDS')]) color_mapper = LinearColorMapper(low=min(count), high=max(count), palette=Blues[9][1:]) radio_button_group = RadioButtonGroup(labels=dates, active=0, margin=(0, 0, 0, 10)) radio_button_group.on_change('active', call) button_widget = Button(label='Play', margin=(0, 0, 0, 120), width=100) button_widget.on_click(callback) data = ColumnDataSource( data={ 'DISTRICT': dis, 'RECORDS': count, 'X': list(coords.apply(lambda x: x[0])), 'Y': list(coords.apply(lambda x: x[1])), 'CENTER_X': cen_x, 'CENTER_Y': cen_y }) labels = LabelSet(x='CENTER_X', y='CENTER_Y', source=data, text='DISTRICT',
def build_time_evolution_tab(): # Importing geographical shapefile s3_root = 'https://covid19-bokeh-app.s3.eu-west-2.amazonaws.com' geo_data_gdf = gpd.read_file(f'{s3_root}/data/_geo_data/ne_50m_land.zip') geosource = GeoJSONDataSource(geojson=geo_data_gdf.to_json()) # Importing geo-evolutions cases/deaths data time_evol_df = pd.read_csv(f'{s3_root}/data/geo_time_evolution.csv') # Selecting earliest snapshot time_evol_df.date = pd.to_datetime(time_evol_df.date, format="%Y-%m-%d") snapshot_df = time_evol_df[time_evol_df.date == min(time_evol_df.date)] global_by_day_df = pd.read_csv(f'{s3_root}/data/global_by_day.csv') global_by_day_df.date = pd.to_datetime(global_by_day_df.date, format="%Y-%m-%d") global_totals_df = global_by_day_df.loc[global_by_day_df.date == min( time_evol_df.date)] global_cases = int(global_totals_df.iloc[0]['cases']) global_deaths = int(global_totals_df.iloc[0]['deaths']) # Applying bubble-size mapping bubble_size = snapshot_df['cases'].apply(lambda x: 0.5 * math.log(x, 1.1) if x > 0 else 0) snapshot_df = snapshot_df.assign(size=bubble_size.values) # Creating ColumnDataSource for visualisation cases_cds = ColumnDataSource(snapshot_df) # Adding figure and geographical patches from shapefile geo_plot = figure(plot_height=450, plot_width=720, x_range=(-180, 180), y_range=(-90, 90), name="time_evolution_geo_plot", sizing_mode="scale_width") geo_patches = geo_plot.patches('xs', 'ys', source=geosource, alpha=0.5) # Adding circle glyph to create bubble plot cases_circles = geo_plot.circle(x='long', y='lat', size='size', source=cases_cds, color='red', alpha=0.2) # Adding hover tool hover = HoverTool(tooltips=[('Country/Region', '@region'), ('Province/State', '@province'), ('Cases', '@cases')], renderers=[cases_circles]) geo_plot.add_tools(hover) # Adding hbar countries_df = snapshot_df.loc[:, ['date', 'region', 'cases']] countries_df.rename(columns={"cases": "value"}, inplace=True) countries_df = countries_df.groupby(['date', 'region']).sum().reset_index() countries_df.sort_values(by='value', ascending=False, inplace=True) countries_df = countries_df.reset_index(drop=True) countries_cds = ColumnDataSource(countries_df) hbar_plot = figure(plot_height=450, plot_width=475, y_range=(10.5, -0.5), x_range=(0, countries_df.value.max() * 1.2), name="time_evolution_hbar_plot", sizing_mode="scale_width") hbar = hbar_plot.hbar(left=0, right='value', y='index', source=countries_cds, height=0.5, line_color='white') labels = LabelSet(x='value', y='index', text='region', text_font_size='10pt', text_color='white', x_offset=5, y_offset=0, source=countries_cds, level='glyph', render_mode='canvas') hbar_plot.add_layout(labels) # Adding hover tool hover_hbar = HoverTool(tooltips=[('Country/Region', '@region'), ('Cases', '@value')], renderers=[hbar]) hbar_plot.add_tools(hover_hbar) # Adding callback for updating data def data_view_callback(attr, old, new): """Callback function to update data source: - Updates source data to selected data view (cases/deaths/new cases/new deaths) and selected snapshot date on date slider. - Updates HoverTool to reflect data view change - Updates Divs for total cases/deaths """ # Determine data view selection if cases_deaths_button.active == 0: data_view = "cases" elif cases_deaths_button.active == 1: data_view = "deaths" if total_new_button.active == 1: data_view = f"new_{data_view}" # Determine date selection slider_date = date_slider.value_as_datetime.date() # Filter data for selected date snapshot_df = time_evol_df[time_evol_df.date == pd.Timestamp( slider_date)] # Map bubble size on selected data view bubble_size = snapshot_df[data_view].apply( lambda x: 0.5 * math.log(x, 1.1) if x > 0 else 0) snapshot_df = snapshot_df.assign(size=bubble_size.values) cases_cds.data = snapshot_df hover.tooltips = [('Country/Region', '@region'), ('Province/State', '@province'), (data_view.replace('_', ' ').title(), f'@{data_view}')] # Update hbar data countries_df = snapshot_df.loc[:, ['date', 'region', data_view]] countries_df.rename(columns={data_view: "value"}, inplace=True) countries_df = countries_df.groupby(['date', 'region']).sum().reset_index() countries_df.sort_values(by="value", ascending=False, inplace=True) countries_df = countries_df.reset_index(drop=True) countries_cds.data = countries_df hbar_plot.x_range.end = countries_df.value.max() * 1.2 hover_hbar.tooltips = [('Country/Region', '@region'), (data_view.replace('_', ' ').title(), '@value')] # Filter for totals global_totals_df = global_by_day_df.loc[( global_by_day_df.date == pd.Timestamp(slider_date))] global_cases = int(global_totals_df.iloc[0]['cases']) global_deaths = int(global_totals_df.iloc[0]['deaths']) cases_div.text = (f'<h3 class="card-text">' f'{global_cases:,}</h3>') deaths_div.text = (f'<h3 class="card-text">' f'{global_deaths:,}</h3>') # Adding Date slider date_range = [ pd.Timestamp(date_val) for date_val in time_evol_df.date.unique() ] date_slider = DateSlider(title="Date", start=min(date_range), end=max(date_range), value=min(date_range), sizing_mode="scale_width") date_slider.on_change('value', data_view_callback) # Adding Cases/Deaths toggle cases_deaths_button = RadioButtonGroup(labels=["Cases", "Deaths"], active=0, sizing_mode="scale_width") cases_deaths_button.on_change('active', data_view_callback) # Adding Total/New toggle total_new_button = RadioButtonGroup(labels=["Total", "New"], active=0, sizing_mode="scale_width") total_new_button.on_change('active', data_view_callback) # Adding callback for zooming into a selected continent def continent_zoom_callback(attr, old, new): continent_map_ref = { # Worldwide 0: { 'x_range': [-200, 200], 'y_range': [-100, 100] }, # Europe 1: { 'x_range': [-30, 50], 'y_range': [30, 70] }, # North America 2: { 'x_range': [-175, -15], 'y_range': [0, 80] }, # South America 3: { 'x_range': [-140, 10], 'y_range': [-60, 15] }, # Africa 4: { 'x_range': [-55, 105], 'y_range': [-40, 40] }, # Asia 5: { 'x_range': [40, 140], 'y_range': [-5, 45] }, # Oceania 6: { 'x_range': [80, 200], 'y_range': [-55, 5] } } map_ref = continent_map_ref[continent_button.active] geo_plot.x_range.start = map_ref['x_range'][0] geo_plot.x_range.end = map_ref['x_range'][1] geo_plot.y_range.start = map_ref['y_range'][0] geo_plot.y_range.end = map_ref['y_range'][1] # Adding continent toggle continent_button = RadioGroup(labels=[ "Worldwide", "Europe", "North America", "South America", "Africa", "Asia", "Oceania" ], active=0) continent_button.on_change('active', continent_zoom_callback) # Adding animation with Play/Pause button callback_id = None def animate(): def animate_update(): date = date_slider.value_as_datetime.date() + timedelta(days=1) date = pd.Timestamp(date) if date >= max(date_range): date = min(date_range) date_slider.value = date global callback_id if play_button.label == '► Play': play_button.label = '❚❚ Pause' callback_id = curdoc().add_periodic_callback(animate_update, 300) else: play_button.label = '► Play' curdoc().remove_periodic_callback(callback_id) play_button = Button(label='► Play', width=60, button_type="success") play_button.on_click(animate) # Adding Cases/Deaths count cases_div = Div(text=f'<h3 class="card-text">' f'{global_cases:,}</h3>', sizing_mode="scale_width", name="cases_div") deaths_div = Div(text=f'<h3 class="card-text">' f'{global_deaths:,}</h3>', sizing_mode="scale_width", name="deaths_div") # Defining layout of tab widgets = widgetbox(date_slider, cases_deaths_button, total_new_button, play_button, continent_button, name="time_evolution_widgetbox", sizing_mode="scale_width") # Add the plot to the current document curdoc().add_root(geo_plot) curdoc().add_root(hbar_plot) curdoc().add_root(widgets) curdoc().add_root(cases_div) curdoc().add_root(deaths_div)
def update(attr, old, new): # Adjust map by using radio buttons colour_fillings = map_redraw(new) categories = [ "Active COVID cases", "Resolved COVID cases", "Deaths due to COVID" ] data_map.patches(source=geosource, line_color='black', fill_color=colour_fillings, line_width=0.25, fill_alpha=1) data_map.title.text = categories[new] + ' by Public Health Unit in Ontario' #Specify figure layout. data_map.add_layout(color_bar, 'below') button_group = RadioButtonGroup( labels=["Active Cases", "Resolved Cases", "Deaths"], active=0) button_group.on_change('active', lambda attr, old, new: update(attr, old, new)) # Slider tool for selecting dates data_slider = Slider(title='Date (YYYYMMDD)', start=20200410, end=20201224, step=1, value=20200410) data_slider.on_change('value', json_data_update) # Output final map project_layout = column(data_map, widgetbox(button_group, data_slider)) curdoc().add_root(project_layout)
def wohngeld(plot_dict, data): def make_dataset(sel_year, hh_size, wg_dict): dataset = wg_dict[sel_year][hh_size] heatmap_source = pd.DataFrame(dataset.stack(), columns=["Wohngeld"]).reset_index() heatmap_source.columns = ["Miete", "Einkommen", "Wohngeld"] return ColumnDataSource(heatmap_source) def update_plot(attr, old, new): sel_year = [1992, 2001, 2009, 2016, 2020, 2021][year_selection.active] hh_size = hh_size_selection.value new_src = make_dataset(sel_year, hh_size, wg_dict) src.data.update(new_src.data) def setup_plot(src): """ Create the heatmap plot. src: ColumnDataSource """ # Prepare a color pallete and color mapper mapper = LinearColorMapper( # force 0 to be mapped with white color palette=tuple( itertools.chain(["#FFFFFF"], tuple(reversed(Viridis256[1:])))), low=0, high=1000, ) # Actual figure setup p = figure( plot_width=800, plot_height=400, x_range=(src.data["Miete"].min(), src.data["Miete"].max()), y_range=(src.data["Einkommen"].min(), src.data["Einkommen"].max()), tools="hover", tooltips="Housing Benefit: @Wohngeld{0.0f}€", ) p.rect( x="Miete", y="Einkommen", width=25, height=src.data["Einkommen"][1] - src.data["Einkommen"][0], source=src, line_color=transform("Wohngeld", mapper), fill_color=transform("Wohngeld", mapper), ) color_bar = ColorBar( color_mapper=mapper, location=(0, 0), ticker=BasicTicker(desired_num_ticks=20), formatter=NumeralTickFormatter(format="0€"), label_standoff=12, ) p.add_layout(color_bar, "right") plot = plotstyle(p, plot_dict) return plot wg_dict = data year_selection = RadioButtonGroup( labels=[str(i) for i in [1992, 2001, 2009, 2016, 2020, 2021]], active=5) year_selection.on_change("active", update_plot) hh_size_selection = Slider(start=1, end=12, value=4, step=1, title="Household Size") hh_size_selection.on_change("value", update_plot) src = make_dataset(2021, 4, wg_dict) p = setup_plot(src) description = Div( text=plot_dict["description"], width=1000, ) year_label = Div(text="Year") layout = column(description, year_label, year_selection, hh_size_selection, p) tab = Panel(child=layout, title="Housing benefits") return tab
def post(self, *args, **kwargs): """ POST request callback """ if self.multipart_streamer: try: file_input = FileInput(accept=".ulg, .csv") file_input.on_change('value', upload_new_data_sim) file_input2 = FileInput(accept=".ulg, .csv") file_input2.on_change('value', upload_new_data_real) curdoc().template_variables['title_html'] = get_heading_html( ulog, px4_ulog, db_data, None, [ ('Open Main Plots', link_to_main_plots) ], 'PID Analysis') + page_intro intro_text = Div( text="""<H2>Sim/Real Thiel Coefficient Calculator</H2>""", width=500, height=100, align="center") sim_upload_text = Div( text= """Upload a simulator datalog: <a href="/tornado_handlers/browse"> this script</a>""", width=500, height=15) real_upload_text = Paragraph( text="Upload a corresponding real-world datalog:", width=500, height=15) #checkbox_group = CheckboxGroup(labels=["x", "y", "vx","vy","lat","lon"], active=[0, 1]) sim_reverse_button = RadioButtonGroup( labels=["Sim Default", "Reversed"], active=0) sim_reverse_button.on_change( 'active', lambda attr, old, new: reverse_sim()) real_reverse_button = RadioButtonGroup( labels=["Real Default", "Reversed"], active=0) real_reverse_button.on_change( 'active', lambda attr, old, new: reverse_real()) simsource_static.selected.on_change('indices', simselection_change) # The below are in case you want to see the x axis range change as you pan. Poorly documented elsewhere! #ts1.x_range.on_change('end', lambda attr, old, new: print ("TS1 X range = ", ts1.x_range.start, ts1.x_range.end)) #ts2.x_range.on_change('end', lambda attr, old, new: print ("TS2 X range = ", ts2.x_range.start, ts2.x_range.end)) ts1.x_range.on_change( 'end', lambda attr, old, new: change_sim_scale(ts1.x_range.start)) ts2.x_range.on_change( 'end', lambda attr, old, new: change_real_scale(ts2.x_range .start)) # set up layout widgets = column(datatype, stats) sim_button = column(sim_reverse_button) real_button = column(real_reverse_button) main_row = row(widgets) series = column(ts1, sim_button, ts2, real_button) layout = column(main_row, series) # initialize update() doc.add_root(intro_text) doc.add_root(sim_upload_text) doc.add_root(file_input) doc.add_root(real_upload_text) doc.add_root(file_input2) doc.add_root(layout) doc.title = "Flight data" except CustomHTTPError: raise except ULogException: raise CustomHTTPError( 400, 'Failed to parse the file. It is most likely corrupt.') except: print('Error when handling POST data', sys.exc_info()[0], sys.exc_info()[1]) raise CustomHTTPError(500) finally: self.multipart_streamer.release_parts()
word_path = np.array(words[new[0]]).dot([5, 1]) highlight_alpha = np.ones((25, )) * 0.25 highlight_alpha[word_path] = 1 dice_src.data["fill_alpha"] = highlight_alpha.reshape(5, 5) # reset highlights else: dice_src.data["fill_alpha"] = np.ones((5, 5)) # Set up callbacks shuffle_button.on_click(shuffle) start_button.on_click(start_game) stop_button.on_click(stop_timer) show_words_button.on_click(show_word_list) show_words_options.on_change("active", sort_word_list) word_select.on_change("value", show_word) # Set up layouts and add to document inputs = column( special_toggle, angle_toggle, shuffle_button, time_slider, start_button, stop_button, timer, p, ) rhs = column(show_words_button, show_words_options,
rangeslider = RangeSlider(start=140000, end=225000, step=10, value=(140000, 150000), title="X range") file_selector = Select(value=None, options=nix(None, files)) waveselector = RadioButtonGroup(labels=["P wave", "QRS wave", "T wave"], active=0) textboxnew = PreText(text="New points: \t[]") retrievebutton = Button(label='Retrieve Segmentation') storebutton = Button(label='Store Segmentation') writebutton = Button(label='Write to File') # Set callbacks file_selector.on_change('value', file_change) source.selected.on_change('indices', selection_change) retrievebutton.on_click(retrieve_segmentation) storebutton.on_click(save_segmentation) writebutton.on_click(write_segmentation) rangeslider.on_change('value', change_range) waveselector.on_change('active', file_change) # set up layout buttons = row(waveselector, retrievebutton, storebutton, writebutton) layout = column(file_selector, textboxnew, rangeslider, buttons, grid) # initialize # update() curdoc().add_root(layout) curdoc().title = "FullDelineator"
np.around(100 * mp[0], decimals=2)) + "%" label75.text = '75% probability still alive at age = ' + str( np.around(Age75, decimals=1)) label25.text = '25% probability still alive at age = ' + str( np.around(Age25, decimals=1)) label1ya.text = "reduced to = " + str(np.around(100 * mp2[0], decimals=2)) + "%" label50a.text = 'reduced to = ' + str(np.around(MA2, decimals=1)) label75a.text = 'reduced to = ' + str(np.around(A72, decimals=1)) label25a.text = 'reduced to = ' + str(np.around(A22, decimals=1)) for w in [AgeSlider, EventMortalitySlider]: w.on_change('value', update_data) GenderRadioButtons.on_change('active', update_data) inputs = column(AgeSlider, EventMortalitySlider, GenderRadioButtons) # read in html strings for header and footer with open("LifeHeader.txt", "r") as myfile: texttop = myfile.read() with open("LifeFooter.txt", "r") as myfile: textbottom = myfile.read() divtop = Div(text=texttop, sizing_mode="scale_width") divbottom = Div(text=textbottom, sizing_mode="scale_width") # create the document curdoc().add_root(divtop) curdoc().add_root(row(inputs, plot))
def __init__(self): ### Methods self.args = Settings() self.index = None self.data_getter = None self.filter = None self._data = None self._model_type = None self._model_dir = self.args.models_path + 'unique_object/' self.controls = {} self.scene_plotter = ScenePlotter(self._set_head_selection) ### initialization of the interface ## Model type selector def update_select_net(): if self._model_dir is not None: file_list = [fn for fn in os.listdir(self._model_dir) if os.path.isfile(os.path.join(self._model_dir, fn))] file_list.sort(key=lambda fn: os.stat(os.path.join(self._model_dir, fn)).st_mtime, reverse=True) file_list = [os.path.splitext(fn)[0] for fn in file_list] self.controls['net'].options = file_list # print(self._model_dir) # print('file_list') # print(file_list) if len(file_list) > 0: self.controls['net'].value = file_list[0] else: self.controls['net'].value = None def update_model_type(): if self.controls['multi_mono_object'].active == 0: self._model_type = 'mono' self._model_dir = self.args.models_path + 'unique_object/' elif self.controls['multi_mono_object'].active == 1: self._model_type = 'multi_obj' self._model_dir = self.args.models_path + 'multi_objects/' elif self.controls['multi_mono_object'].active == 2: self._model_type = 'multi_pred' self._model_dir = self.args.models_path + 'multi_pred/' model_types = ['CV', 'CA', 'Bicycle', 'CV_LSTM', 'CA_LSTM', 'Bicycle_LSTM', 'nn_attention'] existing_types = [type for type in model_types if os.path.isdir(self._model_dir + type)] self.controls['model_sub_type'].options = existing_types print('existing types') print(existing_types) if len(existing_types) > 0 and not self.controls['model_sub_type'].value in existing_types: self.controls['model_sub_type'].value = existing_types[0] return set_model_sub_type() update_select_net() def set_model_sub_type(): if self.controls['model_sub_type'].value is not None: self._model_dir = self._model_dir + self.controls['model_sub_type'].value + '/' self.args.model_type = self.controls['model_sub_type'].value else: self._model_dir = None def update_multi_mono_object(attr, old, new): update_model_type() print(self._model_dir) self._set_data_getter() print('___') multi_mono_object = RadioButtonGroup(labels=["Mono-object", "Multi-objects", "Multi-pred"], active=1) self.controls['multi_mono_object'] = multi_mono_object multi_mono_object.on_change('active', update_multi_mono_object) ## Model sub type selector model_types = ['CV', 'CA', 'Bicycle', 'CV_LSTM', 'CA_LSTM', 'Bicycle_LSTM', 'nn_attention'] model_sub_type = Select(title='Select model type:', value=model_types[3], options=model_types) self.controls['model_sub_type'] = model_sub_type model_sub_type.on_change('value', lambda att, old, new: update_model_type()) ## Model selector select = Select(title="Select parameter file:", value=None, options=[]) self.controls['net'] = select select.on_change('value', lambda att, old, new: self._set_data_getter()) ## Select dataset to use dataset_list = ['Argoverse', 'Fusion', 'NGSIM'] select = Select(title='Dataset:', value=dataset_list[0], options=dataset_list) self.controls['dataset'] = select select.on_change('value', lambda att, old, new: self._set_data_getter(change_index=True)) ## Set what to draw checkbox_group = CheckboxGroup( labels=['Draw lanes', 'Draw history', 'Draw true future', 'Draw forecast', 'Draw forecast covariance'], active=[0, 1, 2, 3, 4]) self.controls['check_box'] = checkbox_group checkbox_group.on_change('active', lambda att, old, new: (self._update_cov(), self._update_lanes(), self._update_path())) ## Set the number of pred n_pred = Slider(start=1, end=6, step=1, value=1, title='Number of prediction hypothesis') self.controls['n_pred'] = n_pred n_pred.on_change('value', lambda att, old, new: (self._update_cov(), self._update_path())) ## Sequence ID input text_input = TextInput(title="Sequence ID to plot:", value="Random") self.controls['sequence_id'] = text_input ## Head selection input multi_select_head = MultiSelect(title='Attention head multiple selection:', value=[], options=[]) self.controls['Head_selection'] = multi_select_head multi_select_head.on_change('value', self.scene_plotter.set_active_heads) ## Refresh all sample button = Button(label="Refresh", button_type="success") self.controls['refresh'] = button button.on_click( lambda event: (self._set_index(), self._set_data())) # button.js_on_click(CustomJS(args=dict(p=self.image), code="""p.reset.emit()""")) update_multi_mono_object(None, None, None) ## Set the interface layout inputs = column(*(self.controls.values()), width=320, height=1000) inputs.sizing_mode = "fixed" lay = layout([[inputs, self.scene_plotter.get_image()]], sizing_mode="scale_both") curdoc().add_root(lay) self.scene_plotter._tap_on_veh('selected', [], [0])
p.xaxis.axis_label = 'Time' p.yaxis.visible = False p.add_tools(hover) curdoc().clear() div.text = '<h1>' + file_input.filename + '</h1>' curdoc().add_root(column(file_input, div, radio_button, get_current_plot())) def get_current_plot(): if radio_button.active == 0: return p1 elif radio_button.active == 1: return p2 else: return p3 def change_current_plot(attr, old, new): curdoc().clear() curdoc().add_root(column(file_input, div, radio_button, get_current_plot())) file_input = FileInput(accept=".json") file_input.on_change('value', load_trace_data) radio_button.on_change('active', change_current_plot) curdoc().add_root(file_input)
height=450, width=600, tools="save,reset", toolbar_location="below") plot_figure.scatter('x', 'y', color='label', source=source, size=10) radio_button_group = RadioButtonGroup(labels=["Red", "Orange"]) def radiogroup_click(attr, old, new): active_radio = radio_button_group.active ##Getting radio button value # filter the dataframe with value in radio-button if active_radio == 0: selected_df = df[df['label'] == 'Red'] elif active_radio == 1: selected_df = df[df['label'] == "Orange"] source.data = dict(x=selected_df.x, y=selected_df.y, label=selected_df.label) radio_button_group.on_change('active', radiogroup_click) layout = row(radio_button_group, plot_figure) curdoc().add_root(layout) curdoc().title = "Radio Button Group Bokeh Server"
align="center", sizing_mode="stretch_width") # Make a toggle to cycle through the dates button = Button(label='► Play', height=30) button.on_click(animate) # Make a toggle for changing the map to linear tog_lin = Toggle(label='Lin Map', active=False, height=30) tog_lin.on_change('active', change_var) tog_res = Toggle(label='Hi Res', active=False, height=30) tog_res.on_change('active', change_src) rb_who_jhu = RadioButtonGroup(labels=['WHO', 'JHU'], active=0, height=30) rb_who_jhu.on_change('active', change_src) rb_cases_deaths = RadioButtonGroup(labels=['Cases', 'Deaths'], active=0, height=30) rb_cases_deaths.on_change('active', change_var) rb_abs_rel = RadioButtonGroup(labels=['Per Region', 'Per 100k'], active=0, height=30) rb_abs_rel.on_change('active', change_var) rb_tot_new = RadioButtonGroup(labels=['Total', 'New', 'Avg'], active=0, height=30) rb_tot_new.on_change('active', change_var)
var recovered = document.getElementById("total-Region-Recovered"); var confirmed = document.getElementById("total-Region-Confirmed"); var region = cb_obj.value death.innerHTML = death_case[region].toLocaleString('id') recovered.innerHTML = recovered_case[region].toLocaleString('id') confirmed.innerHTML = confirmed_case[region].toLocaleString('id') """ js_on_change_region = CustomJS(args=dict(source=source, death_case=total_death_case, confirmed_case=total_confirmed_case, recovered_case=total_recovered_case), code=code) region_select.js_on_change('value', js_on_change_region) case_select.on_change('active', handle_case_change) range_slider.on_change('value', handle_range_change) button.on_click(change_theme) plt = make_plot(source, case.capitalize() + " case in " + region, case, sizing_mode="stretch_both") # Layouting about_text = """ <div style="width:300px;"> <ul class="list-group"> <li class="list-group-item">Anvaqta Tangguh Wisesa</li> <li class="list-group-item">Rachma Indira</li> <li class="list-group-item">Rachmansyah Adhi Widhianto</li> </ul>
def heatmap(df): def make_dataset(df, usageType): """ usageType:'gastotalusage, tariff1totalusage of tariff2totalusage """ df_verwerkt = df[df['attributeName'] == usageType] df_verwerkt = df_verwerkt.sort_values('time') df_verwerkt = df_verwerkt.replace(0, np.NaN) df_verwerkt = df_verwerkt.fillna(method='ffill') df_verwerkt['time'] = pd.to_datetime(df_verwerkt['time'], unit='ms', utc=True) df_verwerkt['time'] = df_verwerkt['time'].apply( lambda x: x.astimezone(timezone('Europe/Amsterdam'))) df_verwerkt['hour'] = df_verwerkt['time'].dt.hour df_verwerkt['dayofweek'] = df_verwerkt['time'].dt.dayofweek df_verwerkt['difference'] = df_verwerkt['value'].diff() df_verwerkt[df_verwerkt['difference'] > 1000] = 0 # sprong naar Nederhoven uitfilteren pivot = pd.pivot_table(df_verwerkt, index='dayofweek', columns='hour', values='difference', aggfunc=sum) pivot = pivot.fillna(0) stacked = pivot.stack().reset_index() stacked = stacked.rename(columns={0: 'aantal'}) return ColumnDataSource(data=stacked) # return stacked def make_plot(src): p1 = figure(title="Gasverbruik per uur", x_range=(-0.5, 23.5), y_range=(-0.5, 6.5), x_axis_location="above", plot_width=900, plot_height=400, tools=TOOLS, toolbar_location='below', tooltips=[('Aantal', '@aantal'), ('Dag', '@dayofweek'), ('Uur', '@hour')]) p1.grid.grid_line_color = None p1.axis.axis_line_color = None p1.axis.major_tick_line_color = None p1.axis.major_label_text_font_size = "5pt" p1.axis.major_label_standoff = 0 p1.xaxis.major_label_orientation = pi / 3 p1.xaxis.ticker = FixedTicker(ticks=[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 ]) p1.yaxis.ticker = FixedTicker(ticks=[0, 1, 2, 3, 4, 5, 6]) p1.yaxis.major_label_overrides = { 0: 'Maandag', 1: 'Dinsdag', 2: 'Woensdag', 3: 'Donderdag', 4: 'Vrijdag', 5: 'Zaterdag', 6: 'Zondag' } p1.rect(x="hour", y="dayofweek", width=1, height=1, source=src, fill_color={ 'field': 'aantal', 'transform': mapper1 }, line_color=None) color_bar1 = ColorBar( color_mapper=mapper1, major_label_text_font_size="5pt", ticker=BasicTicker(desired_num_ticks=len(colors)), formatter=PrintfTickFormatter(format="%d"), label_standoff=6, border_line_color=None, location=(0, 0)) p1.add_layout(color_bar1, 'right') return p1 def update(attr, old, new): # Get the selected items for the graph # ... selected = radio_button_group.active usageType = 'gastotalusage' # standaardwaarde # Koppel de selectie aan de juiste gegevens uit het DataFrame if selected == 0: usageType = 'gastotalusage' p.title.text = 'Gasverbruik per uur' elif selected == 1: usageType = 'tariff1totalusage' p.title.text = 'Stroomtarief 1 verbruik' elif selected == 2: usageType = 'tariff2totalusage' p.title.text = 'Stroomtarief 2 verbruik' print('Update usageType: ' + str(usageType)) # update data new_src = make_dataset(df, usageType) src.data.update(new_src.data) # update color bar new_df = src.to_df() mapper1.low = new_df.aantal.min() mapper1.high = new_df.aantal.max() print('------------------------') radio_button_group = RadioButtonGroup( labels=["Gas", "Tarief 1", "Tarief 2"], active=0) radio_button_group.on_change('active', update) # initial execution src = make_dataset(df, 'gastotalusage') new_df = src.to_df() mapper1 = LinearColorMapper(palette=colors, low=new_df.aantal.min(), high=new_df.aantal.max()) p = make_plot(src) # make a grid grid = gridplot([[p, radio_button_group]]) tab = Panel(child=grid, title='Heatmap') print("heatmap() uitgevoerd") return tab
def barchart_datepicker(df): def make_dataset(df, usageType='gastotalusage', start=datetime.date(2015, 1, 1), stop=datetime.date.today()): if type(start) == str: start = datetime.datetime.strptime(start, '%Y-%m-%d').date() if type(stop) == str: stop = datetime.datetime.strptime(stop, '%Y-%m-%d').date() start_milliseconds = ( (start - datetime.date(1970, 1, 1)).total_seconds() * 1000) stop_milliseconds = ( (stop - datetime.date(1970, 1, 1)).total_seconds() * 1000) + ( 86400000 - 1 ) # Plus 1 dag minus - milliseconde = einde van die dag if usageType == 'powertotalusage': # select both tariff1totalusage and tariff2totalusage df_verwerkt1 = df.loc[(df['attributeName'] == 'tariff1totalusage') & (df['time'] >= start_milliseconds) & (df['time'] <= stop_milliseconds)] df_verwerkt1 = df_verwerkt1.sort_values('time') df_verwerkt1 = df_verwerkt1.replace(0, np.NaN) df_verwerkt1 = df_verwerkt1.fillna(method='ffill') df_verwerkt1 = df_verwerkt1.fillna( method='bfill') # nodig om eerste rij te fixen. df_verwerkt1['time'] = pd.to_datetime(df_verwerkt1['time'], unit='ms', utc=True) df_verwerkt1['time'] = df_verwerkt1['time'].apply( lambda x: x.astimezone(timezone('Europe/Amsterdam'))) # df_verwerkt1['hour'] = df_verwerkt1['time'].dt.hour df_verwerkt1['minutes'] = (df_verwerkt1['time'].dt.hour * 60) + df_verwerkt1['time'].dt.minute # df_verwerkt1['dayofweek'] = df_verwerkt1['time'].dt.dayofweek df_verwerkt1['difference'] = df_verwerkt1['value'].diff() df_verwerkt1['difference'] = df_verwerkt1['difference'].fillna(0) df_verwerkt1[df_verwerkt1['difference'] > 1000] = 0 # sprong naar Nederhoven uitfilteren df_verwerkt1 = df_verwerkt1[df_verwerkt1['difference'] > 0] # df_verwerkt1 = remove_outlier(df_verwerkt1, 'difference') df_verwerkt2 = df.loc[(df['attributeName'] == 'tariff2totalusage') & (df['time'] >= start_milliseconds) & (df['time'] <= stop_milliseconds)] df_verwerkt2 = df_verwerkt2.sort_values('time') df_verwerkt2 = df_verwerkt2.replace(0, np.NaN) df_verwerkt2 = df_verwerkt2.fillna(method='ffill') df_verwerkt2 = df_verwerkt2.fillna( method='bfill') # nodig om eerste rij te fixen. df_verwerkt2['time'] = pd.to_datetime(df_verwerkt2['time'], unit='ms', utc=True) df_verwerkt2['time'] = df_verwerkt2['time'].apply( lambda x: x.astimezone(timezone('Europe/Amsterdam'))) # df_verwerkt2['hour'] = df_verwerkt2['time'].dt.hour df_verwerkt2['minutes'] = (df_verwerkt2['time'].dt.hour * 60) + df_verwerkt2['time'].dt.minute # df_verwerkt2['dayofweek'] = df_verwerkt2['time'].dt.dayofweek df_verwerkt2['difference'] = df_verwerkt2['value'].diff() df_verwerkt2['difference'] = df_verwerkt2['difference'].fillna(0) df_verwerkt2[df_verwerkt2['difference'] > 1000] = 0 # sprong naar Nederhoven uitfilteren df_verwerkt2 = df_verwerkt2[df_verwerkt2['difference'] > 0] # df_verwerkt2 = remove_outlier(df_verwerkt2, 'difference') df_verwerkt = pd.concat([df_verwerkt1, df_verwerkt2], ignore_index=True) groupby = df_verwerkt.groupby('minutes').sum() else: df_verwerkt = df.loc[(df['attributeName'] == usageType) & (df['time'] >= start_milliseconds) & (df['time'] <= stop_milliseconds)] df_verwerkt = df_verwerkt.sort_values('time') df_verwerkt = df_verwerkt.replace(0, np.NaN) df_verwerkt = df_verwerkt.fillna(method='ffill') df_verwerkt = df_verwerkt.fillna( method='bfill') # nodig om eerste rij te fixen. df_verwerkt['time'] = pd.to_datetime(df_verwerkt['time'], unit='ms', utc=True) df_verwerkt['time'] = df_verwerkt['time'].apply( lambda x: x.astimezone(timezone('Europe/Amsterdam'))) # df_verwerkt['hour'] = df_verwerkt['time'].dt.hour df_verwerkt['minutes'] = (df_verwerkt['time'].dt.hour * 60) + df_verwerkt['time'].dt.minute # df_verwerkt['dayofweek'] = df_verwerkt['time'].dt.dayofweek df_verwerkt['difference'] = df_verwerkt['value'].diff() df_verwerkt['difference'] = df_verwerkt['difference'].fillna(0) df_verwerkt[df_verwerkt['difference'] > 1000] = 0 # sprong naar Nederhoven uitfilteren df_verwerkt = df_verwerkt[df_verwerkt['difference'] > 0] # df_verwerkt = remove_outlier(df_verwerkt, 'difference') groupby = df_verwerkt.groupby('minutes').sum() print('startdatum zoals verwerkt: ' + str(start)) print('einddatum zoals verwerkt: ' + str(stop)) return ColumnDataSource(data=groupby) def make_plot(src): # Deze regel maakt een dict met de vorm {0: '00:00', 1: '00:01', ... t/m 1440 voor alle minuten van de dag. # In feite zet deze regel alle minuten van 0 t/m 1440 om in een string met tijd voor de x-as. d = { i: f"{floor(i/60):02d}" + ":" + f"{int(i%60):02d}" for i in range(1440) } p = figure(title='Bar chart', x_range=(0, 1440), tools=TOOLS, background_fill_color="#fafafa") p.sizing_mode = 'stretch_both' # https://docs.bokeh.org/en/latest/docs/user_guide/layout.html p.vbar(x='minutes', bottom=0, top='difference', source=src, width=0.9, color={ 'field': 'difference', 'transform': color_mapper }) p.y_range.start = 0 p.xaxis.axis_label = 'Tijd' p.xaxis.major_label_overrides = d p.yaxis.axis_label = 'Verbruik' p.grid.grid_line_color = "white" return p def update_radios(attr, old, new): # Get the selected items for the graph # ... selected = radio_button_group.active global usageType # Koppel de selectie aan de juiste gegevens uit het DataFrame if selected == 0: usageType = 'gastotalusage' p.title.text = 'Gasverbruik per minuut' elif selected == 1: usageType = 'tariff1totalusage' p.title.text = 'Stroomtarief 1 verbruik' elif selected == 2: usageType = 'tariff2totalusage' p.title.text = 'Stroomtarief 2 verbruik' elif selected == 3: usageType = 'powertotalusage' p.title.text = 'Stroomverbruik totaal' print('Update usageType: ' + str(usageType)) # update data new_src = make_dataset(df, usageType=usageType, start=start, stop=stop) src.data.update(new_src.data) def update_start_date(attr, old, new): print('New start date: ' + str(new)) global start start = new # update data new_src = make_dataset(df, usageType=usageType, start=new, stop=stop) src.data.update(new_src.data) def update_end_date(attr, old, new): print('New stop date: ' + str(new)) global stop stop = new # update data new_src = make_dataset(df, usageType=usageType, start=start, stop=new) src.data.update(new_src.data) radio_button_group = RadioButtonGroup( labels=["Gas", "Tarief 1", "Tarief 2", "Stroom totaal"], active=0) radio_button_group.on_change('active', update_radios) datepicker_start = DatePicker(title='Startdatum', min_date=date(2015, 1, 1), max_date=date.today()) datepicker_stop = DatePicker(title='Einddatum', min_date=date(2015, 1, 1), max_date=date.today()) datepicker_start.on_change('value', update_start_date) datepicker_stop.on_change('value', update_end_date) # initial execution src = make_dataset(df, 'gastotalusage') p = make_plot(src) # make a grid grid = gridplot([[p], [radio_button_group], [datepicker_start], [datepicker_stop]]) grid.sizing_mode = 'scale_width' tab = Panel(child=grid, title='Bar chart') print("barchart() uitgevoerd") return tab
if button_animation.label == '► Play': button_animation.label = '❚❚ Pause' callback_id = curdoc().add_periodic_callback(animate_update, 200) else: button_animation.label = '► Play' curdoc().remove_periodic_callback(callback_id) """ ----------- Set up widgets and events ----------- """ # Button to choose the feature to display in the map label_features = ["intranational", "international"] # labels of possible features button_choice = RadioButtonGroup(labels=["Intranational", "International"], active=0) button_choice.on_change('active', update_map) # As the RadioButton isn't implemented with a title option, we add a PreText object before it title_button_choice = PreText(text="Choose the type of flights to visualize", style={ 'font-size': '12pt', 'color': 'black', 'font-family': 'sans-serif' }) # Description for Slider slider_explanation = PreText(text="Slider per day", style={ 'font-size': '9pt', 'color': 'black', 'font-family': 'sans-serif' })
# initialize controls # slider for going though time time_slider = Slider(title="time", name='time', value=pde_settings.t_init, start=pde_settings.t_min, end=pde_settings.t_max, step=pde_settings.t_step) time_slider.on_change('value', time_change) # slider controlling spatial stepsize of the solver h_slider = Slider(title="spatial meshwidth", name='spatial meshwidth', value=pde_settings.h_init, start=pde_settings.h_min, end=pde_settings.h_max, step=pde_settings.h_step) h_slider.on_change('value', mesh_change) # slider controlling spatial stepsize of the solver k_slider = Slider(title="temporal meshwidth", name='temporal meshwidth', value=pde_settings.k_init, start=pde_settings.k_min, end=pde_settings.k_max, step=pde_settings.k_step) k_slider.on_change('value', mesh_change) # radiobuttons controlling pde type pde_type = RadioButtonGroup(labels=['Heat', 'Wave'], active=0) pde_type.on_change('active', pde_type_change) # radiobuttons controlling solver type solver_type = RadioButtonGroup(labels=['Explicit', 'Implicit'], active=0) solver_type.on_change('active', mesh_change) # text input for IC initial_condition = TextInput(value=pde_settings.IC_init, title="initial condition") initial_condition.on_change('value', initial_condition_change) # initialize plot toolset = "crosshair,pan,reset,resize,wheel_zoom,box_zoom" # Generate a figure container plot = Figure(plot_height=400, plot_width=400, tools=toolset, title="Time dependent PDEs", x_range=[pde_settings.x_min, pde_settings.x_max],