예제 #1
0
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
예제 #3
0
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
예제 #5
0
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
예제 #6
0
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
예제 #7
0
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"
예제 #8
0
    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
예제 #9
0
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])
예제 #10
0
파일: most_h.py 프로젝트: mathildemrt/ada
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',
예제 #11
0
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)
예제 #13
0
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
예제 #14
0
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
예제 #16
0
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)
예제 #17
0
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
예제 #18
0
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>&nbsp;&nbsp;</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
예제 #19
0
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')
예제 #20
0
    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
예제 #21
0
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
예제 #22
0
파일: type.py 프로젝트: kz9/cse163-project
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
예제 #23
0
        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)
예제 #24
0
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
예제 #25
0
파일: main.py 프로젝트: sophiarora/bokeh-1
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
예제 #27
0
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
예제 #28
0
파일: main.py 프로젝트: stevenrdungan/mvp
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"),
예제 #29
0
    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)
예제 #30
0

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)""",
예제 #31
0
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
예제 #32
0
##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)
예제 #33
0
            '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)
예제 #34
0
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