class range_slider(): def __init__(self, widget_lst, label, start, end, step, callback_throttle, default): self.label = label self.start = start self.end = end self.step = step self.callback_throttle = callback_throttle self.default = default self.slider = None self.callback = None widget_lst.append(self) def initialize(self, widget_lst): self.slider = RangeSlider(start = self.start, end = self.end, value = self.default, step = self.step, title = self.label) widget_lst.append(self.slider) if self.callback is not None: self.slider.on_change('value', self.callback) def add_callback(self, callback): self.callback = callback if self.slider is not None: self.slider.on_change('value', self.callback) #May not keep that one def set_value(self, value): if self.slider is not None: self.slider.value = value self.default = value
def get_slider(desc, range, default=None): if default is None: default = range slider = RangeSlider( title=desc, start=range[0], end=range[1], value=default, step=0.1) slider.on_change('value', on_filter_change) return slider
def heatmap_tab(controls): # the list of control domains will be colorcoded for the heat map controls_domains=list(set((dataFrame[dataFrame['root']==True])['control_name'])) controls_domains.sort() controls_colors = Category20_16 controls_colors.sort() controls_selection = CheckboxGroup(labels=controls_domains, active = [0, 1]) range_select = RangeSlider(start = 0, end = 100, value = (80, 100), step = 10, title = 'Compliance % Range') def form_controls_dataset(controls_list, range_start = 80, range_end = 100): # Dataframe to hold information heatmap_df = pd.DataFrame(columns=['impact', 'frequency', 'control']) range_extent = range_end - range_start # Iterate through all the carriers for i, control_name in enumerate(controls_list): # Add to the overall dataframe heatmap_df = heatmap_df.append(temp_df) # Overall dataframe heatmap_df = heatmap_df.sort_values(['impact', 'frequency']) return ColumnDataSource(heatmap_df) controls_dataset = form_controls_dataset(list(controls_domains[0]), range_start = range_select.value[0], range_end = range_select.value[1]) def update(attr, old, new): controls_to_plot = [] for i in controls_selection.active: tmp_control_name=controls_selection.labels[i] tmp_control_id= new_controls_dataset = form_controls_dataset(controls_to_plot, range_start = range_select.value[0], range_end = range_select.value[1]) controls_dataset.data.update(new_controls_dataset.data) controls_selection.on_change('active', update) range_select.on_change('value', update) # return tab
class BasicFilter: number: int name: str gui_name: str full_range: List[int] step: int options: List def __init__(self, number: int, name: str, gui_name: str = "", full_range: List[int] = [0, 1], step: int = 1, options: List = []): self.number = number self.name = name self.gui_name = gui_name if gui_name else name self.full_range = full_range self.step = step self.options = options self.slider = RangeSlider(title=gui_name, start=full_range[0], end=full_range[1], step=step, value=full_range) self.slider.on_change("value", self.slider_function) def slider_function(self, attr, old, new): for opt in self.options: opt_limit = getattr(opt, self.name) if opt_limit["incompatible"]: if new[0] <= opt_limit["limit"] <= new[1]: opt_limit["incompatible"] = False opt.incompatibility_count -= 1 if opt.incompatibility_count == 0: opt.button.disabled = False else: if not (new[0] <= opt_limit["limit"] <= new[1]): opt_limit["incompatible"] = True opt.incompatibility_count += 1 opt.button.disabled = True
class range_slider(): def __init__(self, widget_lst, label, start, end, step, callback_throttle, default): self.widget_lst = widget_lst self.slider = None self.initialize(label, start, end, step, callback_throttle, default) def initialize(self, label, start, end, step, callback_throttle, default): self.slider = RangeSlider(start=start, end=end, range=default, step=step, title=label, callback_throttle=callback_throttle) self.widget_lst.append(self.slider) def add_callback(self, callback): self.slider.on_change('range', callback) def set_value(self, value): self.slider.range = value
def emergence_tab(company_data, founder_data, gis_data): company_data.loc[:, 'IncorporationDate'] = pd.to_datetime( company_data['IncorporationDate'], format='%d/%m/%Y') company_data.loc[:, 'year'] = company_data['IncorporationDate'].dt.to_period( 'Y').astype(str).astype(int) founder_data = founder_data.dropna() founder_data.loc[:, 'IncorporationDate'] = pd.to_datetime( founder_data['IncorporationDate'], format='%d/%m/%Y') founder_data.loc[:, 'year'] = founder_data['IncorporationDate'].dt.to_period( 'Y').astype(str).astype(int) founder_data.loc[:, 'age'] = founder_data['year'] - founder_data[ 'date_of_birth.year'] founder_data.loc[:, 'age'] = founder_data['age'].astype(int) ############################################## # def the function to prepare data for plots # ############################################## def make_dataset(plot_indicators, map_indicators, range_start=1980, range_end=2020, year_select=2020): # calculate the accumulated number of companies companies = company_data.copy() companies.loc[:, 'company_count'] = 1 companies = companies.loc[:, ['year', 'company_count']] companies = pd.DataFrame( companies.groupby(['year'])['company_count'].sum()) companies.loc[:, 'company_sum'] = companies['company_count'].cumsum() companies = companies.reset_index() data = companies.loc[:, ['year', 'company_sum']] # calculate the accumulated number of founders founders = founder_data.copy() founders.loc[:, 'founder_count'] = 1 founders = founders.loc[:, ['year', 'founder_count']] founders = pd.DataFrame( founders.groupby(['year'])['founder_count'].sum()) founders.loc[:, 'founder_sum'] = founders['founder_count'].cumsum() founders = founders.reset_index() data = pd.merge(data, founders, on='year') data = data.drop(columns=['founder_count'], axis=1) data = data[data['year'] >= range_start] data = data[data['year'] <= range_end] company_nodes = gis_data.copy() companies_1 = company_data.copy() companies_1 = companies_1.loc[:, ['RegAddress.PostCode', 'year']] companies_1 = companies_1[companies_1['year'] <= year_select] companies_1.loc[:, 'count'] = 1 companies_1 = pd.DataFrame( companies_1.groupby(['RegAddress.PostCode'])['count'].sum()) companies_1.loc[:, 'count'] = companies_1['count'].apply(np.log) companies_1.loc[:, 'count'] = companies_1['count'] * 30 companies_1 = companies_1.reset_index() companies_1.loc[:, 'RegAddress.PostCode'] = companies_1[ 'RegAddress.PostCode'].str.replace(' ', '') companies_1 = pd.merge(companies_1, company_nodes, left_on='RegAddress.PostCode', right_on='postcode') companies_1 = companies_1.loc[:, ['count', 'x', 'y']] founder_nodes = gis_data.copy() founder_1 = founder_data.copy() founder_1 = founder_1[founder_1['year'] <= year_select] founder_1.loc[:, 'count'] = 1 founder_1 = pd.DataFrame( founder_1.groupby(['RegAddress.PostCode'])['count'].sum()) founder_1.loc[:, 'count'] = founder_1['count'].apply(np.log) founder_1.loc[:, 'count'] = founder_1['count'] * 30 founder_1 = founder_1.reset_index() founder_1.loc[:, 'RegAddress.PostCode'] = founder_1[ 'RegAddress.PostCode'].str.replace(' ', '') founder_1 = pd.merge(founder_1, founder_nodes, left_on='RegAddress.PostCode', right_on='postcode') founder_1 = founder_1.loc[:, ['count', 'x', 'y']] if 'Num of Companies' not in plot_indicators: data.loc[:, 'company_sum'] = 'N/A' if 'Num of Founders' not in plot_indicators: data.loc[:, 'founder_sum'] = 'N/A' if map_indicators != 'Num of Companies': companies_1 = pd.DataFrame(columns=['count', 'x', 'y']) if map_indicators != 'Num of Founders': founder_1 = pd.DataFrame(columns=['count', 'x', 'y']) return (ColumnDataSource(data), ColumnDataSource(companies_1), ColumnDataSource(founder_1)) ############################# # plot the map of tech-city # ############################# def make_map(company_src, founder_src): # set the range of axises x_min = -12000 x_max = -8500 y_min = 6714000 y_max = 6716000 # define the map tiles to use tile_provider = get_provider(Vendors.CARTODBPOSITRON_RETINA) # plot the map p_map = figure(match_aspect=True, x_range=(x_min, x_max), y_range=(y_min, y_max), x_axis_type='mercator', y_axis_type='mercator', height=550) p_map.circle(x='x', y='y', color='darkslategray', source=company_src, size=10, fill_alpha=0.4, radius='count') p_map.circle(x='x', y='y', color='brown', source=founder_src, size=10, fill_alpha=0.4, radius='count') p_map.grid.visible = True # add map tiles map = p_map.add_tile(tile_provider) map.level = 'underlay' # formatting p_map.xaxis.visible = False p_map.yaxis.visible = False return p_map #################################### # define the function to plot data # #################################### def make_plot(src): p = figure(plot_width=1000, plot_height=550, x_axis_label='YEAR', y_axis_label='NUM') p.line(source=src, x='year', y='company_sum', color='darkslategray', legend_label='Num of Companies') p.line(source=src, x='year', y='founder_sum', color='brown', legend_label='Num of Founders') p.legend.location = 'top_left' hover = HoverTool(tooltips=[( 'Year', '@year'), ('Num of Companies', '@company_sum'), ('Num of Founders', '@founder_sum')]) p.add_tools(hover) return p ############################## # define the update function # ############################## def update(attr, old, new): plot_indicators = [ plot_indicator_selection.labels[i] for i in plot_indicator_selection.active ] map_indicators = map_indicator_selection.value new_src, new_company_src, new_founder_src = make_dataset( plot_indicators, map_indicators, range_start=range_select.value[0], range_end=range_select.value[1], year_select=year_select.value) src.data.update(new_src.data) company_src.data.update(new_company_src.data) founder_src.data.update(new_founder_src.data) # %% set controllers available_indicators = ['Num of Companies', 'Num of Founders'] plot_indicator_selection = CheckboxGroup(labels=available_indicators, active=[0, 1]) plot_indicator_selection.on_change('active', update) map_indicator_selection = Select(title="Choose Indicator", value='Num of Companies', options=available_indicators) map_indicator_selection.on_change('value', update) year_select = Slider(start=1980, end=2020, value=2020, step=1, title='Choose the year') year_select.on_change('value', update) range_select = RangeSlider(start=1980, end=2020, value=(1980, 2020), title='Time Period (year)') range_select.on_change('value', update) # %% initial indicators and data source initial_plot_indicators = [ plot_indicator_selection.labels[i] for i in plot_indicator_selection.active ] initial_map_indicator = map_indicator_selection.value src, company_src, founder_src = make_dataset( initial_plot_indicators, initial_map_indicator, range_start=range_select.value[0], range_end=range_select.value[1], year_select=year_select.value) p1 = make_plot(src) p2 = make_map(company_src, founder_src) # %% put controls in a single element plot_controls = WidgetBox(plot_indicator_selection, range_select) map_controls = WidgetBox(map_indicator_selection, year_select) # text description: title_1 = Div(text=''' <b>Emergence and Development of London Tech City</b> ''') description_1 = Div(text=''' <b>In 2008</b>, Tech City - also known as East London Tech City or Silicon Roundabout - came to prominence, with a variety of companies operating in the area, including Last.FM, Poke and Trampoline System. Being located in Inner East London, Tech City presents a large number of advantages for firms: a central location, cheap rents, accessibility to the rest of London and proximity to other like-minded tech companies. Moreover, Tech City offers many nightlife activaties, which is highly attractive to the type of workers and employees that digital and tech business want to retain - young, urban, creative and tech-savvy. ''') description_2 = Div(text=''' <b>In Nov 2010</b>, then UK Prime Minister made a speech to emphasize the importance of East London Tech firms in the UK Economy and set ambitious plans to further develop Tech City, promising a governmental support. The proposals involved building the profile of the area through government funding (£15 million in Government Funding) and support. Besides, Tech City Investment Organisation (TCIO) was created by the government aiming to make Tech City the leading digital hub in Europe. ''') description_3 = Div( text='<b>The Tech City strategy presented 3 clear objectives:</b>\n') description_4 = Div( text='1. Supporting the cluster of start-ups and small/midium-sized\ businesses(SMES);') description_5 = Div(text='2. Attracting large international investers;') description_6 = Div( text='3. Using this momentum to steer high-tech activity further east,\ including into a post-Games Olympic Park.') description_7 = Div(text=''' <b>In May 2011</b>, TweetDeck, a social media dashboard, was launched by Twitter and gave another boost to the already growing repulation of Tech City. ''') reference_1 = Div(text=''' <a href="https://www.mbymontcalm.co.uk/blog/history-behind-tech-city/ ">Reference 1</a> ''') reference_2 = Div(text=''' <a href="https://www.demos.co.uk/files/A_Tale_of_Tech_City_web.pdf ">Reference 2</a> ''') reference_3 = Div(text=''' <a href="https://www.gov.uk/government/speeches/east-end-tech-city-speech">Reference 3</a> ''') reference_4 = Div(text=''' <a href="https://olaonikoyi.medium.com/the-problems-at-east-london -tech-city-london-silicon-roundabout-d0bc2d4c7181">Reference 4</a> ''') title_2 = Div(text=''' <b>Data Visual</b> ''') description_8 = Div(text=''' The programme was a major success and resulted in an important multiplication of the number of tech companies operating in the region. In 2000, the number of companies in Tech City was 628. After Cameron's speech in 2011, the number of companies started increasing exponentially - indeed, the number of companies increased by 1204% between 2011 and 2020 (3,208 in 2011 vs. 41,841 in 2020). ''') # %% design the layout plot_layout = column(plot_controls, p1) map_layout = column(map_controls, p2) graph_layout = row(plot_layout, map_layout) layout = column(title_1, description_1, description_2, description_3, description_4, description_5, description_6, description_7, reference_1, reference_2, reference_3, reference_4, title_2, description_8, graph_layout) # %% make a tab with the layout tab = Panel(child=layout, title='Emergence of Tech-City') return tab
def load_page(experiment_df, experiment_db): ########## bokeh plots ########## # general plot tools plot_tools = 'wheel_zoom, pan, reset, save, hover' hover = HoverTool(tooltips=[("(x,y)", "($x, $y)")]) # progress curve plots global raw_source raw_source = ColumnDataSource(data=dict(x=[], y=[], yr=[], yfit=[])) global raw raw = figure(title="Initial Rate Fit", x_axis_label="Time", y_axis_label="Signal", plot_width=350, plot_height=300, tools=plot_tools) raw.circle('x', 'y', size=2, source=raw_source, color='gray', selection_color="black", alpha=0.6, nonselection_alpha=0.2, selection_alpha=0.6) raw.line('x', 'yfit', source=raw_source, color='red') global warning_source warning_source = ColumnDataSource(data=dict( x=[0], y=[0], t=[ 'Please enter transform equation! \nMust convert signal to [substrate] \nin Schnell-Mendoza mode (e.g. via \nx/6.22/0.45/0.001 for sample data). \nNote: this transform may need \nto be inverted through multiplying \nby -1 when analyzing experiments \nthat measure increasing product \nconcentration over time)' ])) global warning warning = raw.text(x='x', y='y', text='t', text_font_size='12pt', angle=0, source=warning_source) warning.visible = False global circles_source circles_source = ColumnDataSource( data=dict(x=[-.05, -.05, 1.6, 1.6], y=[0, 0.6, 0, 0.6])) global circles circles = raw.circle(x='x', y='y', alpha=0., source=circles_source) circles.visible = False global resi resi = figure(title="Initial Rate Fit Residuals", x_axis_label="Time", y_axis_label="Residual", plot_width=700, plot_height=200, tools='wheel_zoom,pan,reset') resi.yaxis.formatter = BasicTickFormatter(precision=2, use_scientific=True) resi.circle('x', 'yr', size=5, source=raw_source, color='grey', alpha=0.6) # model plot for titration experiments global model_data_source model_data_source = ColumnDataSource( data=dict(xt=[], yt=[], n=[], ct=[], et=[])) global model_plot_source model_plot_source = ColumnDataSource( data=dict(xp=[], yp=[], l=[], u=[], cp=[], ep=[])) global model_fit_source model_fit_source = ColumnDataSource(data=dict(x=[], y=[])) global varea_source varea_source = ColumnDataSource(data=dict(x=[], r1=[], r2=[])) global model model = figure(title='Model Fit', x_axis_label='Concentration', y_axis_label='Rate', plot_width=350, plot_height=300, tools=plot_tools) model.circle('xp', 'yp', size=8, source=model_plot_source, color='cp', alpha=0.6) model.add_layout( Whisker(source=model_plot_source, base='xp', upper='u', lower='l')) model.line('x', 'y', source=model_fit_source, line_width=3, color='black', alpha=0.8) model.varea('x', 'r1', 'r2', source=varea_source, color='grey', alpha=0.3) ########## bokeh widgets ########## # button for selecting progress curve fitting routine global fit_button fit_button = RadioButtonGroup(labels=[ 'Maximize Slope Magnitude', 'Linear Fit', 'Logarithmic Fit', 'Schnell-Mendoza' ], active=0, width=375) fit_button.on_change('active', widget_callback) # button for selecting progress curve fitting routine global scalex_box scalex_box = CheckboxButtonGroup( labels=["transform x-axis to Log10 scale"], active=[]) scalex_box.on_change('active', widget_callback) # dropdown menu for selecting titration experiment model global model_select model_select = Select( title='Choose Model', value='Michaelis-Menten', options=['Michaelis-Menten', 'pEC50/pIC50', 'High-Throughput Screen'], width=350) model_select.on_change('value', widget_callback) # dropdown menu for selecting blank sample to subtract from remaining titration samples global subtract_select subtract_select = Select(title='Select Blank Sample for Subtraction', value='', options=list(experiment_df)[1:] + [''], width=350) subtract_select.on_change('value', widget_callback) # dropdown menu for selecting titration sample to plot in current view global sample_select sample_select = Select(title='Y Axis Sample', value=list(experiment_df)[-1], options=list(experiment_df)[1:], width=350) sample_select.on_change('value', sample_callback) # text input box for transforming slopes to rates global transform_input transform_input = TextInput(value='', title="Enter Transform Equation", width=350) transform_input.on_change('value', widget_callback) # text input box for setting delay time in logarithmic progress curve fitting global offset_input offset_input = TextInput(value='', title="Enter Time Between Mixing and First Read", width=350) offset_input.on_change('value', widget_callback) # text input boxes for fixing EC/IC50 parameters global bottom_fix bottom_fix = TextInput(value='', title="Fix pIC50/pEC50 Bottom") bottom_fix.on_change('value', widget_callback) global top_fix top_fix = TextInput(value='', title="Fix pIC50/pEC50 Top") top_fix.on_change('value', widget_callback) global slope_fix slope_fix = TextInput(value='', title="Fix pIC50/pEC50 Hill Slope") slope_fix.on_change('value', widget_callback) # text input boxes for progress curve xrange selection global start_time start_time = TextInput(value=str( experiment_df[list(experiment_df)[0]].values[0]), title="Enter Start Time") global end_time end_time = TextInput(value=str( experiment_df[list(experiment_df)[0]].values[-1]), title='Enter End Time') start_time.on_change('value', xbox_callback) end_time.on_change('value', xbox_callback) # range slider to select threshold for hit detection in HTS mode global threshold_slider threshold_slider = Slider(start=0, end=5, value=2, step=0.1, title='HTS Hit Threshold (Standard Deviation)', width=350) threshold_slider.on_change('value', threshold_callback) # range slider to update plots according to progress cuve xrange selection xmin = experiment_df[experiment_df.columns[0]].values[0] xmax = experiment_df[experiment_df.columns[0]].values[-1] global range_slider range_slider = RangeSlider( start=xmin, end=xmax, value=(xmin, xmax), step=experiment_df[experiment_df.columns[0]].values[1] - xmin, title='Fine Tune X-Axis Range', width=650) range_slider.on_change('value', slider_callback) # button to upload local data file global file_source file_source = ColumnDataSource(data=dict(file_contents=[], file_name=[])) file_source.on_change('data', file_callback) try: output_filename = file_source.data['file_name'] + '-out.csv' except: output_filename = 'output.csv' global upload_button upload_button = Button(label="Upload Local File", button_type="success", width=350) upload_button.callback = CustomJS(args=dict(file_source=file_source), code=open( join(dirname(__file__), "upload.js")).read()) # table containing rate fits and errors template = """ <div style="background:<%=ct%>"; color="white";> <%= value %></div> """ formatter = HTMLTemplateFormatter(template=template) columns = [ TableColumn(field='n', title='Sample'), TableColumn(field='yt', title='Slope (Initial Rate)', formatter=formatter), TableColumn(field='et', title='Std. Error') ] global rate_table rate_table = DataTable(source=model_data_source, columns=columns, width=350, height=250, selectable=True, editable=True) # tables containing model fits and errors global mm_source mm_source = ColumnDataSource(dict(label=[], Km=[], Vmax=[])) columns = [ TableColumn(field='label', title=''), TableColumn(field='Vmax', title='Vmax'), TableColumn(field='Km', title='Km') ] global mm_table mm_table = DataTable(source=mm_source, columns=columns, width=350, height=75, selectable=True, editable=True) global ic_source ic_source = ColumnDataSource( dict(label=[], Bottom=[], Top=[], Slope=[], p50=[])) columns = [ TableColumn(field='label', title=''), TableColumn(field='Bottom', title='Bottom'), TableColumn(field='Top', title='Top'), TableColumn(field='Slope', title='Slope'), TableColumn(field='p50', title='pEC/IC50') ] global ic_table ic_table = DataTable(source=ic_source, columns=columns, width=350, height=75, selectable=True, editable=True) # button for copying rate data table to clipboard global copy_button copy_button = Button(label="Copy Table to Clipboard", button_type="primary", width=350) copy_button.callback = CustomJS(args=dict(source=model_data_source), code=open( join(dirname(__file__), "copy.js")).read()) # button for downloading rate data table to local csv file global download_button download_button = Button(label="Download Table to CSV", button_type="primary", width=350) download_button.callback = CustomJS(args=dict(source=model_data_source, file_name=output_filename), code=open( join(dirname(__file__), "download.js")).read()) ########## document formatting ######### desc = Div(text=open(join(dirname(__file__), "description.html")).read(), width=1400) advanced = Div( text="""<strong>Advanced Settings for \npEC/IC50 Analysis</strong>""") widgets = widgetbox(model_select, sample_select, subtract_select, transform_input, offset_input, advanced, scalex_box, bottom_fix, top_fix, slope_fix) table = widgetbox(rate_table) main_row = row( column(upload_button, widgets), column(fit_button, row(raw, model), resi, row(start_time, end_time), range_slider), column(download_button, copy_button, table, mm_table, ic_table, threshold_slider)) sizing_mode = 'scale_width' l = layout([[desc], [main_row]], sizing_mode=sizing_mode) update() curdoc().clear() curdoc().add_root(l) curdoc().title = "ICEKAT"
print('\n', rng_st) st = rng_st end = rng_end # Create new ColumnDataSource # new_src = make_dataset(range_start = range_start, # range_end = range_end, # bin_width = bin_width) # Update the data on the plot source.data['x'] = data_model['time'][st:end] print(select_y.value) source.data['y'] = data_model[select_y.value][st:end] # Update the plot when the value is changed range_select.on_change('value', update) # start = Slider(title="start", value=data_model['time'][0], start=data_model['time'][0], # end=data_model['time'][-1], step=data_model['time'][1]-data_model['time'][0]) # end = Slider(title="end", value=data_model['time'][-1], start=data_model['time'][0], # end=data_model['time'][-1], step=data_model['time'][1]-data_model['time'][0]) # def update_range(attrname, old, new): # # Get the current slider values # a = start.value # b = end.value # ai = np.where(data_model['time']== a) # bi = np.where(data_model['time']== b) # # Generate the new ranges
NIGHTS = FILTER_PROPERTIES[c.MINIMUM_NIGHTS] NIGHTS_SLIDER = Slider(start=NIGHTS[0], end=NIGHTS[1], value=NIGHTS[0], step=1, title='Nights') NIGHTS_SLIDER.on_change(c.VALUE, update_data) # Range Slider Widget PRICE = FILTER_PROPERTIES[c.PRICE] PRICE_SLIDER = RangeSlider(start=PRICE[0], end=PRICE[1], value=(PRICE[0], PRICE[1]), step=50, title='Nightly Price') PRICE_SLIDER.on_change(c.VALUE, update_data) # Multi Select Widgets AMENITIES_SELECT = MultiSelect(title='Amenities:', value=[], options=FILTER_PROPERTIES[c.AMENITIES]) AMENITIES_SELECT.on_change(c.VALUE, update_data) PROPERTY_TYPE_SELECT = MultiSelect(title='Property Type:', value=[], options=FILTER_PROPERTIES[c.PT]) PROPERTY_TYPE_SELECT.on_change(c.VALUE, update_data) NEIGHBOURHOOD_SELECT = MultiSelect(title='Neighbourhood:', value=[], options=FILTER_PROPERTIES[c.NC])
var_slider = Slider(start=100, end=2000, value=1000, step=100, title="The # most hottt songs") var_slider.on_change('value', update) #checkbox_year = CheckboxGroup(labels=["Show songs with missing year"], active=[]) #checkbox_year.on_change('active', update) year_slider = RangeSlider(start=1950, end=2010, value=(1950, 2010), step=5, title="year") year_slider.on_change('value', update) dico_fig2 = { 'year distribution': 'year', 'duration distribution': 'duration', 'loudness distribution': 'loudness', 'tempo distribution': 'tempo', 'artist hotttnesss distribution': 'artist_hotttnesss', 'artist_familiarity': 'artist_familiarity' } fig2 = Select(title='Right figure', value='genre pie chart', options=[ 'genre pie chart', 'year distribution', 'duration distribution', 'loudness distribution',
def histogram_tab(df_avgs_w_l): def make_dataset(conf_list, range_start=0, range_end=1, bin_width=1 / 20, years=(2003, 2004)): by_conf = pd.DataFrame(columns=[ 'left', 'right', 'f_interval', 'count', 'year', 'name', 'color' ]) df = df_avgs_w_l[(df_avgs_w_l['Season'] >= years[0]) & (df_avgs_w_l['Season'] <= years[1])] # Iterate through all the conferences for i, conf_name in enumerate(conf_list): # Subset to the conference subset = df[df['ConfName'] == conf_name] # Create a histogram with 5 minute bins arr_hist, edges = np.histogram(subset['rpi'], bins=int(20), range=[.3, .75]) # Divide the counts by the total to get a proportion # arr_df = pd.DataFrame({'proportion': arr_hist / np.sum(arr_hist), 'left': edges[:-1], 'right': edges[1:] }) arr_df = pd.DataFrame({ 'count': arr_hist, 'left': edges[:-1], 'right': edges[1:] }) # Format the proportion # arr_df['f_proportion'] = ['%0.5f' % proportion for proportion in arr_df['proportion']] # Format the interval arr_df['f_interval'] = [ '%0.3f to %0.3f Rating' % (left, right) for left, right in zip(arr_df['left'], arr_df['right']) ] # Assign the carrier for labels arr_df['name'] = conf_name # Color each carrier differently arr_df['color'] = Category20_16[i] # Add to the overall dataframe by_conf = by_conf.append(arr_df) # Overall dataframe by_conf = by_conf.sort_values(['name', 'left']) return ColumnDataSource(by_conf) def style(p): # Title p.title.align = 'center' p.title.text_font_size = '20pt' p.title.text_font = 'serif' # Axis titles p.xaxis.axis_label_text_font_size = '14pt' p.xaxis.axis_label_text_font_style = 'bold' p.yaxis.axis_label_text_font_size = '14pt' p.yaxis.axis_label_text_font_style = 'bold' # Tick labels p.xaxis.major_label_text_font_size = '12pt' p.yaxis.major_label_text_font_size = '12pt' return p def make_plot(src): # Create the figure p = figure(plot_height=600, plot_width=800, title='Histogram of RPI by Conference', x_axis_label='RPI', y_axis_label='Count') # Add the quad glpyh with the source by conference p.quad(bottom=0, left='left', right='right', top='count', color='color', legend='name', source=src, fill_alpha=0.8, hover_fill_alpha=1.0, hover_fill_color='color', line_color='black') # Create the hover tool hover = HoverTool(tooltips=[('Conference', '@name'), ('Number of Teams', '@count'), ('RPI', '@f_interval')], mode='vline') # Add styling and hover tool p.add_tools(hover) p.legend.click_policy = 'hide' # Styling p = style(p) return p def update(attr, old, new): # Get the list of carriers for the graph confs_to_plot = [ conf_selection.labels[i] for i in conf_selection.active ] years = (year_select.value[0], year_select.value[1]) # Make a new dataset based on the selected carriers and the # make_dataset function defined earlier new_src = make_dataset(confs_to_plot, range_start=.3, range_end=.75, bin_width=1 / 20, years=years) # Update the source used the quad glpyhs src.data.update(new_src.data) conf_selection = CheckboxGroup(labels=list( df_avgs_w_l['ConfName'].unique()), active=[0]) conf_selection.on_change('active', update) # Slider to select the binwidth, value is selected number year_select = RangeSlider(start=2003, end=2019, step=1, value=[2003, 2004], title='Year') # Update the plot when the value is changed year_select.on_change('value', update) controls = WidgetBox(year_select, conf_selection) initial_confs = [conf_selection.labels[i] for i in conf_selection.active] src = make_dataset(initial_confs, range_start=.3, range_end=.75, bin_width=1 / 20) p = make_plot(src) layout = row(controls, p) tab = Panel(child=layout, title='Histogram') return tab
# CheckboxGroup to select carrier to display carrier_selection = CheckboxGroup(labels=available_carriers, active = [0, 1]) carrier_selection.on_change('active', update) # Slider to select width of bin binwidth_select = Slider(start = 1, end = 30, step = 1, value = 5, title = 'Delay Width (min)') binwidth_select.on_change('value', update) # RangeSlider control to select start and end of plotted delays range_select = RangeSlider(start = -60, end = 180, value = (-60, 120), step = 5, title = 'Delay Range (min)') range_select.on_change('value', update) # Find the initially selected carrieres initial_carriers = [carrier_selection.labels[i] for i in carrier_selection.active] src = make_dataset(initial_carriers, range_start = range_select.value[0], range_end = range_select.value[1], bin_width = binwidth_select.value) p = make_plot(src) # Put controls in a single element controls = WidgetBox(carrier_selection, binwidth_select, range_select)
def tab_visualize(csv): csv_original = csv.copy() csv_modified = csv.copy() target_csv = {'csv': csv_original} source_length = target_csv['csv'].shape[0] table_source = ColumnDataSource(target_csv['csv']) table_columns = [ TableColumn(field=col, title=col) for col in list(target_csv['csv'].columns) ] table_original = DataTable(source=table_source, columns=table_columns, width=1550, height=250, fit_columns=False, name="Original") g = target_csv['csv'].columns.to_series().groupby( target_csv['csv'].dtypes).groups g_list = list(g.keys()) float_list = [] rest_list = [] for l in g_list: if ('float' or 'int' in str(l)): float_list += list(g[l]) else: rest_list += list(g[l]) print(float_list) print(rest_list) def make_dataset(col_list, range_start, range_end): xs = [] ys = [] labels = [] colors = [] target_length = target_csv['csv'].shape[0] end = range_end if (range_end < target_length) else target_length target_data = target_csv['csv'][col_list + rest_list].iloc[range_start:end] target_x = list(np.arange(target_data.shape[0]) + range_start) for col, i in zip(col_list, range(len(col_list))): y = list(target_data[col].values) xs.append(target_x) ys.append(y) labels.append(col) colors.append(line_colors[i]) new_src = ColumnDataSource(data={ 'x': xs, 'y': ys, 'label': labels, 'colors': colors }) return new_src def make_plot(src): p = figure(plot_width=1300, plot_height=400, title='Raw data', x_axis_label='Index', y_axis_label='Sensor value') p.multi_line('x', 'y', legend='label', color='colors', line_width=1, source=src) tools = HoverTool() TOOLTIPS = [("", ""), ("", "")] return p def update(attr, old, new): column_to_plot = select_column.value new_src = make_dataset(column_to_plot, range_select.value[0], range_select.value[1]) src.data.update(new_src.data) line_colors = Category20_16 line_colors.sort() select_column = MultiSelect(title="Column visualization", value=float_list, options=float_list) select_column.on_change("value", update) range_select = RangeSlider(start=0, end=source_length, value=(0, int(source_length / 100)), step=1, title='Sensor range') range_select.on_change('value', update) src = make_dataset([float_list[0]], range_select.value[0], range_select.value[1]) p = make_plot(src) select_normalize = Select(title="Select normalize transformation", options=["-", "Min-Max", "Z normalize", "Raw"]) button_get_normal = Button(label="Transform") def normal_handler(): print("Normalize") # cols_to_normalize = float_list cols_to_normalize = select_transform.value if (select_normalize.value == "Min-Max"): scaler = preprocessing.MinMaxScaler() csv_modified[cols_to_normalize] = scaler.fit_transform( X=csv_original[cols_to_normalize].values) target_csv['csv'] = csv_modified table_source.data = ColumnDataSource(target_csv['csv']).data csv[cols_to_normalize] = target_csv['csv'][cols_to_normalize] print("Min Max Mormalize") elif (select_normalize.value == "Z normalize"): scaler = preprocessing.StandardScaler() csv_modified[cols_to_normalize] = scaler.fit_transform( X=csv_original[cols_to_normalize].values) target_csv['csv'] = csv_modified table_source.data = ColumnDataSource(target_csv['csv']).data csv[cols_to_normalize] = target_csv['csv'][cols_to_normalize] print("Z normalize") elif (select_normalize.value == "Raw"): csv_modified[cols_to_normalize] = csv_original[cols_to_normalize] target_csv['csv'] = csv_modified table_source.data = ColumnDataSource(target_csv['csv']).data csv[cols_to_normalize] = target_csv['csv'][cols_to_normalize] print("Raw") button_get_normal.on_click(normal_handler) select_transform = MultiSelect(title="Select columns for transformation", value=list(target_csv['csv'].columns), options=list(target_csv['csv'].columns)) controls = WidgetBox(select_normalize, select_transform, button_get_normal, select_column, range_select) layout = Column(Row(table_original), Row(controls, p)) tab = Panel(child=layout, title='Visualization') return tab
source = ColumnDataSource(data=dict(year=df.Year, population=df.Population,marriagep1000=df.Marriages_per_1000,divorcep1000=df.Divorces_per_1000)) plot_figure = figure(title='Range Slider',plot_height=450, plot_width=600, tools="save,reset", toolbar_location="below") plot_figure.scatter('divorcep1000', 'marriagep1000', size=5, source=source) plot_figure.xaxis.axis_label='Divorces Per 1000' plot_figure.yaxis.axis_label='Marriages Per 1000' range_slider = RangeSlider(start=1867, end=2011, value=(1867,2011), step=1, title="Filter Year") def slider_change(attr,old,new): slider_value=range_slider.value ##Getting slider value slider_low_range=slider_value[0] slider_high_range=slider_value[1] filtered_df=df[(df['Year'] >= slider_low_range) & (df['Year']<=slider_high_range)] source.data=dict(year=filtered_df.Year, population=filtered_df.Population, marriagep1000=filtered_df.Marriages_per_1000,divorcep1000=filtered_df.Divorces_per_1000) range_slider.on_change('value',slider_change) layout=row(range_slider, plot_figure) curdoc().add_root(layout) curdoc().title = "Range Slider Bokeh Server"
def histogram_tab(flights): # Function to make a dataset for histogram based on a list of carriers # a minimum delay, maximum delay, and histogram bin width def make_dataset(carrier_list, range_start = -60, range_end = 120, bin_width = 5): # Dataframe to hold information by_carrier = pd.DataFrame(columns=['proportion', 'left', 'right', 'f_proportion', 'f_interval', 'name', 'color']) range_extent = range_end - range_start # Iterate through all the carriers for i, carrier_name in enumerate(carrier_list): # Subset to the carrier subset = flights[flights['name'] == carrier_name] # Create a histogram with 5 minute bins arr_hist, edges = np.histogram(subset['arr_delay'], bins = int(range_extent / bin_width), range = [range_start, range_end]) # Divide the counts by the total to get a proportion arr_df = pd.DataFrame({'proportion': arr_hist / np.sum(arr_hist), 'left': edges[:-1], 'right': edges[1:] }) # Format the proportion arr_df['f_proportion'] = ['%0.5f' % proportion for proportion in arr_df['proportion']] # Format the interval arr_df['f_interval'] = ['%d to %d minutes' % (left, right) for left, right in zip(arr_df['left'], arr_df['right'])] # Assign the carrier for labels arr_df['name'] = carrier_name # Color each carrier differently arr_df['color'] = Category20_16[i] # Add to the overall dataframe by_carrier = by_carrier.append(arr_df) # Overall dataframe by_carrier = by_carrier.sort_values(['name', 'left']) return ColumnDataSource(by_carrier) def style(p): # Title p.title.align = 'center' p.title.text_font_size = '20pt' p.title.text_font = 'serif' # Axis titles p.xaxis.axis_label_text_font_size = '14pt' p.xaxis.axis_label_text_font_style = 'bold' p.yaxis.axis_label_text_font_size = '14pt' p.yaxis.axis_label_text_font_style = 'bold' # Tick labels p.xaxis.major_label_text_font_size = '12pt' p.yaxis.major_label_text_font_size = '12pt' return p def make_plot(src): # Blank plot with correct labels p = figure(plot_width = 700, plot_height = 700, title = 'Histogram of Arrival Delays by Airline', x_axis_label = 'Delay (min)', y_axis_label = 'Proportion') # Quad glyphs to create a histogram p.quad(source = src, bottom = 0, top = 'proportion', left = 'left', right = 'right', color = 'color', fill_alpha = 0.7, hover_fill_color = 'color', legend = 'name', hover_fill_alpha = 1.0, line_color = 'black') # Hover tool with vline mode hover = HoverTool(tooltips=[('Carrier', '@name'), ('Delay', '@f_interval'), ('Proportion', '@f_proportion')], mode='vline') p.add_tools(hover) # Styling p = style(p) return p def update(attr, old, new): carriers_to_plot = [carrier_selection.labels[i] for i in carrier_selection.active] new_src = make_dataset(carriers_to_plot, range_start = range_select.value[0], range_end = range_select.value[1], bin_width = binwidth_select.value) src.data.update(new_src.data) # Carriers and colors available_carriers = list(set(flights['name'])) available_carriers.sort() airline_colors = Category20_16 airline_colors.sort() carrier_selection = CheckboxGroup(labels=available_carriers, active = [0, 1]) carrier_selection.on_change('active', update) binwidth_select = Slider(start = 1, end = 30, step = 1, value = 5, title = 'Bin Width (min)') binwidth_select.on_change('value', update) range_select = RangeSlider(start = -60, end = 180, value = (-60, 120), step = 5, title = 'Range of Delays (min)') range_select.on_change('value', update) # Initial carriers and data source initial_carriers = [carrier_selection.labels[i] for i in carrier_selection.active] src = make_dataset(initial_carriers, range_start = range_select.value[0], range_end = range_select.value[1], bin_width = binwidth_select.value) p = make_plot(src) # Put controls in a single element controls = WidgetBox(carrier_selection, binwidth_select, range_select) # Create a row layout layout = row(controls, p) # Make a tab with the layout tab = Panel(child=layout, title = 'Histogram') return tab
sc_renderers = plot_sc_data(team_objs, sc_sources, line_colors) compile_expected_wins(league_obj, team_objs, weeks, owner_to_idx, num_teams) ew_sources = get_ew_sources(weeks, team_objs, owners, week_num, num_teams) expected_wins_table = initialize_ew_table(team_objs, week_num, num_teams) table_wrap = column(children=[expected_wins_table]) ew_renderers = plot_ew_data(team_objs, ew_sources, line_colors) # register callback handlers to respond to changes in widget values lg_id_input.on_change('value', league_id_handler) lg_id_input.js_on_change('value', ga_view_callback) week_slider.on_change('value', week_slider_handler) team1_dd.on_change('value', team1_select_handler) team2_dd.on_change('value', team2_select_handler) comp_button.on_click(helper_handler) year_input.on_change('value', season_handler) # arrange layout tab1 = Panel(child=plot1_wrap, title='Scores') tab2 = Panel(child=plot2_wrap, title='Expected Wins') tab3 = Panel(child=table_wrap, title='Summary') figures = Tabs(tabs=[tab1, tab2, tab3], width=500) compare_widgets = column(team1_dd, team2_dd, comp_button) wid_spac1 = Spacer(height=30)
def density_tab(flights): # Dataset for density plot based on carriers, range of delays, # and bandwidth for density estimation def make_dataset(carrier_list, range_start, range_end, bandwidth): xs = [] ys = [] colors = [] labels = [] for i, carrier in enumerate(carrier_list): subset = flights[flights['name'] == carrier] subset = subset[subset['arr_delay'].between(range_start, range_end)] kde = gaussian_kde(subset['arr_delay'], bw_method=bandwidth) # Evenly space x values x = np.linspace(range_start, range_end, 100) # Evaluate pdf at every value of x y = kde.pdf(x) # Append the values to plot xs.append(list(x)) ys.append(list(y)) # Append the colors and label colors.append(airline_colors[i]) labels.append(carrier) new_src = ColumnDataSource(data={'x': xs, 'y': ys, 'color': colors, 'label': labels}) return new_src def make_plot(src): p = figure(plot_width = 700, plot_height = 700, title = 'Density Plot of Arrival Delays by Airline', x_axis_label = 'Delay (min)', y_axis_label = 'Density') p.multi_line('x', 'y', color = 'color', legend = 'label', line_width = 3, source = src) # Hover tool with next line policy hover = HoverTool(tooltips=[('Carrier', '@label'), ('Delay', '$x'), ('Density', '$y')], line_policy = 'next') # Add the hover tool and styling p.add_tools(hover) p = style(p) return p def update(attr, old, new): # List of carriers to plot carriers_to_plot = [carrier_selection.labels[i] for i in carrier_selection.active] # If no bandwidth is selected, use the default value if bandwidth_choose.active == []: bandwidth = None # If the bandwidth select is activated, use the specified bandwith else: bandwidth = bandwidth_select.value new_src = make_dataset(carriers_to_plot, range_start = range_select.value[0], range_end = range_select.value[1], bandwidth = bandwidth) src.data.update(new_src.data) def style(p): # Title p.title.align = 'center' p.title.text_font_size = '20pt' p.title.text_font = 'serif' # Axis titles p.xaxis.axis_label_text_font_size = '14pt' p.xaxis.axis_label_text_font_style = 'bold' p.yaxis.axis_label_text_font_size = '14pt' p.yaxis.axis_label_text_font_style = 'bold' # Tick labels p.xaxis.major_label_text_font_size = '12pt' p.yaxis.major_label_text_font_size = '12pt' return p # Carriers and colors available_carriers = list(set(flights['name'])) available_carriers.sort() airline_colors = Category20_16 airline_colors.sort() # Carriers to plot carrier_selection = CheckboxGroup(labels=available_carriers, active = [0, 1]) carrier_selection.on_change('active', update) range_select = RangeSlider(start = -60, end = 180, value = (-60, 120), step = 5, title = 'Range of Delays (min)') range_select.on_change('value', update) # Initial carriers and data source initial_carriers = [carrier_selection.labels[i] for i in carrier_selection.active] # Bandwidth of kernel bandwidth_select = Slider(start = 0.1, end = 5, step = 0.1, value = 0.5, title = 'Bandwidth for Density Plot') bandwidth_select.on_change('value', update) # Whether to set the bandwidth or have it done automatically bandwidth_choose = CheckboxButtonGroup( labels=['Choose Bandwidth (Else Auto)'], active = []) bandwidth_choose.on_change('active', update) # Make the density data source src = make_dataset(initial_carriers, range_start = range_select.value[0], range_end = range_select.value[1], bandwidth = bandwidth_select.value) # Make the density plot p = make_plot(src) # Add style to the plot p = style(p) # Put controls in a single element controls = WidgetBox(carrier_selection, range_select, bandwidth_select, bandwidth_choose) # Create a row layout layout = row(controls, p) # Make a tab with the layout tab = Panel(child=layout, title = 'Density Plot') return tab
def recommender_tab_advanced(recommender): def make_div_list(textlist, max_lines, fmt_str="""%s""", **attribs): """create a list of divs containing text to display""" divs = [] for i in range(max_lines): if len(textlist) > i: divs.append(Div(text=fmt_str % (textlist[i]), **attribs)) else: divs.append(Div(text=fmt_str % (' '), **attribs)) return divs def make_rec_list(titles, max_lines): """create a recommendation list of games, with a thumbnail, game title, info and Amazon buy links""" global games_by_title fmt_str1 = """ <div class="rec-post-container"> <div class="rec-post-thumb"><img src="%s" /></div> <div class="rec-post-content"> <h3 class="rec-post-title">%s<br> <a href="%s" target="_blank">Info</a><span> </span> <a href="%s" target="_blank">Buy on Amazon</a> </h3> </div> </div>""" fmt_str2 = """""" divs = [] for i in range(max_lines): # there is a title available for this list slot if len(titles) > i: divs.append( Div(text=fmt_str1 % (games_by_title['pic_url'].loc[titles[i]], titles[i], 'https://boardgamegeek.com/boardgame/' + str(games_by_title['id'].loc[titles[i]]), 'https://www.amazon.com/s?k=' + titles[i].replace(' ', '+') + '&i=toys-and-games'))) # no title, so fill with blank else: divs.append(Div(text=fmt_str2)) return divs # update the 'liked games' list UI elements def update_liked_list(titlelist): global max_liked ctl_liked_games.children = make_div_list(titlelist, max_liked, fmt_str=liked_list_fmt, render_as_text=False) # update the 'recommended games' list UI elements def update_recommended_list(titlelist): global n_recommendations ctl_recommended_games.children = make_rec_list(titlelist, n_recommendations) # called when a control widget is changed def update_filters(attr, old, new): global category_includes, mechanics_includes global category_excludes, mechanics_excludes category_includes = [ ctl_category_selection1.labels[i] for i in ctl_category_selection1.active ] category_includes += [ ctl_category_selection2.labels[i] for i in ctl_category_selection2.active ] mechanics_includes = [ ctl_mechanics_selection1.labels[i] for i in ctl_mechanics_selection1.active ] mechanics_includes += [ ctl_mechanics_selection2.labels[i] for i in ctl_mechanics_selection2.active ] # NOTE: this will need to be changed if I ever implement exclude selections! if ctl_include_expansions.active: category_excludes = [] else: category_excludes = ['Expansion for Base-game'] # called when a control widget is changed def update_preflist(attr, old, new): global liked_games liked_games.append(ctl_game_entry.value) liked_games = list(filter(None, set(liked_games))) # get control values update_liked_list(liked_games) ctl_game_entry.value = '' # reset preferred games list def reset_preferred_games(): global liked_games liked_games = [] update_liked_list(liked_games) # recommend some games def recommend_games(): global liked_games, recommended_games global games_all, n_recommendations, title_list global category_includes, mechanics_includes # get game IDs for titles liked_ids = recommender.get_item_title_id(liked_games) # select games to search from based on filters: recommended_games = recommender.recommend_items_by_pref_list( liked_ids, num2rec=n_recommendations, weightrange=ctl_game_weight.value, minrating=ctl_game_min_rating.value, categories_include=category_includes, categories_exclude=category_excludes, mechanics_include=mechanics_includes, mechanics_exclude=mechanics_excludes) # show the recommended games update_recommended_list(recommended_games) # NOTE: I'm using globals because I'm running into variable scope # problems with the bokeh handlers. Easiest to declare globals global liked_games, recommended_games, games_all global n_recommendations, max_liked, title_list, title_list_lower global category_includes, mechanics_includes global category_excludes, mechanics_excludes global games_by_title # layout params n_recommendations = 10 max_liked = 8 num_check_options = 20 # Format to use for liked list. # This needs to be changed to work like rec list liked_list_fmt = """<div style="font-size : 14pt; line-height:14pt;">%s</div>""" # variables used by the tab games_all = recommender.item_data # use all games for search liked_games = [] recommended_games = [] weight_range = [1, 5] category_includes = [] mechanics_includes = [] category_excludes = [] mechanics_excludes = [] # list of all game titles title_list = games_all['name'] title_list_lower = [s.lower() for s in title_list] games_by_title = recommender.item_data.set_index('name') # preferred game entry text control ctl_game_entry = AutocompleteInput(completions=list(title_list) + list(title_list_lower), min_characters=1, title='Enter some game names you like:') ctl_game_entry.on_change('value', update_preflist) # reset liked game list button ctl_reset_prefs = Button(label='Reset game list', width_policy='min', align='end') ctl_reset_prefs.on_click(reset_preferred_games) # liked list title ctl_liked_list_title = Div( text= """<div style="font-size : 18pt; line-height:16pt;">Games you like:</div>""" ) # liked game entries ctl_liked_games = WidgetBox( children=make_div_list(liked_games, max_liked, fmt_str=liked_list_fmt)) # recommended list title ctl_recommended_list_title = Div( text= """<div style="font-size : 18pt; line-height:16pt;">Games we recommend:</div>""" ) # recommended games list widget ctl_recommended_games = WidgetBox( children=make_rec_list(recommended_games, n_recommendations)) # Recommend games button ctl_recommend = Button(label='Recommend some games!', width_policy='min', align='center') ctl_recommend.on_click(recommend_games) # game weight slider ctl_game_weight = RangeSlider( start=1, end=5, value=(1, 5), step=.1, title='Game weight range', width_policy='min', ) ctl_game_weight.on_change('value', update_filters) # min game rating slider ctl_game_min_rating = Slider(start=1, end=10, value=7, step=.1, title='Minimum average rating', width_policy='min') ctl_game_min_rating.on_change('value', update_filters) # collect all category and mechanics labels from recommender data categories, mechanics = recommender.get_categories_and_mechanics() # game category selection category_list = ['Any category'] + list(categories['tag'].values) ctl_category_selection1 = CheckboxGroup( labels=category_list[:int(num_check_options / 2)], width_policy='min', active=[0]) ctl_category_selection1.on_change('active', update_filters) ctl_category_selection2 = CheckboxGroup( labels=category_list[int(num_check_options / 2):num_check_options], width_policy='min') ctl_category_selection2.on_change('active', update_filters) # game mechanism checkbox group mechanics_list = ['Any mechanism'] + list(mechanics['tag'].values) ctl_mechanics_selection1 = CheckboxGroup( labels=mechanics_list[:int(num_check_options / 2)], width_policy='min', active=[0]) ctl_mechanics_selection1.on_change('active', update_filters) ctl_mechanics_selection2 = CheckboxGroup( labels=mechanics_list[int(num_check_options / 2):num_check_options], width_policy='min') ctl_mechanics_selection2.on_change('active', update_filters) # select whether to include expansions ctl_include_expansions = CheckboxGroup(labels=['Include game expansions'], width_policy='min') ctl_include_expansions.on_change('active', update_filters) # controls to select preferred games pref_controls = WidgetBox( ctl_liked_list_title, ctl_liked_games, Spacer(min_height=20), ctl_game_entry, ctl_reset_prefs, Spacer(min_height=5), ) ctl_liked_list_title = Div( text= """<div style="font-size : 18pt; line-height:16pt;">Game Categories:</div>""" ) filter_controls = WidgetBox( row(ctl_game_weight, Spacer(min_width=50), ctl_game_min_rating), row(ctl_include_expansions), column( row( Div(text= """<div style="font-size : 18pt; line-height:16pt;">Game Categories:</div>""" ), Spacer(min_width=50), ctl_recommend), row(ctl_category_selection1, ctl_category_selection2), Spacer(min_height=5), Div(text= """<div style="font-size : 18pt; line-height:16pt;">Game Mechanics:</div>""" ), row(ctl_mechanics_selection1, ctl_mechanics_selection2), )) # recommendation results results_controls = WidgetBox( ctl_recommended_list_title, ctl_recommended_games, Spacer(min_height=10), ) # Create a row layout layout = row(column(pref_controls, filter_controls), Spacer(min_width=50), results_controls) # Make a tab with the layout tab = Panel(child=layout, title='Advanced Game Recommender') return tab
def make_tab(): # Slider to select width of bin pastdays_select = RangeSlider(start=0, end=999, value=(0, 999), step=1, title='Past Days', sizing_mode="stretch_both") # Slider to select buffer size bufferdays_select = Slider(start=.01, end=9, value=0.01, step=.1, title='Buffer Size (days)', sizing_mode="stretch_both") # Re-read refresh_button = Button(label="Time window and buffer are up to date", button_type="success", sizing_mode="stretch_both") refresh_button.disabled = True # read data flights, available_carriers = read(pastdays_select, bufferdays_select) # CheckboxGroup to select carrier to display locationcodes = np.unique( ['.'.join(seedid.split('.')[:3]) for seedid in available_carriers]) selections = [] for locationcode in locationcodes[:maxnstation]: matching = [s for s in available_carriers if locationcode in s] active = [i for i, m in enumerate(matching)] # if "Z" == m[-1]] selections += [ CheckboxButtonGroup(labels=matching, active=active, sizing_mode="stretch_both") ] #selections += [MultiSelect(#title="Option:", # value=matching, # active=active) # Find the initially selected carrieres initial_carriers = [s.labels[i] for s in selections for i in s.active] # Slider to select width of bin binwidth_select = Slider(start=16, end=160, step=16, value=80, title='Bin number', sizing_mode="stretch_both") # RangeSlider control to select start and end of plotted delays range_select = RangeSlider(start=-1, end=999, value=(-.2, 99), step=.1, title='Range (sec)', sizing_mode="stretch_both") # Switch from lines to hists type_switch = RadioButtonGroup(labels=["Histogram", "Cumulated dist."], active=0, sizing_mode="stretch_both") # Find the initially selected carrieres plottype = type_switch.labels[type_switch.active] src = {} for output in ['Latencies', 'Delays', 'PSD']: src[output] = make_dataset(flights, initial_carriers, range_start=range_select.value[0], range_end=range_select.value[1], bin_width=binwidth_select.value, output=output, plottype=plottype) callback = partial(update, output='Delays', type_switch=type_switch, flights=flights, src=src, selections=selections, range_select=range_select, binwidth_select=binwidth_select) callbacklat = partial(update, output='Latencies', type_switch=type_switch, flights=flights, src=src, range_select=range_select, selections=selections, binwidth_select=binwidth_select) callbackpsd = partial(update, output='PSD', type_switch=type_switch, flights=flights, src=src, range_select=range_select, selections=selections, binwidth_select=binwidth_select) callbackneedsread = partial(needsreadupdate, refresh_button=refresh_button) callbackread = partial(readupdate, src=src, selections=selections, range_select=range_select, type_switch=type_switch, binwidth_select=binwidth_select, pastdays_select=pastdays_select, bufferdays_select=bufferdays_select, refresh_button=refresh_button) [ s.on_change('active', callback, callbacklat, callbackpsd) for s in selections ] type_switch.on_change('active', callback, callbacklat, callbackpsd) binwidth_select.on_change('value', callback, callbacklat, callbackpsd) range_select.on_change('value', callback, callbacklat, callbackpsd) pastdays_select.on_change('value', callbackneedsread) bufferdays_select.on_change('value', callbackneedsread) refresh_button.on_click(callbackread) p = {} for output in ['PSD', 'Latencies', 'Delays']: p[output] = make_plot(src[output], output=output) # Create a row layout graphs = [p[k] for k in p] controls = [ type_switch, binwidth_select, range_select, refresh_button, pastdays_select, bufferdays_select, *selections[:maxnstation] ] graphslayout = column(children=graphs, sizing_mode="stretch_both") controlslayout = column( children=controls, sizing_mode='fixed', #stretch_width', width=400, ) layout = row(children=[graphslayout, controlslayout], sizing_mode='stretch_both') # Make a tab with the layout return Panel(child=layout, title='Channels')
fig.title.text = 'San Diego Housing Prices,' + str(yr) + 'Price Range - (' + str(range_start/1000000)+'M, ' + \ str(range_end/1000000)+'M' # Make a slider object: slider slider = Slider(title='Year', start=2000, end=2019, step=1, value=2015) #price_min = Select(value=10000, title='Min Sale Price', options=) #price_max = Select(value=1000000, title='Max Sale Price', options=) range_select = RangeSlider(start=50000, end=20000000, value=(1000000, 5000000), step=50000, title='Price Range ($)') # Update the plot when the value is changed source = display_data(selected_year=2015) fig = make_plot(source) slider.on_change('value', update_plot) range_select.on_change('value', update_plot) # Make a column layout of widgetbox(slider) and plot, and add it to the current document layout = column(fig, widgetbox(slider, range_select)) curdoc().add_root(layout) curdoc().title = 'San Deigo Housing Prices' output_file('viz.html') show(layout) # Calls figure
def histo_tab(dataframe): """ function called by main.py to show this tab. """ def calc_totals_averages(name_list): """ Simple calculations on columns of the dataframe """ totals = {} means = {} for name in name_list: totals[name] = dataframe[name].sum() means[name] = int(dataframe[name].mean()) return totals, means def make_dataset(name_list, x_min=30000, x_max=130000, n_bins=40): """ return a column datasource """ totals, means = calc_totals_averages(name_list) hist_df = pd.DataFrame(columns=[ "name", "left", "right", "f_interval", "steps", "colour", "total", "average" ]) for i, name in enumerate(name_list): step_hist, edges = np.histogram(dataframe[name], bins=n_bins, range=[x_min, x_max]) tmp_df = pd.DataFrame({ "steps": step_hist, "left": edges[:-1], "right": edges[1:] }) tmp_df['f_interval'] = ['%d to %d steps' % (left, right) \ for left, right in zip(tmp_df['left'], tmp_df['right'])] tmp_df["name"] = name tmp_df["colour"] = Category20_16[i] tmp_df["total"] = totals[name] tmp_df["average"] = means[name] # add this persons data to the overall hist_df hist_df = hist_df.append(tmp_df) # convert to a Bokeh ColumnDataSource and return it source = ColumnDataSource(hist_df) return source def style(p): # Title p.title.align = 'center' p.title.text_font_size = '20pt' p.title.text_font = 'serif' # Axis titles p.xaxis.axis_label_text_font_size = '14pt' p.xaxis.axis_label_text_font_style = 'bold' p.yaxis.axis_label_text_font_size = '14pt' p.yaxis.axis_label_text_font_style = 'bold' # Tick labels p.xaxis.major_label_text_font_size = '12pt' p.yaxis.major_label_text_font_size = '12pt' return p def make_plot(source): """ return the bokeh figure """ print("In make_plot") p = figure(plot_height=600, plot_width=600, x_axis_label='steps', y_axis_label="Count") p.quad(source=source, bottom=0, top='steps', left='left', right='right', fill_color='colour', alpha=0.5, line_color='black', legend='name') hover = HoverTool(tooltips=[("Name", "@name"), ( "Total", "@total"), ("Average", "@average"), ('Step range', '@f_interval'), ('Num of Weeks', '@steps')]) p.add_tools(hover) p = style(p) return p def update(attr, old, new): """ Update the plot every time a change is made """ hists_to_plot = [selection.labels[i] for i in selection.active] new_src = make_dataset(hists_to_plot, x_min=range_select.value[0], x_max=range_select.value[1], n_bins=nbin_select.value) cds.data.update(new_src.data) ### back to the histo_tab function definition... names = list(dataframe.columns) names.sort() # widgets to allow user to configure the plot selection = CheckboxGroup(labels=names, active=list(range(len(names)))) selection.on_change('active', update) nbin_select = Slider(start=1, end=100, step=1, value=40, title="Num bins") nbin_select.on_change('value', update) range_select = RangeSlider(start=20000, end=200000, value=(30000, 130000), step=1000, title="Range") range_select.on_change('value', update) # initial column data source and plot initial_names = [selection.labels[i] for i in selection.active] cds = make_dataset(initial_names) p = make_plot(cds) controls = WidgetBox(selection, nbin_select, range_select) # create row layout layout = row(controls, p) #turn this into a tab tab = Panel(child=layout, title="Histograms") return tab
def type_tab(df): """ Make a tab includes a line plot which shows how different attack types affected when year pass Parameters: df (DataFrame): a pandas dataframe Returns: tab: a bokeh object """ # Setup needed variable unique_types = list(df.attacktype1_txt.unique()) palette = brewer['Spectral'][len(unique_types)] colormap = {unique_types[i]: palette[i] for i in range(len(unique_types))} def make_data(df, start=1970, end=2017, types=unique_types): """ Modify data for plotting Parameters: df (DataFrame): a pandas dataframe start (int): start year number end (int): end year number types (list): a list of unique attack type Returns: ColumnDataSource: a bokeh object """ modified = df[(df['iyear'] >= start) & (df['iyear'] <= end)].\ groupby(['iyear', 'attacktype1_txt'], as_index=False).count() modified = modified[modified['attacktype1_txt'].isin(types)] source = {} for i in range(len(types)): if 'x' in source.keys(): source['x'].append( list(modified[modified['attacktype1_txt'] == types[i]].iyear)) source['y'].append( list(modified[modified['attacktype1_txt'] == types[i]].eventid)) source['type'].append( list(modified[modified['attacktype1_txt'] == types[i]].attacktype1_txt.unique())) source['colors'].append(colormap[types[i]]) else: source['x'] = [ list(modified[modified['attacktype1_txt'] == types[i]].iyear) ] source['y'] = [ list(modified[modified['attacktype1_txt'] == types[i]].eventid) ] source['type'] = [ list(modified[modified['attacktype1_txt'] == types[i]].attacktype1_txt.unique()) ] source['colors'] = [colormap[types[i]]] return ColumnDataSource(source) def update(): """ Update the ColumnDataSource when client interact with widgets """ selected_types = [types.labels[i] for i in types.active] new_src = make_data(df, year.value[0], year.value[1], selected_types) src.data.update(new_src.data) # Setup needed variable year = RangeSlider(start=1970, end=2017, value=(1970, 2017), step=1, title="Year Range") types = CheckboxGroup(labels=unique_types, active=list(range(len(unique_types)))) src = make_data(df) year.on_change('value', lambda attr, old, new: update()) types.on_change('active', lambda attr, old, new: update()) controls = WidgetBox(year, types) # line plot p = figure(plot_height=600, plot_width=800, title='Attack Types', x_axis_label='Years', y_axis_label='Types', output_backend='webgl') p.multi_line(xs='x', ys='y', source=src, line_color='colors', line_width=2, legend='type') p.legend.location = 'top_left' p.add_tools( HoverTool(show_arrow=False, tooltips=[('Year', '$data_x'), ('Counts', '$data_y'), ('Type', '@type')])) # Setup tab structure and name tab = Panel(child=row(controls, p), title='Attack Types') return tab
bipot.mode = bipot.DUAL Voltage_WE2.visible = True """Callback Assignments""" callback_update_plot = None callback_acquire_data_fake = None Connect.on_click(callback_Connect_eLoaD_BLE) Save.js_on_click(callback_Save) Start.on_click(callback_Start) Random_test.on_click(callback_Random_4) Gain.on_change('value', update_gain) Scan_rate.on_change('value', update_scan_rate) Segments.on_change('value', update_segments) Voltage_Start.on_change('value', update_v1_start) Voltage_WE2.on_change('value', update_v2) Voltage_Window.on_change('value', update_v1_window) Sweep_direction.on_change('active', update_sweep) Voltammetry_Mode.on_change('active', update_voltammetry_mode) #---------------------------# # Callbacks (Threads) # #---------------------------# #Plotting has no priority, also slower @gen.coroutine #It seems that we cannot make streaming unlocked def stream(): global acquiredData source.stream( {'time': acquiredData['timestamp'], 'raw_data': acquiredData['raw_data']}) clear_dict(acquiredData)
class signalHandler: def __init__(self, signalFilename="", lyricsFilename="", signal=[], sampleRate=0, color="red"): self.path = os.getcwd() logger.logData(source="Signal handler", priority="INFO", msgType="Setup start", msgData=()) self.setupVariables() self.color = color self.setupMapper() self.setupColorBar() self.lyricsImported = 0 if lyricsFilename: self.setupLyricTable(lyricsFilename) self.lyricsImported = 1 self.setupPlotWindow() self.setupControls() self.setupGUI() if signalFilename: self.importFile(signalFilename) if len(signal): self.addSignal(signal, sampleRate) logger.logData(source="Signal handler", priority="INFO", msgType="Setup done", msgData=((self.signalImported))) def setupGUI(self): """Wraps the plot, slider, and tool column into one layout""" audioCol = column(self.p, self.colorBar, self.timeWindowSlider, height=self.figureHeight) # dtgCol = column(self.dtg.gui,width=400) if self.lyricsImported: # self.gui = self.lyricTable self.gui = row(self.lyricsGui, audioCol, self.controls, height=self.figureHeight - 110) else: self.gui = row(audioCol, self.controls, height=self.figureHeight - 110) def setupVariables(self): """sets up important variables to the tool, including figure size dummy variables to use before file import tool options - loop, button sizes, button delay """ try: self.masterPath = os.getcwd() #use when running from Sublime os.listdir(self.masterPath) except: self.masterPath = os.path.join("soundTools", "") #use when running from Bokeh os.listdir(self.masterPath) self.subtitlePath = os.path.join(self.masterPath, "lyrics") self.audioPath = os.path.join(self.masterPath, "audio") self.webpagePath = os.path.join(self.masterPath, "webpages") self.figureWidth = 1000 self.figureHeight = 500 self.buttonWidth = 200 self.buttonHeight = 15 self.numXTicks = 4 self.soundPlaying = 0 self.signalImported = 0 self.lastChunkIndex = 0 self.strideMultiplier = 100 self.sweepStartSample = 0 self.sweepEndSample = 10 self.activeChannels = [] self.yRange = (-1, 1) self.channelAnchorYs = np.arange(0, self.yRange[1], 2) self.plotStyle = 0 self.glyphsSetup = 0 self.loop = 0 self.plotMode = 0 self.outputFilename = "output" self.updateDelay = 12 #delay period in milliseconds befwen timeline update while playing the active signal self.windowChunkLength = 10 #seconds def showGui(self): output_file(os.path.join("webpages", "signalHandler.html")) logger.logData(source="Signal handler", priority="INFO", msgType="Show", msgData=()) show(self.gui) curdoc().add_root(self.gui) def addSignal(self, signalIn, sampleRate): """Adds a prexisting list/mutliDim ndarray (with known sample rate) as the active signal and updates plot""" #keep the original in case of a reset self.originalSignal = signalIn #signal gets changed on update of time slider self.signal = self.originalSignal #activeSignal gets changed on update of of signal AND update of active channels self.activeSignal = self.signal self.sampleRate = sampleRate self.signalImported = 1 logger.logData(source="Signal handler", priority="INFO", msgType="Signal add", msgData=()) self.analyzeSignal() def importFile(self, filename): """imports a wav file into the tool and updates the plot and tools""" #check to make sure the filename is valid try: self.sampleRate, self.originalSignal = wavfile.read( os.path.join( self.audioPath, filename)) #keep the original for master reference except: logger.logData(source="Signal handler", priority="WARN", msgType="Import file fail", msgData=(filename)) return #update tool's internal filename self.filename = filename #import the wav file self.signal = self.originalSignal self.activeSignal = self.signal self.signalImported = 1 logger.logData(source="Signal handler", priority="INFO", msgType="Import file", msgData=(filename)) #get relevant signal info and update plot self.analyzeSignal() def analyzeSignal(self): """Parses the metadata from the active signal and updates plot and tools""" self.glyphsSetup = 0 #get number of channels of signal try: self.numChannels = self.signal.shape[1] except: #if it's single channel its imported as a list, make it a 1D ndarray self.numChannels = 1 self.signal = np.transpose(np.array([self.signal])) self.activeChannels = list(range(self.numChannels)) self.channelButtons.labels = list(map(str, self.activeChannels)) self.channelButtons.active = self.activeChannels if not np.any(self.signal): logger.logData(source="Signal handler", priority="WARN", msgType="Empty", msgData=()) return self.numSamples = len(self.signal) self.sampleIndices = range(self.numSamples) self.messedUpTs = self.sampleIndices self.updateMapperHigh(self.numSamples) self.updateColorBar(self.sampleIndices) self.signalDuration = self.numSamples / float(self.sampleRate) self.windowChunks = int( (self.signalDuration / self.windowChunkLength)) + 1 #update the time slider with the imported signal's duration self.timeWindowSlider.end = self.signalDuration self.timeWindowSlider.value = [0, self.signalDuration] self.sweepStartSample = 0 self.sweepEndSample = self.numSamples #setup the ticker to replace indices with timestamps self.setMasterXAxisTicker() #PLOT SCATTER PARAMS #get max amplitude of signal to adjust y range and channel spacing self.sigPeak = np.amax(self.signal) self.yRange = (0, 2 * self.numChannels * self.sigPeak) #generate offsets to space multiple channels out in the y axis self.channelAnchorYs = np.arange(self.sigPeak, self.yRange[1], 2 * self.sigPeak) logger.logData(source="Signal handler", priority="INFO", msgType="Analyze", msgData=(round(self.signalDuration, 3), self.numChannels, self.numSamples, self.sampleRate)) self.drawActivePlot() # self.drawFullSignal() def setMasterXAxisTicker(self): #ticker dictionary to rpaplce x axis index ticks with their coirrosponding timestamps self.masterTicker = list( range(0, self.numSamples, int(self.numSamples / self.numXTicks))) self.masterXAxisOverrideDict = {} timeLabels = np.linspace(0, self.signalDuration, self.numXTicks) for sampleInd, timeLabel in zip(self.masterTicker, timeLabels): self.masterXAxisOverrideDict[sampleInd] = str(round(timeLabel, 3)) #set up the size and duration of the sub-chunks displayed while the signal is playing self.samplesPerChunk = int(self.numSamples / self.windowChunks) self.chunkDuration = self.samplesPerChunk / float(self.sampleRate) #the absolute index values comprising the x axis ticks self.chunkTicker = list( range(0, self.samplesPerChunk, int(self.samplesPerChunk / self.numXTicks))) # self.chunkLabels = np.linspace(0,self.chunkDuration,10) # self.chunkTickOverride = {} # for sampleInd,timeLabel in zip(self.chunkTicker,self.chunkLabels): # self.chunkTickOverride[sampleInd] = str(round(timeLabel,3)) def fileCallback(self, attr, old, new): """Callback assigned to choosing a file from the file browser""" filename = new['file_name'][0] self.importFile(filename) def fileButtonSetup(self): """Creates a "File opener" button and assigns a javascript callback to it that opens an os-independent file picker window imports chosen file into the class""" fileSource = ColumnDataSource({'file_name': []}) self.fileImportButton.callback = CustomJS( args=dict(file_source=fileSource), code=""" function read_file(filename) { var reader = new FileReader(); reader.onload = load_handler; reader.onerror = error_handler; // readAsDataURL represents the file's data as a base64 encoded string reader.readAsDataURL(filename); } function load_handler(event) { file_source.data = {'file_name':[input.files[0].name]}; file_source.trigger("change"); } function error_handler(evt) { if(evt.target.error.name == "NotReadableError") { alert("Can't read file!"); } } var input = document.createElement('input'); input.setAttribute('type', 'file'); input.onchange = function(){ if (window.FileReader) { read_file(input.files[0]); } else { alert('FileReader is not supported in this browser'); } } input.click(); """) fileSource.on_change('data', self.fileCallback) def setupControls(self): """Called on setup, creates buttons and sliders to: open a local audio file set loop mode update the active timespan play the active timespan set filename to save active signal to save active signal to that filename """ #check boxes to choose what plots to display self.plotModeButtons = RadioButtonGroup( labels=["Wav", "FFT", "Spectrogram"], active=self.plotMode, button_type="warning", width=self.buttonWidth, height=self.buttonHeight) self.plotModeButtons.on_change("active", self.plotModeCallback) #choose betwen line or scatter plot self.plotStyleButtons = RadioButtonGroup(labels=["Line", "Scatter"], active=0, button_type="danger", width=self.buttonWidth, height=self.buttonHeight) self.plotStyleButtons.on_change("active", self.plotStyleCallback) channelTitle = Div(text="""<b>Audio Channels:</b>""", width=self.buttonWidth, height=2) self.channelButtons = CheckboxButtonGroup(labels=["-"], active=[0], button_type="primary", width=self.buttonWidth, height=self.buttonHeight) self.channelButtonRow = column(channelTitle, self.channelButtons, width=self.buttonWidth, height=self.buttonHeight * 2) self.channelButtons.on_change("active", self.channelButtonCallback) #creates a filebutton and assigns it a callback linked to a broser-based file browser self.fileImportButton = Button(label="Import File", button_type="success", width=self.buttonWidth, height=self.buttonHeight) self.fileButtonSetup() #create a loop toggle button and assigns a callback to it self.loopAudioToggle = Toggle(label="Loop", button_type="success", width=self.buttonWidth, height=self.buttonHeight) self.loopAudioToggle.on_click(self.loopAudioCallback) #double ended slider to clip audio by time self.timeWindowSlider = RangeSlider(start=0, end=1, value=[0, 1], step=.05, title="Wav File Window", width=self.figureWidth, height=self.buttonHeight) self.timeWindowSlider.on_change("value", self.timeSliderCallback) #button to commit clip changes to active signal self.updateButton = Button(label="Update", button_type="success", width=self.buttonWidth, height=self.buttonHeight) self.updateButton.on_click(self.updateButtonCallback) #button to play active signal, self.playButton = Button(label="Play", button_type="success", width=self.buttonWidth, height=self.buttonHeight) self.playButton.on_click(self.playSound) self.filenameBox = TextInput(value="output", title="Output Filename:", width=self.buttonWidth) #button to write active signal to file self.writeFileButton = Button(label="Write Active File", button_type="success", width=self.buttonWidth, height=self.buttonHeight) self.writeFileButton.on_click(self.writeFileButtonCallback) #button to reset tool to state right after signal import self.resetButton = Button(label="Reset", button_type="success", width=self.buttonWidth, height=self.buttonHeight) self.resetButton.on_click(self.resetButtonCallback) self.resetZoomButton = Button(label="Reset Zoom", button_type="success", width=self.buttonWidth, height=self.buttonHeight) self.resetZoomButton.js_on_click( CustomJS(args=dict(p=self.p), code=""" p.reset.emit() """)) self.generalControlsColumn = column(self.plotModeButtons, self.plotStyleButtons, self.filenameBox, self.channelButtonRow, width=self.buttonWidth) self.buttonColumn = column( self.resetZoomButton, self.fileImportButton, self.updateButton, self.loopAudioToggle, self.playButton, self.writeFileButton, self.resetButton, width=self.buttonWidth) #,height=self.figureHeight) self.controls = row(self.generalControlsColumn, self.buttonColumn) #wrap buttons and text box in a column of fixed width # self.buttonColumn = column(self.plotModeButtons,self.plotStyleButtons,self.channelButtonRow,self.resetZoomButton,self.fileImportButton,self.updateButton,self.loopToggle,self.playButton,self.writeFileButton,self.resetButton,self.filenameBox,width=self.buttonWidth)#,height=self.figureHeight) #choose active channels def channelButtonCallback(self, attr, old, new): if not self.signalImported: return try: self.activeChannels = new self.activeSignal = self.signal[:, self.activeChannels] self.glyphsSetup = 0 self.drawActivePlot() logger.logData(source="Signal handler", priority="INFO", msgType="Channel update", msgData=((old, new))) except: logger.logData(source="Signal handler", priority="WARN", msgType="Channel fail", msgData=(old)) return #choose between line or scatter plot def plotStyleCallback(self, attr, old, new): self.plotStyle = new self.glyphsSetup = 0 # self.drawFullSignal() self.drawActivePlot() def plotModeCallback(self, att, old, new): self.plotMode = new self.drawActivePlot() def loopAudioCallback(self, event): """Called on toggling of the loop button, binary inverts previous loop val""" self.loop = 1 - self.loop def writeFileButtonCallback(self): """Called on click of the write Fiile button Writes the active signal to the filename set by the textbox""" outputFilename = self.filenameBox.value + ".wav" outputPath = os.path.join(self.path, "audio", outputFilename) numChannels = len(self.activeChannels) logger.logData(source="Signal handler", priority="INFO", msgType="Write", msgData=(outputFilename, numChannels, self.sampleRate, self.signalDuration)) wavfile.write(outputPath, self.sampleRate, self.activeSignal) # def resetZoomCallback(self): # print(1) def resetButtonCallback(self): """Returns the tool to state it was immediately after file was imported""" #if no signal is imported, do nothing if not self.signalImported: return #reset active to signal to the original, unclipped signal self.signal = self.originalSignal logger.logData(source="Signal handler", priority="INFO", msgType="Reset", msgData=()) #return variables and plot to original state self.analyzeSignal() def updateButtonCallback(self): """Called on press of the update button, clips the signsal by the estart and end trimes decreed by the time slider, resets the plot to like the clipped signal is the new full signal""" #if no signal is imported, do nothing if not self.signalImported: logger.logData(source="Signal handler", priority="WARN", msgType="Update failed", msgData=()) return #clip all channel samples corresponding to the times on slider self.signal = self.signal[self.sweepStartSample:self.sweepEndSample, :] logger.logData(source="Signal handler", priority="INFO", msgType="Update signal", msgData=()) #update variables and plot with clipped signal self.analyzeSignal() def timeSliderCallback(self, attr, old, new): """Called on update of the time slider moves the sweep start/end lines used for clipping the signal when the update button is pressed""" if not self.signalImported: return try: #convert the start and end times to integer sample numbers and update internal locations self.sweepStartSample = int(new[0] * self.sampleRate) self.sweepEndSample = int(new[1] * self.sampleRate) #update sweep line graphics startLine = self.p.select_one({'name': 'sweepStartLine'}) startLine.data_source.data = { 'x': [self.sweepStartSample, self.sweepStartSample], 'y': self.yRange } endLine = self.p.select_one({'name': 'sweepEndLine'}) endLine.data_source.data = { 'x': [self.sweepEndSample, self.sweepEndSample], 'y': self.yRange } except: return def shiftSamples(self, channelIndex): """Element wise adds to the channel's vector to offset a channel so it can vbe plotted alongside other channels""" channelSamples = self.signal[:, channelIndex] reducedSamples = channelSamples[::self.strideMultiplier] return reducedSamples + self.channelAnchorYs[channelIndex] def setupPlotWindow(self): """Creates a window containing the channel plots""" p = figure(height=300, width=self.figureWidth, x_range=(0, 1), y_range=(0, 1), tools="box_zoom", toolbar_location=None, output_backend="webgl") # p.toolbar.active_scroll = "auto" p.yaxis.visible = False p.grid.visible = False self.p = p def updateFigureForSpectrogram(self): self.p.x_range.end = self.numSamples self.p.y_range.end = self.yRange[1] self.p.xaxis.ticker = self.masterTicker self.p.xaxis.major_label_overrides = self.masterXAxisOverrideDict def plotSpectrogram(self): """Plots a log spectrogram of the active audio, returns figure object""" #max freq represetnedf (nyquist constrained) imgHeight = self.sampleRate / 2 self.p.y_range.end = imgHeight * self.numChannels imgWidth = self.signalDuration self.p.x_range.end = imgWidth for channelNum in self.activeChannels: channelSignal = self.signal[:, channelNum] freqs, times, data = self.log_specgram(channelSignal, self.sampleRate) self.p.image(image=[data], x=0, y=imgHeight * channelNum, dw=imgWidth, dh=imgHeight, palette="Spectral11") def log_specgram(self, audio, sampleRate, window_size=20, step_size=10, eps=1e-10): """Kraggin log spectrogram useful for MFCC analysis""" nperseg = int(round(window_size * sampleRate / 1e3)) noverlap = int(round(step_size * sampleRate / 1e3)) freqs, times, spec = spectrogram(audio, fs=sampleRate, window='hann', nperseg=nperseg, noverlap=noverlap, detrend=False) return freqs, times, np.log(spec.T.astype(np.float32) + eps) def setupPlotScatterGlyphs(self): self.p.line([self.sweepStartSample, self.sweepStartSample], self.yRange, color="blue", line_width=2, name="sweepStartLine") self.p.line([self.sweepEndSample, self.sweepEndSample], self.yRange, color="blue", line_width=2, name="sweepEndLine") self.p.line([0, 0], self.yRange, color='red', line_width=2, name='timeLine') # self.scatterSource = {"x":[],"place":[]} self.scatterSources = [] for channelNum in self.activeChannels: self.scatterSources.append( ColumnDataSource({ "x": list(self.sampleIndices), "y": list(self.sampleIndices), "place": self.messedUpTs })) # self.p.scatter(x=[],y=[],radius=.1, fill_color={'field':"place",'transform': self.mapper},name="audioLine" + str(channelNum)) self.p.scatter(x="x", y="y", radius=1, source=self.scatterSources[channelNum], fill_color={ 'field': "place", 'transform': self.mapper }, line_color={ 'field': "place", 'transform': self.mapper }, name="audioLine" + str(channelNum)) def setupLinePlotGlyphs(self): self.p.line([self.sweepStartSample, self.sweepStartSample], self.yRange, color="blue", line_width=2, name="sweepStartLine") self.p.line([self.sweepEndSample, self.sweepEndSample], self.yRange, color="blue", line_width=2, name="sweepEndLine") self.p.line([0, 0], self.yRange, color='red', line_width=2, name='timeLine') for channelNum in self.activeChannels: self.p.line(x=[], y=[], line_width=.3, color=self.color, name="audioLine" + str(channelNum)) def drawActivePlot(self): if not self.signalImported: return if self.plotMode == 0: self.drawFullSignal() elif self.plotMode == 1: self.getFFT() else: self.plotSpectrogram() def drawFullSignal(self): if self.glyphsSetup == 0: self.p.renderers = [] if self.plotStyle: self.setupPlotScatterGlyphs() else: self.setupLinePlotGlyphs() self.glyphsSetup = 1 """redraws each channel of the full plot and updates the xaxis to the full signal duration""" for channelNum in self.activeChannels: shiftedSamples = self.shiftSamples(channelNum) reducedSampleIndices = self.sampleIndices[::self.strideMultiplier] if self.plotStyle: self.scatterSources[channelNum].data = { 'x': reducedSampleIndices, 'y': list(shiftedSamples), "place": reducedSampleIndices } else: channelLine = self.p.select_one( {'name': 'audioLine' + str(channelNum)}) channelLine.data_source.data = { 'x': reducedSampleIndices, 'y': shiftedSamples, "place": reducedSampleIndices } #update x axis with full timespan self.p.x_range.end = self.numSamples self.p.y_range.end = self.yRange[1] self.p.xaxis.ticker = self.masterTicker self.p.xaxis.major_label_overrides = self.masterXAxisOverrideDict def playSound(self): """Starts playing the signal, and draws a sweeping vertical line on actively updating sub-samples of the audfio""" #if the "Play" button is pushed during play, it acts as a stop button if self.soundPlaying == 1: logger.logData(source="Signal handler", priority="INFO", msgType="Pause", msgData=()) self.stopAudio() return #if no signal is imported, do nothing if not self.signalImported: return #hide sweep lines until their chunk occurs startLine = self.p.select_one({'name': 'sweepStartLine'}) startLine.visible = False endLine = self.p.select_one({'name': 'sweepEndLine'}) endLine.visible = False ##Chunk-specific sweep lines self.startLineAdded = 0 self.endLineAdded = 0 #precompute which chunk the sweep lines are in for speed self.sweepStartChunk = int( np.floor(self.sweepStartSample / (self.samplesPerChunk + 1))) self.sweepEndChunk = int( np.floor(self.sweepEndSample / (self.samplesPerChunk + 1))) #precompute their indices in their chunk self.shiftedSweepStart = self.sweepStartSample - self.sweepStartChunk * self.samplesPerChunk self.shiftedSweepEnd = self.sweepEndSample - self.sweepEndChunk * self.samplesPerChunk if self.p.select_one({'name': 'sweepEndLineChunk'}) == None: #preadd the lines for speed self.p.line([self.shiftedSweepStart, self.shiftedSweepStart], self.yRange, color="blue", line_width=2, visible=False, name="sweepStartLineChunk") self.p.line([self.shiftedSweepEnd, self.shiftedSweepEnd], self.yRange, color="blue", line_width=2, visible=False, name="sweepEndLineChunk") #update the x axis with the sub-chunk values self.p.x_range.end = self.samplesPerChunk self.p.xaxis.ticker = self.chunkTicker self.p.xaxis.major_label_overrides = self.createChunkXAxisOverrideDict( 0) #set the play button to read "Pause" to pull double duty self.playButton.label = "Pause" logger.logData(source="Signal handler", priority="INFO", msgType="Play", msgData=()) #log start time to keep track of where the time line should be self.startTime = time.time() #start playing the sound try: sd.play(self.activeSignal, self.sampleRate, loop=self.loop, blocking=False) except: logger.logData(source="Signal handler", priority="CRIT", msgType="Play failed", msgData=()) self.playButton.label = "Play" return self.soundPlaying = 1 #add a call callback to trigger periodcially and update the timeline and sub-samples self.perCallback = curdoc().add_periodic_callback( self.update, self.updateDelay) def createChunkXAxisOverrideDict(self, chunkIndex): """ creates a dictionary replacing absolute index ticks on the x axis with their corrosponding times """ #get the time labels corrosponding to this chunk chunkTimeLabels = np.linspace(self.chunkDuration * chunkIndex, self.chunkDuration * (chunkIndex + 1), self.numXTicks) chunkTickOverride = {} for sampleInd, timeLabel in zip(self.chunkTicker, chunkTimeLabels): #replace each sample index x tick with the time label chunkTickOverride[sampleInd] = str(round(timeLabel, 3)) return chunkTickOverride def update(self): """Set to be called periodically when audio is playing to draw the active time line on the audio signal""" if self.loop: #mod the time played by total signal duration to keep the time line accurate for multiple plays deltaTime = ( time.time() - self.startTime ) % self.signalDuration #get time elapsed since the file started playing else: deltaTime = time.time( ) - self.startTime #get time elapsed since the file started playing #if signal not done playing if deltaTime < self.signalDuration: #number of samples elapsed dSamples = deltaTime * self.sampleRate #get the active chunk chunkIndex = int(self.windowChunks * (dSamples / self.numSamples)) #if the chunk is different, need to update the audio plot window to the next chunk if self.lastChunkIndex != chunkIndex: #get the starting and ending sample indices for the next chunk chunkStartIndex = self.samplesPerChunk * chunkIndex chunkEndIndex = self.samplesPerChunk * (chunkIndex + 1) #check if any of the sweep lines lie in this chunk if self.startLineAdded: self.p.select_one({ 'name': 'sweepStartLineChunk' }).visible = False self.startLineAdded = 0 if chunkIndex == self.sweepStartChunk: self.p.select_one({ 'name': 'sweepStartLineChunk' }).visible = True self.startLineAdded = 1 if self.endLineAdded: self.p.select_one({ 'name': 'sweepEndLineChunk' }).visible = False self.endLineAdded = 0 if chunkIndex == self.sweepEndChunk: self.p.select_one({ 'name': 'sweepEndLineChunk' }).visible = True self.endLineAdded = 1 #get the signal samples from this chunk and downsample them and shift them by channel reducedChunkSamps = self.signal[ chunkStartIndex:chunkEndIndex:self. strideMultiplier] + self.channelAnchorYs reducedPlaces = list( range(chunkStartIndex, chunkEndIndex, self.strideMultiplier)) #original # chunkSamps = self.signal[chunkStartIndex:chunkEndIndex] # shiftedChunkSamps = chunkSamps + self.channelAnchorYs reducedSampleIndices = list( range(0, self.samplesPerChunk, self.strideMultiplier)) #update plot for each channel for channelIndex in self.activeChannels: if self.plotMode == 0: audioLine = self.p.select_one( {'name': "audioLine" + str(channelIndex)}) audioLine.data_source.data = { 'x': reducedSampleIndices, 'y': reducedChunkSamps[:, channelIndex], "place": reducedPlaces } # audioLine.data_source.data = {'x': reducedSampleIndices, 'y': shiftedChunkSamps[:,channelIndex],"place":reducedPlaces} else: self.scatterSources[channelIndex].data = { "x": reducedSampleIndices, "y": self.sampleIndices, "place": self.messedUpTs } #update the x-axis ticks with the new times self.p.xaxis.major_label_overrides = self.createChunkXAxisOverrideDict( chunkIndex) #update chunk index with new one self.lastChunkIndex = chunkIndex ##time line update #get the glyph for the time line timeLine = self.p.select_one({'name': 'timeLine'}) #sample index of the timeline is total samples elapsed less the number of samples in all previous chunks timeLineIndex = dSamples - chunkIndex * self.samplesPerChunk #update the time line with the new times timeLine.data_source.data = { 'x': [timeLineIndex, timeLineIndex], 'y': self.yRange } #signal IS done playing else: if self.loop: return else: self.stopAudio() def stopAudio(self): """Stops the audio playing, returns the plot to state before audio started playing""" #stop the updating of the time line curdoc().remove_periodic_callback(self.perCallback) #stop playing the signal sd.stop() self.soundPlaying = 0 #change play button back to play from pause self.playButton.label = "Play" logger.logData(source="Signal handler", priority="INFO", msgType="Play done", msgData=()) #restore plot to full signal self.drawActivePlot() #redraw sweep lines on the full signal plot startLine = self.p.select_one({'name': 'sweepStartLine'}) startLine.visible = True endLine = self.p.select_one({'name': 'sweepEndLine'}) endLine.visible = True #return time line to t=0 timeLine = self.p.select_one({'name': 'timeLine'}) timeLine.data_source.data["x"] = [0, 0] def setupMapper(self): self.mapper = LinearColorMapper(palette="Inferno256", low=0, high=10) def updateMapperPalette(self, newColors): self.mapper.palette = newColors def updateMapperHigh(self, newHigh): self.mapper.high = newHigh def updateColorBar(self, times): colorBarPlot = self.gui.select_one({'name': 'colorBarPlot'}) colorBarPlot.x_range.end = self.numSamples colorBar = self.gui.select_one({'name': 'colorBar'}) self.messedUpTs = times self.colorSource.data = { "x": self.sampleIndices, "place": self.messedUpTs } # if self.plotMode == 1: # for channelInd in self.activeChannels: # self.scatterSources[channelIndex].data = {"x":self.sampleIndices,"y":self.sampleIndices,"place":self.messedUpTs} def setupColorBar(self): colorTimeline = figure(height=30, y_range=(-.5, .5), width=self.figureWidth, x_range=(0, 10), toolbar_location=None, output_backend="webgl", name="colorBarPlot", tools="") colorTimeline.axis.visible = False colorTimeline.grid.visible = False # colorTimeline.image(image=range(self.numSamples),x=0,y=.5,dh=1,dw=1,fill_color={'field':"x",'transform': self.mappers[colorBarType-1]}, # name="cbar" + str(colorBarType)) self.colorSource = ColumnDataSource({ "x": range(10), "place": range(10) }) # colorTimeline.rect(x="x", y=0, width=1, height=1,fill_color={'field':"place",'transform': self.mapper},name="colorBar", # line_width=0.0,line_color= None,line_alpha = 0.0,source=colorSource # ) colorBar = Rect(x="x", y=0, width=1, height=1, fill_color={ 'field': "place", 'transform': self.mapper }, name="colorBar", line_width=0.0, line_color=None, line_alpha=0.0) colorTimeline.add_glyph(self.colorSource, colorBar) self.colorBar = colorTimeline def getFFT(self): """Plots the fast fourier transform of the active audio, returns a figure object""" fftHeight = self.numChannels self.p.y_range.end = fftHeight maxFreq = self.sampleRate / 2 self.p.x_range.end = maxFreq for channelNum in self.activeChannels: sigPadded = self.signal[:, channelNum] # Determine frequencies f = np.fft.fftfreq(self.numSamples) * self.sampleRate #pull out only positive frequencies (upper half) upperHalf = int(len(f) / 2) fHalf = f[:upperHalf] # Compute power spectral density psd = np.abs(np.fft.fft(sigPadded))**2 / self.numSamples #pull out only power densities for the positive frequencies psdHalf = psd[:upperHalf] #nromalize y vals psdHalf = psdHalf / max(psdHalf) #shift them to allow multiple channels psdHalf += channelNum self.p.line(fHalf, psdHalf) def lyricModeCallback(self, event): self.lyricMode = 1 - self.lyricMode if self.lyricMode: self.lyricsHandler.lyricModeButton.label = "Change to start lyric" else: self.lyricsHandler.lyricModeButton.label = "Change to end lyric" def dataTableCallback(self, att, old, new): if not self.activeChannels: logger.logData(source="Signal handler", priority="WARN", msgType="Lyric empty", msgData=()) return selectionIndex = self.lyricsHandler.lyricTableHandler.source.selected.indices[ 0] timestamp = self.lyricsHandler.lyricTableHandler.source.data[ "timestamps"][selectionIndex] lyricText = self.lyricsHandler.lyricTableHandler.source.data["lyrics"][ selectionIndex] timestampSeconds = timestamp.seconds lyricSample = int(timestampSeconds * self.sampleRate) if self.lyricMode == 0: #update sweep line graphics self.sweepStartSample = lyricSample startLine = self.p.select_one({'name': 'sweepStartLine'}) startLine.data_source.data = { 'x': [lyricSample, lyricSample], 'y': self.yRange } logger.logData(source="Lyrics", priority="INFO", msgType="Start lyric", msgData=(timestamp, lyricText)) else: self.sweepEndSample = lyricSample endLine = self.p.select_one({'name': 'sweepEndLine'}) endLine.data_source.data = { 'x': [lyricSample, lyricSample], 'y': self.yRange } logger.logData(source="Lyrics", priority="INFO", msgType="End lyric", msgData=(timestamp, lyricText)) def setupLyricTable(self, lyricsFilename): lyricsPath = os.path.join(self.path, "lyrics", lyricsFilename) self.lyricsHandler = lyricsHandler(lyricsPath) self.lyricMode = 0 self.lyricsHandler.lyricTableHandler.source.selected.on_change( 'indices', self.dataTableCallback) #create a loop toggle button and assigns a callback to it self.lyricsHandler.lyricModeButton.on_click(self.lyricModeCallback) self.lyricsGui = self.lyricsHandler.gui
from bokeh.io import curdoc df = pd.read_csv(join(dirname(__file__), 'salary_data.csv')) source = ColumnDataSource(data=dict()) def update(): current = df[(df['salary'] >= slider.value[0]) & (df['salary'] <= slider.value[1])].dropna() source.data = { 'name' : current.name, 'salary' : current.salary, 'years_experience' : current.years_experience, } slider = RangeSlider(title="Max Salary", start=10000, end=110000, value=(10000, 50000), step=1000, format="0,0") slider.on_change('value', lambda attr, old, new: update()) button = Button(label="Download", button_type="success") button.callback = CustomJS(args=dict(source=source), code=open(join(dirname(__file__), "download.js")).read()) columns = [ TableColumn(field="name", title="Employee Name"), TableColumn(field="salary", title="Income", formatter=NumberFormatter(format="$0,0.00")), TableColumn(field="years_experience", title="Experience (years)") ] data_table = DataTable(source=source, columns=columns, width=800) controls = widgetbox(slider, button) table = widgetbox(data_table)
def transformation_tab(company_data, founder_data, gis_data, industry_data, world_data, nation_data): company_data.loc[:, 'IncorporationDate'] = pd.to_datetime( company_data['IncorporationDate'], format='%d/%m/%Y') company_data.loc[:, 'year'] = company_data['IncorporationDate'].dt.to_period( 'Y').astype(str).astype(int) founder_data = founder_data.dropna() founder_data.loc[:, 'IncorporationDate'] = pd.to_datetime( founder_data['IncorporationDate'], format='%d/%m/%Y') founder_data.loc[:, 'year'] = founder_data['IncorporationDate'].dt.to_period( 'Y').astype(str).astype(int) founder_data.loc[:, 'age'] = founder_data['year'] - founder_data[ 'date_of_birth.year'] founder_data.loc[:, 'age'] = founder_data['age'].astype(int) ################################### # diversification into industries # ################################### # %% prepare dataset def make_industry_dataset(range_start=1980, range_end=2020, year_select=2020): # calculate the number of industries industries = company_data.copy() industries = industries.loc[:, [ 'SICCode.SicText_1', 'SICCode.SicText_2', 'SICCode.SicText_3', 'SICCode.SicText_4', 'year' ]] df1 = industries.loc[:, ['SICCode.SicText_1', 'year']].dropna() df1 = df1.rename(columns={'SICCode.SicText_1': 'siccode'}) df2 = industries.loc[:, ['SICCode.SicText_2', 'year']].dropna() df2 = df1.rename(columns={'SICCode.SicText_2': 'siccode'}) df3 = industries.loc[:, ['SICCode.SicText_3', 'year']].dropna() df3 = df1.rename(columns={'SICCode.SicText_3': 'siccode'}) df4 = industries.loc[:, ['SICCode.SicText_4', 'year']].dropna() df4 = df1.rename(columns={'SICCode.SicText_4': 'siccode'}) industries = pd.concat([df1, df2, df3, df4]) industries = industries[industries['siccode'] != 'None Supplied'] industries = industries.sort_values(by=['year']) industries = industries.drop_duplicates(subset=['siccode'], keep='first') industries.loc[:, 'count'] = 1 industries = pd.DataFrame(industries.groupby(['year'])['count'].sum()) industries.loc[:, 'sum'] = industries['count'].cumsum() industries = industries.reset_index() industries = industries[industries['year'] >= range_start] industries = industries[industries['year'] <= range_end] industries = industries.loc[:, ['year', 'sum']] industries.loc[:, 'left'] = industries['year'].astype(float) - 0.5 industries.loc[:, 'right'] = industries['year'].astype(float) + 0.5 # calculate the perc of industries sic = industry_data.copy() perc = company_data.copy() perc = perc.loc[:, [ 'SICCode.SicText_1', 'SICCode.SicText_2', 'SICCode.SicText_3', 'SICCode.SicText_4', 'year' ]] perc = perc[perc['year'] <= year_select] df1 = perc.loc[:, ['SICCode.SicText_1', 'year']].dropna() df1 = df1.rename(columns={'SICCode.SicText_1': 'siccode'}) df2 = perc.loc[:, ['SICCode.SicText_2', 'year']].dropna() df2 = df1.rename(columns={'SICCode.SicText_2': 'siccode'}) df3 = perc.loc[:, ['SICCode.SicText_3', 'year']].dropna() df3 = df1.rename(columns={'SICCode.SicText_3': 'siccode'}) df4 = perc.loc[:, ['SICCode.SicText_4', 'year']].dropna() df4 = df1.rename(columns={'SICCode.SicText_4': 'siccode'}) perc = pd.concat([df1, df2, df3, df4]) perc = perc[perc['siccode'] != 'None Supplied'] perc = perc.sort_values(by=['year']) perc = perc.drop_duplicates(subset=['siccode'], keep='first') perc.loc[:, 'sector_code'] = perc['siccode'].str[0:2] perc.loc[:, 'sector_code'] = perc['sector_code'].astype(int) perc = pd.merge(perc, sic, left_on='sector_code', right_on='SICCode') perc = perc.loc[:, ['sector_code', 'Section', 'Description']] perc.loc[:, 'count'] = 1 perc = pd.DataFrame(perc.groupby(['Section'])['count'].sum()) perc = perc.reset_index() perc = pd.merge(perc, sic, on='Section') perc = perc.drop_duplicates(subset=['Section'], keep='first') perc.loc[:, 'angle'] = perc['count'] / perc['count'].sum() * 2 * np.pi perc.loc[:, 'perc'] = perc['count'] / perc['count'].sum() perc.loc[:, 'perc_num'] = round(perc['perc'] * 100, 2) sections = sorted(list(set(sic['Section']))) color = pd.DataFrame({'Section': sections}) color.loc[:, 'color'] = Category20c[len(color.index)] perc = pd.merge(perc, color, on='Section', how='left') return ColumnDataSource(industries), ColumnDataSource(perc) # %% plot data def make_industry_plot(src): p = figure( plot_width=1000, plot_height=550, title='Industries in Tech-City by years', x_axis_label='YEAR', y_axis_label='NUM', ) p.quad(source=src, bottom=0, top='sum', left='left', right='right', color='lightblue', fill_alpha=0.7, hover_fill_color='steelblue', hover_fill_alpha=1.0, line_color='black') hover = HoverTool(tooltips=[('Year', '@year'), ('Num of Industries', '@sum')]) p.add_tools(hover) return p def make_par_chart(src): p = figure(plot_width=550, plot_height=550, title='Distribution of Sections', tools='hover', tooltips='@Description (@Section) : @perc_num%', x_range=(-2, 2)) p.wedge(x=-0.25, y=0, radius=1.5, source=src, start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'), legend_field='Section', fill_color='color') p.axis.axis_label = None p.axis.visible = False p.grid.grid_line_color = None p.legend.title = 'Sections' return p ################################################# # diversification into international background # ################################################# # %% prepare dataset def make_nation_dataset(range_start=1980, range_end=2020, year_select=2020): # calculate the number of nationalities of founders nations = founder_data.copy() nations = nations.loc[:, ['year', 'nationality']] nations = nations.dropna() nations = nations.reset_index(drop=True) nations = nations.drop('nationality', axis=1).join(nations['nationality'].str.split( ',', expand=True).stack().reset_index( level=1, drop=True).rename('nationality')) nations_1 = nations.copy() nations = pd.merge(nations, nation_data, how='left', left_on='nationality', right_on='nation') nations = nations.sort_values(by=['year']) nations = nations.drop_duplicates(subset=['COUNTRY'], keep='first') nations.loc[:, 'count'] = 1 nations = pd.DataFrame(nations.groupby(['year'])['count'].sum()) nations.loc[1980, 'count'] = 0 nations.loc[1981, 'count'] = 0 nations.loc[1982, 'count'] = 0 nations.loc[1983, 'count'] = 0 nations.loc[1984, 'count'] = 0 nations.loc[1988, 'count'] = 0 nations.loc[1989, 'count'] = 0 nations.loc[1991, 'count'] = 0 nations.loc[1993, 'count'] = 0 nations.loc[1994, 'count'] = 0 nations.loc[1995, 'count'] = 0 nations = nations.reset_index() nations = nations.sort_values(by=['year']) nations.loc[:, 'sum'] = nations['count'].cumsum() nations = nations[nations['year'] >= range_start] nations = nations[nations['year'] <= range_end] nations = nations.loc[:, ['year', 'sum']] nations.loc[:, 'left'] = nations['year'].astype(float) - 0.5 nations.loc[:, 'right'] = nations['year'].astype(float) + 0.5 nations_1 = pd.merge(nations_1, nation_data, how='left', left_on='nationality', right_on='nation') nations_1 = nations_1.loc[:, ['year', 'COUNTRY']] nations_1 = nations_1[nations_1['year'] <= year_select] nations_1 = nations_1[nations_1['COUNTRY'] != 'TBD'] nations_1.loc[:, 'count'] = 1 nations_1 = pd.DataFrame(nations_1.groupby(['COUNTRY'])['count'].sum()) nations_1 = nations_1.reset_index() world = world_data.copy() world = world.loc[:, ['COUNTRY', 'geometry']] world.loc[:, 'x'] = world['geometry'].apply( lambda x: x.representative_point().coords[0][0]) world.loc[:, 'y'] = world['geometry'].apply( lambda x: x.representative_point().coords[0][1]) world = pd.merge(world, nations_1, on='COUNTRY') world = world.drop(['geometry'], axis=1) world.loc[:, 'radius'] = world['count'].apply(np.log) return ColumnDataSource(nations), ColumnDataSource(world) # %% plot data def make_nation_plot(src): p = figure( plot_width=700, plot_height=550, title='International Background in Tech-City by years', x_axis_label='YEAR', y_axis_label='NUM', ) p.quad(source=src, bottom=0, top='sum', left='left', right='right', color='peru', fill_alpha=0.7, hover_fill_color='maroon', hover_fill_alpha=1.0, line_color='black') hover = HoverTool(tooltips=[('Year', '@year'), ('Number of Countries', '@sum')]) p.add_tools(hover) return p # %% plot map def make_nation_map(src): world = world_data.copy() world_src = GeoJSONDataSource(geojson=world.to_json()) p = figure(title='world map', plot_height=550, plot_width=850) p.xgrid.grid_line_color = None p.ygrid.grid_line_color = None p1 = p.patches('xs', 'ys', source=world_src, fill_color='linen', line_color='gray', name='map') p2 = p.circle(x='x', y='y', color='peru', source=src, size=10, fill_alpha=0.4, radius='radius', name='circle') hover = HoverTool(tooltips=[('Country', '@COUNTRY'), ('Number of Founders', '@count')], names=['circle']) p.add_tools(hover) p.xaxis.visible = False p.yaxis.visible = False notes1 = Div(text=''' <b>The location of dots:</b> Country Region (city-level info is not available) ''') notes2 = Div(text=''' <b>The size of dots:</b> the size of Founder Numbers ''') layout = column(p, notes1, notes2) return layout ############################### # diversification into gender # ############################### # %% prepare dataset def make_gender_dataset(gender_indicators, range_start=1980, range_end=2020): # calculate the number of male and female founders each year genders = founder_data.copy() genders = genders.loc[:, ['name', 'year']] genders = genders.dropna() genders.loc[:, 'gender'] = genders['name'].str[0:3] genders = genders[(genders['gender'] == 'Mr ') | (genders['gender'] == 'Mrs') | (genders['gender'] == 'Mis') | (genders['gender'] == 'Ms ') | (genders['gender'] == 'Ms.')] males = genders[genders['gender'] == 'Mr '] males.loc[:, 'male_count'] = 1 males = pd.DataFrame(males.groupby(['year'])['male_count'].sum()) males = males.reset_index() females = genders[genders['gender'] != 'Mr '] females.loc[:, 'female_count'] = 1 females = pd.DataFrame(females.groupby(['year'])['female_count'].sum()) females = females.reset_index() genders = pd.merge(males, females, on='year', how='outer') genders = genders.sort_values(by=['year']).reset_index(drop=True) genders = genders.fillna(0) genders.loc[:, 'male_sum'] = genders['male_count'].cumsum() genders.loc[:, 'female_sum'] = genders['female_count'].cumsum() genders.loc[:, 'total_count'] = genders['male_count'] + genders[ 'female_count'] genders.loc[:, 'total_sum'] = genders['male_sum'] + genders['female_sum'] genders.loc[:, 'male_perc'] = genders['male_sum'] * 100 / genders[ 'total_sum'] genders.loc[:, 'female_perc'] = genders['female_sum'] * 100 / genders[ 'total_sum'] ages = founder_data.copy() ages = ages.loc[:, ['year', 'age']] ages = ages.dropna() means = pd.DataFrame(ages.groupby(['year'])['age'].mean()) means = means.reset_index() genders = pd.merge(genders, means, on='year') if 'Num of New Male Founders' not in gender_indicators: genders.loc[:, 'male_count'] = 'N/A' if 'Num of New Female Founders' not in gender_indicators: genders.loc[:, 'female_count'] = 'N/A' if 'Average Age of New Founders' not in gender_indicators: genders.loc[:, 'age'] = 'N/A' genders = genders[genders['year'] >= range_start] genders = genders[genders['year'] <= range_end] genders.loc[:, 'left'] = genders['year'].astype(float) - 0.5 genders.loc[:, 'right'] = genders['year'].astype(float) + 0.5 return ColumnDataSource(genders) # %% plot data def make_gender_plot(src): p1 = figure( plot_width=800, plot_height=550, title='Genders of New Founders in Tech-City by years', x_axis_label='YEAR', y_axis_label='NUM', ) p1.line(source=src, x='year', y='female_count', color='mediumvioletred', legend_label='Num of New Female Founders') p1.line(source=src, x='year', y='male_count', color='goldenrod', legend_label='Num of New Male Founders') hover1 = HoverTool( tooltips=[('Year', '@year'), ('Number of New Male Founders', '@male_count'), ('Number of New Female Founders', '@female_count')]) p1.add_tools(hover1) p1.legend.location = 'top_left' p2 = figure( plot_width=800, plot_height=550, title='Accumulated Distribution of Genders in Tech-City by years', x_axis_label='YEAR', y_axis_label='PERCENTAGE', y_range=(0, 120), ) p2.quad(source=src, bottom=0, top='female_perc', left='left', right='right', color='lightpink', fill_alpha=0.7, hover_fill_color='mediumvioletred', legend='Female Founders', hover_fill_alpha=1.0, line_color='black') p2.quad(source=src, bottom='female_perc', top=100, left='left', right='right', color='darkorange', fill_alpha=0.7, hover_fill_color='goldenrod', legend='Male Founders', hover_fill_alpha=1.0, line_color='black') hover2 = HoverTool(tooltips=[( 'Year', '@year'), ( 'Accumulated Proportion of Male Founders', '@male_perc%' ), ('Accumulated Proportion of Female Founders', '@female_perc%')]) p2.add_tools(hover2) p = row(p1, p2) return p ########## # update # ########## def update_industry(attr, old, new): # %% industry new_industry_src, new_industry_par_src = make_industry_dataset( range_start=industry_range_select.value[0], range_end=industry_range_select.value[1], year_select=industry_year_select.value) industry_src.data.update(new_industry_src.data) industry_par_src.data.update(new_industry_par_src.data) def update_nation(attr, old, new): # %% nation new_nation_src, new_nation_1_src = make_nation_dataset( range_start=nation_range_select.value[0], range_end=nation_range_select.value[1], year_select=nation_year_select.value) nation_src.data.update(new_nation_src.data) nation_1_src.data.update(new_nation_1_src.data) def update_gender(attr, old, new): # %% gender gender_indicators = [ gender_indicator_selection.labels[i] for i in gender_indicator_selection.active ] new_gender_src = make_gender_dataset( gender_indicators, range_start=gender_range_select.value[0], range_end=gender_range_select.value[1]) gender_src.data.update(new_gender_src.data) ################### # set controllers # ################### # %% industries industry_year_select = Slider(start=1980, end=2020, value=2020, step=1, title='Choose the year') industry_year_select.on_change('value', update_industry) industry_range_select = RangeSlider(start=1980, end=2020, value=(1980, 2020), title='Time Period (year)') industry_range_select.on_change('value', update_industry) # %% nations nation_year_select = Slider(start=1980, end=2020, value=2020, step=1, title='Choose the year') nation_year_select.on_change('value', update_nation) nation_range_select = RangeSlider(start=1980, end=2020, value=(1980, 2020), title='Time Period (year)') nation_range_select.on_change('value', update_nation) # %% gender gender_range_select = RangeSlider(start=1980, end=2020, value=(1980, 2020), title='Time Period (year)') gender_range_select.on_change('value', update_gender) available_indicators = [ 'Num of New Male Founders', 'Num of New Female Founders' ] gender_indicator_selection = CheckboxGroup(labels=available_indicators, active=[0, 1]) gender_indicator_selection.on_change('active', update_gender) initial_gender_indicators = [ gender_indicator_selection.labels[i] for i in gender_indicator_selection.active ] ####################### # make plots and maps # ####################### # %% industries industry_src, industry_par_src = make_industry_dataset( range_start=industry_range_select.value[0], range_end=industry_range_select.value[1], year_select=industry_year_select.value) industry_plot = make_industry_plot(industry_src) industry_par = make_par_chart(industry_par_src) # %% nations nation_src, nation_1_src = make_nation_dataset( range_start=nation_range_select.value[0], range_end=nation_range_select.value[1], year_select=nation_year_select.value) nation_plot = make_nation_plot(nation_src) nation_map = make_nation_map(nation_1_src) # %% gender gender_src = make_gender_dataset(initial_gender_indicators, range_start=gender_range_select.value[0], range_end=gender_range_select.value[1]) gender_plot = make_gender_plot(gender_src) ######## # text # ######## # %% industries industry_title_1 = Div(text=''' <b>Diversification of Industries in Tech City</b> ''') industry_description_1 = Div(text=''' Tech City observed an industry diversification in the comapnies present in the area. Indeed, the number of different industries in the Tech City increased from 164 in 2000, to 325 in 2011 and 651 in 2020 which represents a 100% increase in the number of industries between 2011 and 2020 ''') industry_title_2 = Div(text=''' <b>Data Visual</b> ''') # %% nation nation_title_1 = Div(text=''' <b>Diversification of International Background in Tech City</b> ''') nation_description_1 = Div(text=''' The second goal of the Tech City strategy was to attract foreign investors and international companies. Thus, immigration played a central role - <b>since 2011</b>, the government is trying to stimulate domestic talent growth while aiming to build and sustain a globally competitive technology cluster at the same time. ''') nation_description_2 = Div(text=''' <b>In order to do so, the government took some initiatives:</b> ''') nation_description_3 = Div(text=''' 1. Invitation of 300 international start-ups to Tech City in <b> 2012</b> to take part in a 'StartUp Games' initiative to show these startups what their eventual relocation to Tech City has to offer ''') nation_description_4 = Div(text=''' 2. Facilitation of entrepreneur visas since <b>2012</b> ''') nation_description_5 = Div(text=''' 3. Creation of Tech Nation Visa Scheme in <b>2018</b> enables the brightest and best tech talent from around the world to come and work in the UK's digital technology sector, contributing to maintaining the UK's position at the forefront of the global digital economy ''') nation_description_6 = Div(text=''' 4. Tax breaks ''') nation_description_7 = Div(text=''' 5. Creation of the LaunchPad competition for digital firms in <b>2011</b> ''') nation_description_8 = Div(text=''' 6. Cheaper finance for SMES ''') nation_reference_1 = Div(text=''' <a href="https://startups.co.uk/news/startup-games-to-attract-foreign-start-ups-to-tech-city/">Reference 1</a> ''') nation_reference_2 = Div(text=''' <a href="https://technation.io/visa/">Reference 2</a> ''') nation_reference_3 = Div(text=''' <a href="https://www.demos.co.uk/files/A_Tale_of_Tech_City_web.pdf"> Reference 3</a> ''') nation_title_2 = Div(text=''' <b>Data Visual</b> ''') nation_description_9 = Div(text=''' Following these initiatives, Tech City saw a tremendous diversity in the companies' countries of origin. Indeed, the number of countries of origin of the companies in that area increased from 33 to 84 in 2011 to 161 in 2020 which represents a 92% increase between 2011 and 2020. Companies from Asia, Africa and America began to be more present in Tech City. ''') # %% gender gender_title_1 = Div(text=''' <b>Diversification of Genders in Tech City</b> ''') gender_description_1 = Div(text=''' In 2018, only 19% of the digital tech workforce was female, compared to 49% for all UK jobs. Many governmental, public and privately-run organisations took some initiatives to help promote gender diversity in tech city: ''') gender_description_2 = Div(text=''' <b>Tech Talent Charter in 2018</b> - A commitment by public and privately-run organisations to a set of undertakings that aim to deliver greater gender diversity in the tech workforce of the UK, one that better reflects the makeup of the population. ''') gender_description_3 = Div(text=''' <b>Wiki edit-a-thon</b> - Supported by the Wikimedia Foundation, the edit-a-thon was organised to tackle the gender imbalance in Wikipedia pages and to encourage more women to edit entries. The teenage girls and tech entrepreneurs worked together to create new profiles of London women in order to increase the recognition of these women on the internet. ''') gender_reference_1 = Div(text=''' <a href="https://smartlondon.medium.com/three-city-initiatives-to- promote-diversity-in-londons-tech-community-8d31c7bc9453"> Reference 1</a> ''') gender_title_2 = Div(text=''' <b>Data Visual</b> ''') ############### # set layouts # ############### # %% industries industry_plot_controls = WidgetBox(industry_range_select) industry_par_controls = WidgetBox(industry_year_select) industry_plot_layout = column(industry_plot_controls, industry_plot) industry_par_layout = column(industry_par_controls, industry_par) industry_graph_layout = row(industry_plot_layout, industry_par_layout) industry_layout = column(industry_title_1, industry_title_2, industry_description_1, industry_graph_layout) # %% nation nation_plot_controls = WidgetBox(nation_range_select) nation_map_controls = WidgetBox(nation_year_select) nation_plot_layout = column(nation_plot_controls, nation_plot) nation_map_layout = column(nation_map_controls, nation_map) nation_graph_layout = row(nation_plot_layout, nation_map_layout) nation_layout = column( nation_title_1, nation_description_1, nation_description_2, nation_description_3, nation_description_4, nation_description_5, nation_description_6, nation_description_7, nation_description_8, nation_reference_1, nation_reference_2, nation_reference_3, nation_title_2, nation_description_9, nation_graph_layout) # %% gender gender_plot_controls = WidgetBox(gender_indicator_selection, gender_range_select) gender_plot_layout = column(gender_plot_controls, gender_plot) gender_layout = column(gender_title_1, gender_description_1, gender_description_2, gender_description_3, gender_reference_1, gender_title_2, gender_plot_layout) # %% finalization layout = column(industry_layout, nation_layout, gender_layout) ####### # tab # ####### tab = Panel(child=layout, title='Transformation of Tech-City --- Diversification') return tab
def age_hist_tab(df_selected=None): def make_dataset(age_group_list, range_start=0.076070, range_end=0.271264, bin_width=0.00001): by_age_group = pd.DataFrame(columns=[ 'proportion', 'left', 'right', 'f_proportion', 'f_interval', 'name', 'color' ]) range_extent = range_end - range_start # Iterate through all the carriers for i, age_group in enumerate(age_group_list): # Subset to the carrier subset = df_selected[df_selected['age_range'] == age_group] # Create a histogram with 5 minute bins arr_hist, edges = np.histogram(subset['meanfun'], bins=int(range_extent / bin_width), range=[range_start, range_end]) # Divide the counts by the total to get a proportion arr_df = pd.DataFrame({ 'proportion': arr_hist / np.sum(arr_hist), 'left': edges[:-1], 'right': edges[1:] }) # Format the proportion arr_df['f_proportion'] = [ '%0.5f' % proportion for proportion in arr_df['proportion'] ] # Format the interval arr_df['f_interval'] = [ '%0.5f to %0.5f KHz' % (left, right) for left, right in zip(arr_df['left'], arr_df['right']) ] # Assign the carrier for labels arr_df['name'] = age_group # Color each carrier differently arr_df['color'] = Category20_16[i] # Add to the overall dataframe by_age_group = by_age_group.append(arr_df) # Overall dataframe by_age_group = by_age_group.sort_values(['name', 'left']) return ColumnDataSource(by_age_group) def style(p): # Title p.title.align = 'center' p.title.text_font_size = '20pt' p.title.text_font = 'serif' # Axis titles p.xaxis.axis_label_text_font_size = '14pt' p.xaxis.axis_label_text_font_style = 'bold' p.yaxis.axis_label_text_font_size = '14pt' p.yaxis.axis_label_text_font_style = 'bold' # Tick labels p.xaxis.major_label_text_font_size = '12pt' p.yaxis.major_label_text_font_size = '12pt' return p def make_plot(src): # Blank plot with correct labels p = figure( plot_width=700, plot_height=700, title='Histogram of Age Range and Mean Fundamental Frequeny', x_axis_label='Mean fundamental frequency (KHz)', y_axis_label='Proportion') # Quad glyphs to create a histogram p.quad(source=src, bottom=0, top='proportion', left='left', right='right', color='color', fill_alpha=0.7, hover_fill_color='color', legend='name', hover_fill_alpha=1.0, line_color='black') # Hover tool with vline mode hover = HoverTool(tooltips=[('Age Group', '@name'), ('Meanfund frequency', '@f_interval'), ('Proportion', '@f_proportion')], mode='vline') p.add_tools(hover) # Styling p = style(p) return p def update(attr, old, new): age_group_to_plot = [ age_group_selection.labels[i] for i in age_group_selection.active ] new_src = make_dataset(age_group_to_plot, range_start=range_select.value[0], range_end=range_select.value[1], bin_width=binwidth_select.value) src.data.update(new_src.data) # This is the option on the side available_age_groups = list(df_selected['age_range'].unique()) age_group_selection = CheckboxGroup(labels=available_age_groups, active=[0, 1]) # What happens when you select it age_group_selection.on_change('active', update) # The slider on the side binwidth_select = Slider(start=0.001, end=0.01, step=0.001, value=0.001, title='Frequency Width (KHz)') #Something is updated binwidth_select.on_change('value', update) #The slider and the ranges for that one range_select = RangeSlider(start=0.076070, end=0.271264, value=(0.076070, 0.271264), step=0.01, title='Meanfun Frequency (KHz)') # Same here range_select.on_change('value', update) initial_age_grop = [ age_group_selection.labels[i] for i in age_group_selection.active ] src = make_dataset(initial_age_grop, range_start=range_select.value[0], range_end=range_select.value[1], bin_width=binwidth_select.value) p = make_plot(src) # Put controls in a single element controls = WidgetBox(age_group_selection, binwidth_select, range_select) # Create a row layout layout = row(controls, p) # Make a tab with the layout tab = Panel(child=layout, title='Age Group Histogram') return tab
def update(): current = df[(df['Share'] >= range_slider.range[0]) & ( df['Share'] <= range_slider.range[1])].dropna().reset_index(drop=True) source.data = { 'Year': current.Year, 'Player': current.Player, 'Share': current.Share.map(lambda x: '{0:.3g}'.format(x)), } range_slider = RangeSlider(title="Share Range", start=0.0, end=1.0, step=.01, range=(0.0, 1.0)) range_slider.on_change('range', lambda attr, old, new: update()) button1 = Button(label="Export CSV", button_type="success") button1.callback = CustomJS(args=dict(source=source), code=open( join(dirname(__file__), "download_csv.js")).read()) button2 = Button(label="Export JSON", button_type="success") button2.callback = CustomJS(args=dict(source=source), code=open( join(dirname(__file__), "download_json.js")).read()) columns = [ TableColumn(field="Year", title="Year"),
doc.add_next_tick_callback(partial(update_bokeh_props, processed_image_obj.glyph.color_mapper, low=new_range[0], high=new_range[1])) @gen.coroutine @without_document_lock def blur_slider_callback(attr, _, new_kernel): ''' Adjust the Gaussian Blur kernel size ''' image = get_image(raw_image_obj) image_blur = apply_gaussian_blur(image, new_kernel) doc.add_next_tick_callback(partial(update_bokeh_dict, processed_image_obj.data_source.data, image=[image_blur])) image_select.on_change('value', image_change_callback) colormap_scale_slider.on_change('value', colormap_scale_callback) blur_slider.on_change('value', blur_slider_callback) # loading_props.js_on_change('num_loaded', get_loading_modal_update_callback()) image_select_widgets = row([image_select, colormap_scale_slider, blur_slider, Spacer()], sizing_mode='scale_width') images_layout = layout([ [raw_image_fig, processed_image_fig], ], sizing_mode='scale_width') images_panel = Panel(child=images_layout, title='Images') center_tabs = Tabs(tabs=[images_panel]) doc.add_root(column([image_select_widgets, center_tabs], sizing_mode='scale_width')) doc.add_root(loading_props)
def click(): #fmin = fmin_s.value #fmax = fmax_s.value fmin = frange_s.range[0] fmax = frange_s.range[1] opt_tau = opt_tau_anal(eps_s.value, 2 * pi * fmin, 2 * pi * fmax) tau_re_s.value = opt_tau.real / (2 * pi * fmax) tau_im_s.value = opt_tau.imag / (2 * pi * fmax) for w in [tau_re_s, tau_im_s]: w.on_change('value', update_data1) eps_s.on_change('value', update_data2) frange_s.on_change('range', update_data2) reset.on_click(click) # Set up layouts and add to document inputs_1 = widgetbox(tau_re_s, tau_im_s) #inputs_2 = widgetbox(Nom_text, fmin_s, fmax_s, eps_s) inputs_2 = widgetbox(frange_s, eps_s) inputs_2 = widgetbox(frange_s, eps_s) inputs_3 = vform(reset) spacer_1 = Spacer(width=20, height=40) spacer_2 = Spacer(width=20, height=40) spacer_3 = Spacer(width=20, height=130) div1 = Div( text= """<font size="4"><b>Seed parameter tau</b></font> <br> (relative w.r.t. f_max)""",
def histogram_tab(flights): # Function to make a dataset for histogram based on a list of carriers # a minimum delay, maximum delay, and histogram bin width def make_dataset(carrier_list, range_start=-60, range_end=120, bin_width=5): # Dataframe to hold information by_carrier = pd.DataFrame(columns=[ 'proportion', 'left', 'right', 'f_proportion', 'f_interval', 'name', 'color' ]) range_extent = range_end - range_start # Iterate through all the carriers for i, carrier_name in enumerate(carrier_list): # Subset to the carrier subset = flights[flights['name'] == carrier_name] # Create a histogram with 5 minute bins arr_hist, edges = np.histogram(subset['arr_delay'], bins=int(range_extent / bin_width), range=[range_start, range_end]) # Divide the counts by the total to get a proportion arr_df = pd.DataFrame({ 'proportion': arr_hist / np.sum(arr_hist), 'left': edges[:-1], 'right': edges[1:] }) # Format the proportion arr_df['f_proportion'] = [ '%0.5f' % proportion for proportion in arr_df['proportion'] ] # Format the interval arr_df['f_interval'] = [ '%d to %d minutes' % (left, right) for left, right in zip(arr_df['left'], arr_df['right']) ] # Assign the carrier for labels arr_df['name'] = carrier_name # Color each carrier differently arr_df['color'] = Category20_16[i] # Add to the overall dataframe by_carrier = by_carrier.append(arr_df) # Overall dataframe by_carrier = by_carrier.sort_values(['name', 'left']) return ColumnDataSource(by_carrier) def style(p): # Title p.title.align = 'center' p.title.text_font_size = '20pt' p.title.text_font = 'serif' # Axis titles p.xaxis.axis_label_text_font_size = '14pt' p.xaxis.axis_label_text_font_style = 'bold' p.yaxis.axis_label_text_font_size = '14pt' p.yaxis.axis_label_text_font_style = 'bold' # Tick labels p.xaxis.major_label_text_font_size = '12pt' p.yaxis.major_label_text_font_size = '12pt' return p def make_plot(src): # Blank plot with correct labels p = figure(plot_width=700, plot_height=700, title='Histogram of Arrival Delays by Airline', x_axis_label='Delay (min)', y_axis_label='Proportion') # Quad glyphs to create a histogram p.quad(source=src, bottom=0, top='proportion', left='left', right='right', color='color', fill_alpha=0.7, hover_fill_color='color', legend='name', hover_fill_alpha=1.0, line_color='black') # Hover tool with vline mode hover = HoverTool(tooltips=[('Carrier', '@name'), ('Delay', '@f_interval'), ('Proportion', '@f_proportion')], mode='vline') p.add_tools(hover) # Styling p = style(p) return p def update(attr, old, new): carriers_to_plot = [ carrier_selection.labels[i] for i in carrier_selection.active ] new_src = make_dataset(carriers_to_plot, range_start=range_select.value[0], range_end=range_select.value[1], bin_width=binwidth_select.value) src.data.update(new_src.data) # Carriers and colors available_carriers = list(set(flights['name'])) available_carriers.sort() airline_colors = Category20_16 airline_colors.sort() carrier_selection = CheckboxGroup(labels=available_carriers, active=[0, 1]) carrier_selection.on_change('active', update) binwidth_select = Slider(start=1, end=30, step=1, value=5, title='Bin Width (min)') binwidth_select.on_change('value', update) range_select = RangeSlider(start=-60, end=180, value=(-60, 120), step=5, title='Range of Delays (min)') range_select.on_change('value', update) # Initial carriers and data source initial_carriers = [ carrier_selection.labels[i] for i in carrier_selection.active ] src = make_dataset(initial_carriers, range_start=range_select.value[0], range_end=range_select.value[1], bin_width=binwidth_select.value) p = make_plot(src) # Put controls in a single element controls = WidgetBox(carrier_selection, binwidth_select, range_select) # Create a row layout layout = row(controls, p) # Make a tab with the layout tab = Panel(child=layout, title='Histogram') return tab
##Create Widgets y_column = Select(title='Variable', value=y_col_init, options=columns) y_column.on_change('value', update_columns) size_column = Select(title='Size', value='constant', options=['constant'] + columns) size_column.on_change('value', update_columns) slider = RangeSlider(start=years[0], end=years[-1], range=(years[0], years[-1]), step=1, title="Years") slider.on_change('range', update_year) region_column = CheckboxGroup(labels=regions[:], active=range(len(regions))) region_column.on_change('active', update_columns) reset_button = Button(label='Reset') reset_button.on_click(reset) #Create initial plot p, sc_source, line_source = make_plot() desc_box = Div(text=update_desc_box()) controls = widgetbox( [y_column, size_column, region_column, slider, reset_button, desc_box], width=430)
'color': df_slice['plot_color'], 'alpha': df_slice['plot_alpha'], 'size': df_slice['plot_size'], 'text': df_slice['comment_text'].str[0:75] + '...', 'flags': df_slice['all_flags'], 'single_flag': df_slice['single_flag'], 'sim_age': df_slice['sim_age'] }).data slider = RangeSlider(start=0, end=30, value=(0, 30), step=1, title='Simulated Age') slider.on_change('value', callback) buttons = CheckboxButtonGroup(labels=buttonlabels, active=[0, 1, 2, 3, 4, 5, 6]) buttons.on_change('active', callback) select = Select(title='Vectorization', value='Bag of Words', options=['Bag of Words', 'Doc2Vec']) select.on_change('value', callback) tooltips = [('Comment', '@text'), ('Flags', '@flags'), ('Age (d)', '@sim_age')] n_obs = df.shape[0] manif = 't-SNE' title = '{} visualization of {} observations'.format(manif, n_obs)
def density_tab(flights): # Dataset for density plot based on carriers, range of delays, # and bandwidth for density estimation def make_dataset(carrier_list, range_start, range_end, bandwidth): xs = [] ys = [] colors = [] labels = [] for i, carrier in enumerate(carrier_list): subset = flights[flights['name'] == carrier] subset = subset[subset['arr_delay'].between( range_start, range_end)] kde = gaussian_kde(subset['arr_delay'], bw_method=bandwidth) # Evenly space x values x = np.linspace(range_start, range_end, 100) # Evaluate pdf at every value of x y = kde.pdf(x) # Append the values to plot xs.append(list(x)) ys.append(list(y)) # Append the colors and label colors.append(airline_colors[i]) labels.append(carrier) new_src = ColumnDataSource(data={ 'x': xs, 'y': ys, 'color': colors, 'label': labels }) return new_src def make_plot(src): p = figure(plot_width=700, plot_height=700, title='Density Plot of Arrival Delays by Airline', x_axis_label='Delay (min)', y_axis_label='Density') p.multi_line('x', 'y', color='color', legend='label', line_width=3, source=src) # Hover tool with next line policy hover = HoverTool(tooltips=[('Carrier', '@label'), ('Delay', '$x'), ('Density', '$y')], line_policy='next') # Add the hover tool and styling p.add_tools(hover) p = style(p) return p def update(attr, old, new): # List of carriers to plot carriers_to_plot = [ carrier_selection.labels[i] for i in carrier_selection.active ] # If no bandwidth is selected, use the default value if bandwidth_choose.active == []: bandwidth = None # If the bandwidth select is activated, use the specified bandwith else: bandwidth = bandwidth_select.value new_src = make_dataset(carriers_to_plot, range_start=range_select.value[0], range_end=range_select.value[1], bandwidth=bandwidth) src.data.update(new_src.data) def style(p): # Title p.title.align = 'center' p.title.text_font_size = '20pt' p.title.text_font = 'serif' # Axis titles p.xaxis.axis_label_text_font_size = '14pt' p.xaxis.axis_label_text_font_style = 'bold' p.yaxis.axis_label_text_font_size = '14pt' p.yaxis.axis_label_text_font_style = 'bold' # Tick labels p.xaxis.major_label_text_font_size = '12pt' p.yaxis.major_label_text_font_size = '12pt' return p # Carriers and colors available_carriers = sorted(set(flights['name'])) airline_colors = Category20_16 airline_colors.sort() # Carriers to plot carrier_selection = CheckboxGroup(labels=available_carriers, active=[0, 1]) carrier_selection.on_change('active', update) # Range to plot range_select = RangeSlider(start=-60, end=180, value=(-60, 120), step=5, title='Delay Range (min)') range_select.on_change('value', update) # Initial carriers and data source initial_carriers = [ carrier_selection.labels[i] for i in carrier_selection.active ] # Bandwidth of kernel bandwidth_select = Slider(start=0.1, end=5, step=0.1, value=0.5, title='Bandwidth for Density Plot') bandwidth_select.on_change('value', update) # Whether to set the bandwidth or have it done automatically bandwidth_choose = CheckboxButtonGroup( labels=['Choose Bandwidth (Else Auto)'], active=[]) bandwidth_choose.on_change('active', update) # Make the density data source src = make_dataset(initial_carriers, range_start=range_select.value[0], range_end=range_select.value[1], bandwidth=bandwidth_select.value) # Make the density plot p = make_plot(src) # Add style to the plot p = style(p) # Put controls in a single element controls = WidgetBox(carrier_selection, range_select, bandwidth_select, bandwidth_choose) # Create a row layout layout = row(controls, p) # Make a tab with the layout tab = Panel(child=layout, title='Density Plot') return tab