Beispiel #1
0
    def _get_title_div(self, key, default_fontsize='15pt', width=450):
        title_div = None
        title = self._format_title(key) if self.show_title else ''
        if not title:
            return title_div

        title_json = theme_attr_json(self.renderer.theme, 'Title')
        color = title_json.get('text_color', None)
        font = title_json.get('text_font', 'Arial')
        fontstyle = title_json.get('text_font_style', 'bold')
        fontsize = self._fontsize('title').get('fontsize', default_fontsize)
        if fontsize == default_fontsize:  # if default
            fontsize = title_json.get('text_font_size', default_fontsize)
            if 'em' in fontsize:
                # it's smaller than it shosuld be so add 0.25
                fontsize = str(float(fontsize[:-2]) + 0.25) + 'em'

        title_tags = self._title_template.format(
            color=color,
            font=font,
            fontstyle=fontstyle,
            fontsize=fontsize,
            title=title)

        if 'title' in self.handles:
            title_div = self.handles['title']
        else:
            title_div = Div(width=width, style={"white-space": "nowrap"})  # so it won't wrap long titles easily
        title_div.text = title_tags

        return title_div
Beispiel #2
0
 def _get_title(self, key):
     title_div = None
     title = self._format_title(key) if self.show_title else ''
     if title:
         fontsize = self._fontsize('title')
         title_tags = self._title_template.format(title=title,
                                                  **fontsize)
         if 'title' in self.handles:
             title_div = self.handles['title']
         else:
             title_div = Div()
         title_div.text = title_tags
     return title_div
Beispiel #3
0
             code="""
     color_mapper.low = Number(this.value)
"""))
map_range_widgets.append(text_input)

# %% Make heading for the whole thing
"""
# %% Make heading for the whole thing
"""
heading = Div(text="""
<h1> Animated COVID-19 Data Mapped For US Counties - NYT Styled</h1>
<p>Shows the continental US heatmapped to the previous weeks average number of COVID-19 cases per 100k people in each county.</p>
<ul>
	<li>Higher color number corresponds to faster spread of the virus.</li>
    <li>On the left of each graph thera are tools to zoom/pan/reset/save.</li>
    <li>Double tap the map to reset zoom/pan.</li>
	<li>On Mobile: Use two finger to scroll the page.</li>
    <li>Data last updated on: {data_update} </li>
</ul>
""".format(
    data_update=pd.to_datetime(latest_data_date).strftime('%Y-%m-%d'),
    graph_update=pd.Timestamp.now().strftime('%Y-%m-%d'),
))

footer = Div(text="""
<h3> Sources </h3>
<ul>
    <li>GitHub repository for this project: <a href="https://github.com/thedrdos/covid-map"> https://github.com/thedrdos/covid-map </a>. </li>
    <li>Produced using Python with Bokeh and other modules.</li>
	<li>Data sourced from <a href="https://github.com/nytimes/covid-19-data"> The New York Times COVID Data GitHub Repository</a>. </li>
</ul>
<h4> Data Defintions: </h4>
Beispiel #4
0
def create_cws_map(df, suffix):
    """Reads in a data-frame and exports a html file, containing a bokeh map, placed within the 'maps' folder.

    Parameters
    ----------
    df : dataframe
        A dataframe that must contain the following columns:
        - geometry
        - p_id
        - lon
        - lat
        - ta_int

    suffix : str
        A string that will be appended to the title of the plots as well as the html file-names.
    """

    tile_provider = get_provider(
        "CARTODBPOSITRON_RETINA"
    )  # More Providers https://docs.bokeh.org/en/latest/docs/reference/tile_providers.html

    # Range bounds supplied in web mercator coordinates
    p = figure(
        x_range=(825000, 833000),
        y_range=(5933000, 5935000),
        x_axis_type="mercator",
        y_axis_type="mercator",  # Changes axis to a more legible input
        x_axis_label="Longitude",
        y_axis_label="Latitude",
        sizing_mode="stretch_both")
    p.add_tile(tile_provider)

    # Filter point sto be added by color
    p = filter_points_by_color(df, p)

    # Add hover tools as a means for interactivity
    my_hover = HoverTool(
    )  # https://automating-gis-processes.github.io/2016/Lesson5-interactive-map-bokeh.html#adding-interactivity-to-the-map

    # Specify what parameters should be displayed when hovering
    my_hover.tooltips = [('Id', '@p_id'), ('Temperature [C]', '@ta_int'),
                         ('Longitude', '@lon'), ('Latitude', '@lat')]
    p.add_tools(my_hover)

    # Creating divs to serve as additional information
    div_title = Div(align="center",
                    text="<h1>Citizen Weather Stations: " + suffix +
                    ":00</h1>",
                    sizing_mode="stretch_both")
    div_subtitle = Div(
        align="center",
        text=
        "Blue: Below 22 °C. <br> Orange: Between 22 °C and 28 °C. <br> Red: Above 28 °C.",
        sizing_mode="stretch_both")

    # Arrange all the bokeh elements in a layout
    layout_plot = layout([[div_title], [div_subtitle], [p]])

    # Specify output location and name
    output_file("../maps/Bern-CWS-Map_" + suffix + ".html")

    # Shows the result in the default browser and saves the file
    show(layout_plot)
Beispiel #5
0
 def view(a):
     return Div(text='%d' % a)
Beispiel #6
0
# sports['sport'] = sport
# sports['sport'] = sports['sport'].str.lower()
# sports['count'] = count.astype(int)
# sports = sports.sort_values(by='count',ascending=False)

# In[32]:


def update(attr, old, new):
    table, m, div0 = create_plot()
    layout.children[2].children[0] = table
    layout.children[2].children[1] = m
    layout.children[0] = div0


div00 = Div(text="<i> Sort and Select</i>")

# 1) Choose borough
div1 = Div(text="<b> Choose Borough</b>")
boros = ['No Preference'] + list(mid_stat.borough.unique())
select1 = Select(options=boros, value=boros[0])
select1.on_change('value', update)

# 2) Mean Scores
div2 = Div(text="<b> Test Score Intervals </b>")
slider21 = RangeSlider(start=150,
                       end=300,
                       value=(150, 300),
                       step=1,
                       title="Math Score")
slider21.on_change('value', update)
Beispiel #7
0
def xrayvis_app(doc):
    def load_wav_cb(attr, old, new):
        '''Handle selection of audio file to be loaded.'''
        if new == '':
            return
        global wavname
        global snd
        spkr, fname = os.path.split(new)
        wavname = get_cached_fname(
            fname,
            f'https://linguistics.berkeley.edu/phonapps/xray_microbeam_database/{spkr}',
            spkr)
        #        wavname = new
        if not wavname.endswith('.wav'):
            return
        snd = parselmouth.Sound(wavname)
        srcdf = pd.DataFrame(
            dict(
                seconds=snd.ts().astype(np.float32),
                ch0=snd.values[0, :].astype(np.float32),
            ))
        #! TODO: do file caching
        phdf = allphdf.loc[allphdf.wavpath == new, :].copy()
        phdf['t1'] = phdf['t1'].astype(np.float32)
        wddf = allwddf.loc[allwddf.wavpath == new, :].copy()
        wddf['t1'] = wddf['t1'].astype(np.float32)
        uttdiv.text = '<b>Utterance:</b> ' + ' '.join(
            wddf.word.str.replace('sp', '')).strip()
        phwddf = pd.merge_asof(phdf[['t1', 'phone']],
                               wddf[['t1', 'word']],
                               on='t1',
                               suffixes=['_ph', '_wd'])
        # TODO: separate t1_ph and t1_wd columns
        srcdf = pd.merge_asof(srcdf, phwddf, left_on='seconds', right_on='t1')
        srcdf[['phone', 'word']] = srcdf[['phone', 'word']].fillna('')
        srcdf = srcdf.drop('t1', axis='columns')
        dfs['srcdf'] = srcdf
        source.data = srcdf
        tngsource.data = {'x': [], 'y': []}
        othsource.data = {'x': [], 'y': []}
        timesource.data = {k: [] for k in timesource.data.keys()}
        lasttngtimesource.data = {'x': [], 'y': []}
        lastothtimesource.data = {'x': [], 'y': []}
        playvisbtn.channels = channels
        playvisbtn.disabled = False
        playselbtn.channels = channels
        playselbtn.disabled = False
        playvisbtn.fs = snd.sampling_frequency
        playvisbtn.start = snd.start_time
        playvisbtn.end = snd.end_time
        playselbtn.fs = snd.sampling_frequency
        playselbtn.start = 0.0
        playselbtn.end = 0.0
        selbox.left = 0.0
        selbox.right = 0.0
        selbox.visible = False
        cursor.location = 0.0
        cursor.visible = False
        ch0.visible = True
        update_sgram()
        load_artic()
        set_limits(0.0, srcdf['seconds'].max())

    def load_artic():
        '''Load articulation data.'''
        trace.title.text = 'Static trace'
        traj.title.text = 'Trajectories'
        tngfile = os.path.splitext(wavname)[0] + '.txy'
        palfile = os.path.join(os.path.dirname(wavname), 'PAL.DAT')
        phafile = os.path.join(os.path.dirname(wavname), 'PHA.DAT')
        tngdf = pd.read_csv(tngfile,
                            sep='\t',
                            names=[
                                'sec', 'ULx', 'ULy', 'LLx', 'LLy', 'T1x',
                                'T1y', 'T2x', 'T2y', 'T3x', 'T3y', 'T4x',
                                'T4y', 'MIx', 'MIy', 'MMx', 'MMy'
                            ])
        # Convert to seconds
        tngdf['sec'] = tngdf['sec'] / 1e6
        tngdf = tngdf.set_index(['sec'])
        # Convert to mm
        tngdf[[
            'ULx', 'ULy', 'LLx', 'LLy', 'T1x', 'T1y', 'T2x', 'T2y', 'T3x',
            'T3y', 'T4x', 'T4y', 'MIx', 'MIy', 'MMx', 'MMy'
        ]] = tngdf[[
            'ULx', 'ULy', 'LLx', 'LLy', 'T1x', 'T1y', 'T2x', 'T2y', 'T3x',
            'T3y', 'T4x', 'T4y', 'MIx', 'MIy', 'MMx', 'MMy'
        ]] * 1e-3
        # Find global x/y max/min in this recording to set axis limits.
        # Exclude bad values (1000000 in data file; 1000 mm in scaled dataframe).
        cmpdf = tngdf[tngdf < badval]
        xmax = np.max(
            np.max(
                cmpdf[['ULx', 'LLx', 'T1x', 'T2x', 'T3x', 'T4x', 'MIx',
                       'MMx']]))
        xmin = np.min(
            np.min(
                cmpdf[['ULx', 'LLx', 'T1x', 'T2x', 'T3x', 'T4x', 'MIx',
                       'MMx']]))
        ymax = np.max(
            np.max(
                cmpdf[['ULy', 'LLy', 'T1y', 'T2y', 'T3y', 'T4y', 'MIy',
                       'MMy']]))
        ymin = np.min(
            np.min(
                cmpdf[['ULy', 'LLy', 'T1y', 'T2y', 'T3y', 'T4y', 'MIy',
                       'MMy']]))

        paldf = pd.read_csv(palfile, sep='\s+', header=None, names=['x', 'y'])
        paldf = paldf * 1e-3
        palsource.data = {'x': paldf['x'], 'y': paldf['y']}
        phadf = pd.read_csv(phafile, sep='\s+', header=None, names=['x', 'y'])
        phadf = phadf * 1e-3
        phasource.data = {'x': phadf['x'], 'y': phadf['y']}

        xmin = np.min([xmin, np.min(paldf['x']), np.min(phadf['x'])])
        xmax = np.max([xmax, np.max(paldf['x']), np.max(phadf['x'])])
        ymin = np.min([ymin, np.min(paldf['y']), np.min(phadf['y'])])
        ymax = np.max([ymax, np.max(paldf['y']), np.max(phadf['y'])])
        xsz = xmax - xmin
        ysz = ymax - ymin
        xrng = [xmin - (xsz * 0.05), xmax + (xsz * 0.05)]
        yrng = [ymin - (ysz * 0.05), ymax + (ysz * 0.05)]
        dfs['tngdf'] = tngdf
        dfs['paldf'] = paldf
        dfs['phadf'] = phadf

    def update_sgram():
        '''Update spectrogram based on current values.'''
        if snd.end_time < 15:
            sgrams[0] = snd2specgram(snd, 0.005)
            specsource.data = dict(
                sgram0=[sgrams[0].values.astype(np.float32)])
            spec0img.glyph.dw = sgrams[0].x_grid().max()
            spec0img.glyph.dh = sgrams[0].y_grid().max()
            spec0cmap.low = _low_thresh()
            spec0.visible = True
        else:
            specsource.data = dict(sgram0=[])
            spec0.visible = False

    def update_trace():
        '''Update the static trace at the cursor time.'''
        trace.title.text = f'Static trace ({cursor.location:0.4f})'
        tidx = dfs['tngdf'].index.get_loc(cursor.location, method='nearest')
        row = dfs['tngdf'].iloc[tidx]
        tngsource.data = {
            'x': [row.T1x, row.T2x, row.T3x, row.T4x],
            'y': [row.T1y, row.T2y, row.T3y, row.T4y]
        }
        othsource.data = {
            'x': [row.ULx, row.LLx, row.MIx, row.MMx],
            'y': [row.ULy, row.LLy, row.MIy, row.MMy]
        }

    def update_traj():
        '''Update the trajectories during the selected time range.'''
        traj.title.text = f'Trajectories ({selbox.left:0.4f} - {selbox.right:0.4f})'
        seldf = dfs['tngdf'].loc[(dfs['tngdf'].index >= selbox.left)
                                 & (dfs['tngdf'].index <= selbox.right)]
        dfs['seldf'] = seldf
        pts = ('T1x', 'T1y', 'T2x', 'T2y', 'T3x', 'T3y', 'T4x', 'T4y', 'ULx',
               'ULy', 'LLx', 'LLy', 'MIx', 'MIy', 'MMx', 'MMy')
        # Create a list of line segments for each tracked element.
        newdata = {
            pt: list(np.squeeze(np.dstack((seldf[pt].iloc[:-1], seldf[pt].iloc[1:])))) \
                for pt in pts
        }
        newdata['color'] = np.arange(1, len(seldf))
        newdata['sec'] = seldf.index[1:]
        timesource.data = newdata
        anim_slider.start = seldf.index[0]
        anim_slider.end = seldf.index[-1]
        anim_slider.step = np.diff(newdata['sec']).mean()
        anim_slider.value = anim_slider.end
        anim_slider.disabled = False
        anim_btn.disabled = False
        lastrow = seldf.iloc[-1]
        lasttngtimesource.data = {
            'x': [lastrow.T1x, lastrow.T2x, lastrow.T3x, lastrow.T4x],
            'y': [lastrow.T1y, lastrow.T2y, lastrow.T3y, lastrow.T4y]
        }
        lastothtimesource.data = {
            'x': [lastrow.ULx, lastrow.LLx, lastrow.MIx, lastrow.MMx],
            'y': [lastrow.ULy, lastrow.LLy, lastrow.MIy, lastrow.MMy]
        }

    # TODO: this is a workaround until we can set x_range, y_range directly
    # See https://github.com/bokeh/bokeh/issues/4014
    def set_limits(xstart, xend):
        '''Set axis limits.'''
        ch0.x_range.start = xstart
        ch0.x_range.end = xend
        ch0.axis[0].bounds = (xstart, xend)

    def update_select_widgets(clicked_x=None):
        '''Update widgets based on current selection. Use the clicked_x param to
        designate the cursor location if this function is called as the result of
        a Tap event. If clicked_x is None, then use the existing cursor location
        to set the center of the selection.'''
        mode = selmodebtn.labels[selmodebtn.active]
        if clicked_x is None and cursor.visible:
            x_loc = cursor.location
        elif clicked_x is not None:
            x_loc = clicked_x
        else:
            return
        if mode == '200ms':
            start = x_loc - 0.100
            end = x_loc + 0.100
            cursor.location = x_loc
        else:  # 'word' or 'phone'
            idx = np.abs(source.data['seconds'] - x_loc).argmin()
            # TODO: clean up the redundancy
            fld = {'word': 'word', 'phone': 'phone'}[mode]
            label = source.data[fld][idx]
            indexes = nonzero_groups(source.data[fld] == label,
                                     include_any=idx)
            secs = source.data['seconds'][indexes]
            start = secs.min()
            end = secs.max()
            cursor.location = secs.mean()
        playselbtn.start = start
        playselbtn.end = end
        selbox.left = start
        selbox.right = end
        selbox.visible = True
        cursor.visible = True

    def spkr_select_cb(attr, old, new):
        '''Respond to changes in speaker multiselect.'''
        try:
            spkrs = demo[
                (demo.sex.isin(sex_select.value) \
                & demo.dialect_base_state.isin(state_select.value) \
                & (demo.dialect_base_city.isin(city_select.value)))
            ].subject.unique()
            new_opts = [''] + [(f.value, f.label) for f in fileoptsdf[
                fileoptsdf.speaker.isin(spkrs)].itertuples()]
            fselect.options = new_opts
            fselect.value = ''
        except NameError as e:
            pass  # Values not set yet, so ignore

    def cursor_cb(e):
        '''Handle cursor mouse click in the waveform.'''
        update_select_widgets(clicked_x=e.x)
        update_trace()
        update_traj()

    def x_range_cb(attr, old, new):
        '''Handle change of x range in waveform/spectrogram.'''
        if attr == 'start':
            playvisbtn.start = new
        elif attr == 'end':
            playvisbtn.end = new

    def selection_cb(e):
        '''Handle data range selection event.'''
        #! TODO: handle situation in which selection is too short, i.e. len(seldf) <= 1
        cursor.location = (e.geometry['x0'] + e.geometry['x1']) / 2
        cursor.visible = True
        playselbtn.start = e.geometry['x0']
        playselbtn.end = e.geometry['x1']
        selbox.left = e.geometry['x0']
        selbox.right = e.geometry['x1']
        selbox.visible = True
        update_trace()
        update_traj()

    def selmode_cb(attr, old, new):
        '''Handle change in click selection value.'''
        update_select_widgets(clicked_x=None)

    def anim_cb(attr, old, new):
        '''Handle change in the animation slider.'''
        idx = np.argmin(np.abs(timesource.data['sec'] - new))
        n = len(timesource.data['color'])
        active = np.arange(n - idx, n + 1)
        timesource.data['color'] = np.pad(active, (0, n - len(active)),
                                          constant_values=0)
        anim_cmap = LinearColorMapper(palette=r_Greys256,
                                      low=1,
                                      high=n + 1,
                                      low_color='white')
        for tag, palette in (('anim_tng', r_Reds9), ('anim_oth', r_Greens9)):
            for a in find(traj.references(), {'tags': tag}):
                a.line_color = linear_cmap('color',
                                           palette,
                                           low=1,
                                           high=n + 1,
                                           low_color='white')
        lasttngtimesource.data = {
            'x': [
                timesource.data[pt][idx][1]
                for pt in ('T1x', 'T2x', 'T3x', 'T4x')
            ],
            'y': [
                timesource.data[pt][idx][1]
                for pt in ('T1y', 'T2y', 'T3y', 'T4y')
            ]
        }
        lastothtimesource.data = {
            'x': [
                timesource.data[pt][idx][1]
                for pt in ('ULx', 'LLx', 'MIx', 'MMx')
            ],
            'y': [
                timesource.data[pt][idx][1]
                for pt in ('ULy', 'LLy', 'MIy', 'MMy')
            ]
        }

    def anim_btn_cb():
        '''Handle click of anim_btn animate trajectories of selected audio.'''
        values = np.linspace(anim_slider.start, anim_slider.end,
                             len(timesource.data['T1x']))
        for v in values:
            anim_slider.value = v

    def low_thresh_cb(attr, old, new):
        '''Handle change in threshold slider to fade out low spectrogram values.'''
        params['low_thresh_power'] = new
        lt = _low_thresh()
        spec0cmap.low = lt

    def _low_thresh():
        return sgrams[0].values.min() \
               + sgrams[0].values.std()**params['low_thresh_power']

    step = None
    rate = orig_rate = None
    #    dfs = {}
    xrng = []
    yrng = []
    width = 1000
    height = 200
    cutoff = 50
    order = 3
    tngcolor = 'DarkRed'
    othcolor = 'Indigo'
    fselect = Select(options=[], value='')
    fselect.on_change('value', load_wav_cb)
    sex_select = MultiSelect(options=[('F', 'female'), ('M', 'male')],
                             value=['F', 'M'])
    state_select = MultiSelect(
        options=list(demo.dialect_base_state.cat.categories),
        value=list(demo.dialect_base_state.cat.categories))
    city_select = MultiSelect(
        options=list(demo.dialect_base_city.cat.categories),
        value=list(demo.dialect_base_city.cat.categories))
    sex_select.on_change('value', spkr_select_cb)
    state_select.on_change('value', spkr_select_cb)
    city_select.on_change('value', spkr_select_cb)
    spkr_select_cb('', '', '')

    source = ColumnDataSource(data=dict(seconds=[], ch0=[]))
    channels = ['ch0']

    playvisbtn = AudioButton(label='Play visible signal',
                             source=source,
                             channels=channels,
                             width=120,
                             disabled=True)
    playselbtn = AudioButton(label='Play selected signal',
                             source=source,
                             channels=channels,
                             width=120,
                             disabled=True)
    selmodebtn = RadioButtonGroup(labels=['200ms', 'word', 'phone'], active=1)
    selmodebtn.on_change('active', selmode_cb)
    # Instantiate and share specific select/zoom tools so that
    # highlighting is synchronized on all plots.
    boxsel = BoxSelectTool(dimensions='width')
    spboxsel = BoxSelectTool(dimensions='width')
    boxzoom = BoxZoomTool(dimensions='width')
    zoomin = ZoomInTool(dimensions='width')
    zoomout = ZoomOutTool(dimensions='width')
    crosshair = CrosshairTool(dimensions='height')
    shared_tools = [
        'xpan', boxzoom, boxsel, crosshair, zoomin, zoomout, 'reset'
    ]

    uttdiv = Div(text='')

    figargs = dict(tools=shared_tools, )
    cursor = Span(dimension='height',
                  line_color='red',
                  line_dash='dashed',
                  line_width=1)
    wavspec_height = 280
    ch0 = figure(name='ch0',
                 tooltips=[('time', '$x{0.0000}'), ('word', '@word'),
                           ('phone', '@phone')],
                 height=wavspec_height,
                 **figargs)
    ch0.toolbar.logo = None
    ch0.line(x='seconds', y='ch0', source=source, nonselection_line_alpha=0.6)
    # Link pan, zoom events for plots with x_range.
    ch0.x_range.on_change('start', x_range_cb)
    ch0.x_range.on_change('end', x_range_cb)
    ch0.on_event(SelectionGeometry, selection_cb)
    ch0.on_event(Tap, cursor_cb)
    ch0.add_layout(cursor)
    wavtab = Panel(child=ch0, title='Waveform')
    selbox = BoxAnnotation(name='selbox',
                           left=None,
                           right=None,
                           fill_color='green',
                           fill_alpha=0.1,
                           line_color='green',
                           line_width=1.5,
                           line_dash='dashed',
                           visible=False)
    ch0.add_layout(selbox)
    sgrams = [np.ones((1, 1))]
    specsource = ColumnDataSource(data=dict(sgram0=[sgrams[0]]))
    spec0 = figure(
        name='spec0',
        x_range=ch0.x_range,  # Keep times synchronized
        tooltips=[("time", "$x{0.0000}"), ("freq", "$y{0.0000}"),
                  ("value", "@sgram0{0.000000}")],
        height=wavspec_height,
        **figargs)
    spec0.toolbar.logo = None
    spec0.x_range.on_change('start', x_range_cb)
    spec0.x_range.on_change('end', x_range_cb)
    spec0.on_event(SelectionGeometry, selection_cb)
    spec0.on_event(Tap, cursor_cb)
    spec0.add_layout(cursor)
    spec0.x_range.range_padding = spec0.y_range.range_padding = 0
    spec0cmap = LogColorMapper(palette=r_Greys256,
                               low_color=params['low_thresh_color'])
    low_thresh_slider = Slider(start=1.0,
                               end=12.0,
                               step=0.03125,
                               value=params['low_thresh_power'],
                               title='Spectrogram threshold')
    low_thresh_slider.on_change('value', low_thresh_cb)
    spec0img = spec0.image(image='sgram0',
                           x=0,
                           y=0,
                           color_mapper=spec0cmap,
                           level='image',
                           source=specsource)
    spec0.grid.grid_line_width = 0.0
    spec0.add_layout(selbox)
    sgramtab = Panel(child=spec0, title='Spectrogram')

    tngsource = ColumnDataSource(data={'x': [], 'y': []})
    othsource = ColumnDataSource(data={'x': [], 'y': []})
    timesource = ColumnDataSource({
        'T1x': [],
        'T1y': [],
        'T2x': [],
        'T2y': [],
        'T3x': [],
        'T3y': [],
        'T4x': [],
        'T4y': [],
        'ULx': [],
        'ULy': [],
        'LLx': [],
        'LLy': [],
        'MIx': [],
        'MIy': [],
        'MMx': [],
        'MMy': [],
        'color': [],
        'sec': []
    })
    lasttngtimesource = ColumnDataSource(data={'x': [], 'y': []})
    lastothtimesource = ColumnDataSource(data={'x': [], 'y': []})
    palsource = ColumnDataSource(pd.DataFrame({'x': [], 'y': []}))
    phasource = ColumnDataSource(pd.DataFrame({'x': [], 'y': []}))

    trace = figure(width=500,
                   height=300,
                   title='Static trace',
                   x_range=(-100.0, 25.0),
                   y_range=(-37.650, 37.650),
                   tools=[],
                   tags=['xray', 'static_fig'])
    trace.toolbar.logo = None
    trace.circle('x',
                 'y',
                 source=tngsource,
                 size=3,
                 color=tngcolor,
                 tags=['update_xray'])
    trace.circle('x',
                 'y',
                 source=othsource,
                 size=3,
                 color=othcolor,
                 tags=['update_xray'])
    trace.line('x',
               'y',
               source=tngsource,
               color=tngcolor,
               tags=['update_xray'])
    trace.line('x', 'y', source=palsource, color='black')
    trace.line('x', 'y', source=phasource, color='black')

    traj = figure(width=500,
                  height=300,
                  title='Trajectories',
                  x_range=(-100.0, 25.0),
                  y_range=(-37.650, 37.650),
                  tools=[],
                  tags=['xray', 'trajectory_fig'])
    traj.toolbar.logo = None
    traj.multi_line('T1x', 'T1y', source=timesource, tags=['anim_tng'])
    traj.multi_line('T2x', 'T2y', source=timesource, tags=['anim_tng'])
    traj.multi_line('T3x', 'T3y', source=timesource, tags=['anim_tng'])
    traj.multi_line('T4x', 'T4y', source=timesource, tags=['anim_tng'])
    traj.multi_line('ULx', 'ULy', source=timesource, tags=['anim_oth'])
    traj.multi_line('LLx', 'LLy', source=timesource, tags=['anim_oth'])
    traj.multi_line('MIx', 'MIy', source=timesource, tags=['anim_oth'])
    traj.multi_line('MMx', 'MMy', source=timesource, tags=['anim_oth'])
    traj.circle('x', 'y', source=lasttngtimesource, color=tngcolor)
    traj.circle('x', 'y', source=lastothtimesource, color=othcolor)
    traj.line('x', 'y', source=lasttngtimesource, color='lightgray')
    traj.line('x', 'y', source=palsource, color='black')
    traj.line('x', 'y', source=phasource, color='black')

    anim_slider = Slider(start=0,
                         end=100,
                         step=1,
                         value=0,
                         width=240,
                         format='0.000f',
                         title='Selected trajectory',
                         orientation='horizontal',
                         disabled=True)
    anim_slider.on_change('value', anim_cb)
    anim_btn = Button(label='Animate', width=120, disabled=True)
    anim_btn.on_click(anim_btn_cb)

    audtabs = Tabs(tabs=[wavtab, sgramtab])
    mainLayout = column(
        row(sex_select, state_select, city_select),
        row(fselect),
        row(
            column(uttdiv, audtabs),
            column(
                #!                row(anim_slider, anim_btn),
                column(Div(text='Click selection mode:'), selmodebtn,
                       low_thresh_slider),
                row(playvisbtn, playselbtn))),
        row(trace, traj),
        name='mainLayout')
    doc.add_root(mainLayout)
    return doc
Beispiel #8
0
 def view(self):
     return Div(text='%d' % self.a)
Beispiel #9
0
def salt_app(doc):

    import app.bokeh.salt_config as cfg

    # TODO: abstract parts of this to a separate file
    # TODO: following above, make parts reusable?

    # load continuous CTD data and make into a dict (only ~20MB)
    file_list = sorted(
        glob.glob("/Users/mkovatch/Documents/ctdcal/data/pressure/*.csv"))
    ssscc_list = [
        ssscc.strip("/Users/mkovatch/Documents/ctdcal/data/pressure/")[:5]
        for ssscc in file_list
    ]
    ctd_data = []
    for f in file_list:
        df = pd.read_csv(f,
                         header=12,
                         skiprows=[13],
                         skipfooter=1,
                         engine="python")
        df["SSSCC"] = f.strip(
            "/Users/mkovatch/Documents/ctdcal/data/pressure/")[:5]
        ctd_data.append(df)
    ctd_data = pd.concat(ctd_data, axis=0, sort=False)

    # load bottle trip file
    file_list = sorted(
        glob.glob("/Users/mkovatch/Documents/ctdcal/data/bottle/*.pkl"))
    ssscc_list = [
        ssscc.strip("/Users/mkovatch/Documents/ctdcal/data/bottle/")[:5]
        for ssscc in file_list
    ]
    upcast_data = []
    for f in file_list:
        with open(f, "rb") as x:
            df = pickle.load(x)
            df["SSSCC"] = f.strip(
                "/Users/mkovatch/Documents/ctdcal/data/bottle/")[:5]
            # change to secondary if that is what's used
            upcast_data.append(df[["SSSCC", "CTDCOND1", "CTDTMP1", "CTDPRS"]])
    upcast_data = pd.concat(upcast_data, axis=0, sort=False)
    upcast_data["CTDSAL"] = gsw.SP_from_C(upcast_data["CTDCOND1"],
                                          upcast_data["CTDTMP1"],
                                          upcast_data["CTDPRS"])

    # load salt file (adapted from compare_salinities.ipynb)
    file_list = sorted(
        glob.glob("/Users/mkovatch/Documents/ctdcal/data/salt/*.csv"))
    ssscc_list = [
        ssscc.strip("/Users/mkovatch/Documents/ctdcal/data/salt/")[:5]
        for ssscc in file_list
    ]
    salt_data = []
    for f in file_list:
        df = pd.read_csv(f, usecols=["STNNBR", "CASTNO", "SAMPNO", "SALNTY"])
        df["SSSCC"] = f.strip(
            "/Users/mkovatch/Documents/ctdcal/data/salt/")[:5]
        salt_data.append(df)
    salt_data = pd.concat(salt_data, axis=0, sort=False)
    salt_data["SALNTY"] = salt_data["SALNTY"].round(4)
    if "SALNTY_FLAG_W" not in salt_data.columns:
        salt_data["SALNTY_FLAG_W"] = 2

    # load ctd btl data
    df_ctd_btl = pd.read_csv(
        "/Users/mkovatch/Documents/ctdcal/data/scratch_folder/ctd_to_bottle.csv",
        skiprows=[1],
        skipfooter=1,
        engine="python",
    )
    df_btl_all = pd.merge(df_ctd_btl,
                          salt_data,
                          on=["STNNBR", "CASTNO", "SAMPNO"])
    btl_data = df_btl_all.loc[:, [
        "SSSCC",
        "SAMPNO",
        "CTDPRS",
        "CTDTMP",
        "REFTMP",
        "CTDSAL",
        "SALNTY",
        "SALNTY_FLAG_W",
    ], ]
    btl_data["Residual"] = btl_data["SALNTY"] - btl_data["CTDSAL"]
    btl_data[["CTDPRS", "Residual"]] = btl_data[["CTDPRS",
                                                 "Residual"]].round(4)
    btl_data["Comments"] = ""
    btl_data["New Flag"] = btl_data["SALNTY_FLAG_W"].copy()

    # update with old handcoded flags if file exists
    handcoded_file = "salt_flags_handcoded.csv"
    if glob.glob(handcoded_file):
        handcodes = pd.read_csv(handcoded_file,
                                dtype={"SSSCC": str},
                                keep_default_na=False)
        handcodes = handcodes.rename(columns={
            "salinity_flag": "New Flag"
        }).drop(columns="diff")
        # there's gotta be a better way. but this is good enough for now
        btl_data = btl_data.merge(handcodes,
                                  on=["SSSCC", "SAMPNO"],
                                  how="left")
        merge_rows = ~btl_data["New Flag_y"].isnull(
        ) | ~btl_data["Comments_y"].isnull()
        btl_data.loc[merge_rows, "New Flag_x"] = btl_data.loc[merge_rows,
                                                              "New Flag_y"]
        btl_data.loc[merge_rows, "Comments_x"] = btl_data.loc[merge_rows,
                                                              "Comments_y"]
        btl_data = btl_data.rename(columns={
            "New Flag_x": "New Flag",
            "Comments_x": "Comments"
        }).drop(columns=["New Flag_y", "Comments_y"])

    # intialize widgets
    save_button = Button(label="Save flagged data", button_type="success")
    parameter = Select(title="Parameter",
                       options=["CTDSAL", "CTDTMP"],
                       value="CTDSAL")
    ref_param = Select(title="Reference", options=["SALNTY"], value="SALNTY")
    # ref_param.options = ["foo","bar"]  # can dynamically change dropdowns
    station = Select(title="Station", options=ssscc_list, value=ssscc_list[0])
    # explanation of flags:
    # https://cchdo.github.io/hdo-assets/documentation/manuals/pdf/90_1/chap4.pdf
    flag_list = MultiSelect(
        title="Plot data flagged as:",
        value=["1", "2", "3"],
        options=cfg.flag_options,
    )  # returns list of select options, e.g., ['2'] or ['1','2']
    flag_input = Select(
        title="Flag:",
        options=cfg.flag_options,
        value="3",
    )
    comment_box = TextInput(value="", title="Comment:")
    # button_type: default, primary, success, warning or danger
    flag_button = Button(label="Apply to selected", button_type="primary")
    comment_button = Button(label="Apply to selected", button_type="warning")

    vspace = Div(text=""" """, width=200, height=65)
    bulk_flag_text = Div(
        text="""<br><br>
        <b>Bulk Bottle Flagging:</b><br>
        Select multiple bottles using the table
        (with shift/control) or the 'Box Select' tool on the plot.""",
        width=150,
        height=135,
    )

    # set up plot datasources
    src_plot_trace = ColumnDataSource(data=dict(x=[], y=[]))
    src_plot_ctd = ColumnDataSource(data=dict(x=[], y=[]))
    src_plot_upcast = ColumnDataSource(data=dict(x=[], y=[]))
    src_plot_btl = ColumnDataSource(data=dict(x=[], y=[]))

    # set up plots
    fig = figure(
        title="{} vs CTDPRS [Station {}]".format(parameter.value,
                                                 station.value),
        tools="pan,box_zoom,wheel_zoom,box_select,reset",
        y_axis_label="Pressure (dbar)",
    )
    fig.select(BoxSelectTool).select_every_mousemove = False
    fig.y_range.flipped = True  # invert y-axis
    fig.line(
        "x",
        "y",
        line_color="#000000",
        line_width=2,
        source=src_plot_trace,
        legend_label="CTD Trace",
    )
    btl_sal = fig.asterisk(
        "x",
        "y",
        size=12,
        line_width=1.5,
        color="#0033CC",
        source=src_plot_btl,
        legend_label="Bottle sample",
    )
    ctd_sal = fig.circle(
        "x",
        "y",
        size=7,
        color="#BB0000",
        source=src_plot_ctd,
        legend_label="Downcast CTD sample",
    )
    upcast_sal = fig.triangle(
        "x",
        "y",
        size=7,
        color="#00BB00",
        source=src_plot_upcast,
        legend_label="Upcast CTD sample",
    )
    fig.legend.location = "bottom_left"
    fig.legend.border_line_width = 3
    fig.legend.border_line_alpha = 1
    btl_sal.nonselection_glyph.line_alpha = 0.2
    ctd_sal.nonselection_glyph.fill_alpha = 1  # makes CTDSAL *not* change on select
    upcast_sal.nonselection_glyph.fill_alpha = 1  # makes CTDSAL *not* change on select

    # define callback functions

    def update_selectors():

        print("exec update_selectors()")
        ctd_rows = ctd_data["SSSCC"] == station.value
        table_rows = btl_data["SSSCC"] == station.value
        btl_rows = (btl_data["New Flag"].isin(
            flag_list.value)) & (btl_data["SSSCC"] == station.value)

        # update table data
        current_table = btl_data[table_rows].reset_index()
        src_table.data = {  # this causes edit_flag() to execute
            "SSSCC": current_table["SSSCC"],
            "SAMPNO": current_table["SAMPNO"],
            "CTDPRS": current_table["CTDPRS"],
            "CTDSAL": current_table["CTDSAL"],
            "SALNTY": current_table["SALNTY"],
            "diff": current_table["Residual"],
            "flag": current_table["New Flag"],
            "Comments": current_table["Comments"],
        }

        # update plot data
        src_plot_trace.data = {
            "x": ctd_data.loc[ctd_rows, parameter.value],
            "y": ctd_data.loc[ctd_rows, "CTDPRS"],
        }
        src_plot_ctd.data = {
            "x": btl_data.loc[table_rows, parameter.value],
            "y": btl_data.loc[table_rows, "CTDPRS"],
        }
        src_plot_upcast.data = {
            "x": upcast_data.loc[upcast_data["SSSCC"] == station.value,
                                 "CTDSAL"],
            "y": upcast_data.loc[upcast_data["SSSCC"] == station.value,
                                 "CTDPRS"],
        }
        src_plot_btl.data = {
            "x": btl_data.loc[btl_rows, "SALNTY"],
            "y": btl_data.loc[btl_rows, "CTDPRS"],
        }

        # update plot labels/axlims
        fig.title.text = "{} vs CTDPRS [Station {}]".format(
            parameter.value, station.value)
        fig.xaxis.axis_label = parameter.value

        # deselect all datapoints
        btl_sal.data_source.selected.indices = []
        src_table.selected.indices = []

    def edit_flag():

        print("exec edit_flag()")

        btl_data.loc[btl_data["SSSCC"] == src_table.data["SSSCC"].values[0],
                     "New Flag", ] = src_table.data["flag"].values
        btl_data.loc[btl_data["SSSCC"] == src_table.data["SSSCC"].values[0],
                     "Comments", ] = src_table.data["Comments"].values

        edited_rows = (btl_data["New Flag"].isin(
            [3, 4])) | (btl_data["Comments"] != "")

        src_table_changed.data = {
            "SSSCC": btl_data.loc[edited_rows, "SSSCC"],
            "SAMPNO": btl_data.loc[edited_rows, "SAMPNO"],
            "diff": btl_data.loc[edited_rows, "Residual"],
            "flag_old": btl_data.loc[edited_rows, "SALNTY_FLAG_W"],
            "flag_new": btl_data.loc[edited_rows, "New Flag"],
            "Comments": btl_data.loc[edited_rows, "Comments"],
        }

    def apply_flag():

        print("Applying flags")

        table_rows = btl_data["SSSCC"] == station.value
        selected_rows = src_table.selected.indices

        # update table data
        current_table = btl_data[table_rows].reset_index()
        current_table.loc[selected_rows, "New Flag"] = int(flag_input.value)
        src_table.data = {  # this causes edit_flag() to execute
            "SSSCC": current_table["SSSCC"],
            "SAMPNO": current_table["SAMPNO"],
            "CTDPRS": current_table["CTDPRS"],
            "CTDSAL": current_table["CTDSAL"],
            "SALNTY": current_table["SALNTY"],
            "diff": current_table["Residual"],
            "flag": current_table["New Flag"],
            "Comments": current_table["Comments"],
        }

    def apply_comment():

        print("Applying Comments")

        table_rows = btl_data["SSSCC"] == station.value
        selected_rows = src_table.selected.indices

        # update table data
        current_table = btl_data[table_rows].reset_index()
        current_table.loc[selected_rows, "Comments"] = comment_box.value
        src_table.data = {  # this causes edit_flag() to execute
            "SSSCC": current_table["SSSCC"],
            "SAMPNO": current_table["SAMPNO"],
            "CTDPRS": current_table["CTDPRS"],
            "CTDSAL": current_table["CTDSAL"],
            "SALNTY": current_table["SALNTY"],
            "diff": current_table["Residual"],
            "flag": current_table["New Flag"],
            "Comments": current_table["Comments"],
        }

    def save_data():

        print("Saving flagged data...")

        # get data from table
        df_out = pd.DataFrame.from_dict(src_table_changed.data)

        # minor changes to columns/names/etc.
        df_out = df_out.rename(columns={
            "flag_new": "salinity_flag"
        }).drop(columns="flag_old")

        # save it
        df_out.to_csv("salt_flags_handcoded.csv", index=None)

    def selected_from_plot(attr, old, new):
        src_table.selected.indices = new

    def selected_from_table(attr, old, new):
        btl_sal.data_source.selected.indices = new

    # set up DataTables
    src_table = ColumnDataSource(data=dict())
    src_table_changed = ColumnDataSource(data=dict())
    columns = bk.build_columns(
        cfg.cast_columns["fields"],
        cfg.cast_columns["titles"],
        cfg.cast_columns["widths"],
    )
    columns_changed = bk.build_columns(
        cfg.changes_columns["fields"],
        cfg.changes_columns["titles"],
        cfg.changes_columns["widths"],
    )
    data_table = DataTable(
        source=src_table,
        columns=columns,
        index_width=20,
        width=480 + 20,  # sum of col widths + idx width
        height=600,
        editable=True,
        fit_columns=True,
        sortable=False,
    )
    data_table_changed = DataTable(
        source=src_table_changed,
        columns=columns_changed,
        index_width=20,
        width=480 + 20,  # sum of col widths + idx width
        height=200,
        editable=False,
        fit_columns=True,
        sortable=False,
    )
    data_table_title = Div(text="""<b>All Station Data:</b>""",
                           width=200,
                           height=15)
    data_table_changed_title = Div(text="""<b>Flagged Data:</b>""",
                                   width=200,
                                   height=15)

    # set up change callbacks
    parameter.on_change("value", lambda attr, old, new: update_selectors())
    station.on_change("value", lambda attr, old, new: update_selectors())
    flag_list.on_change("value", lambda attr, old, new: update_selectors())
    flag_button.on_click(apply_flag)
    comment_button.on_click(apply_comment)
    save_button.on_click(save_data)
    src_table.on_change("data", lambda attr, old, new: edit_flag())
    src_table.selected.on_change("indices", selected_from_table)
    btl_sal.data_source.selected.on_change("indices", selected_from_plot)

    # format document
    controls = column(
        parameter,
        ref_param,
        station,
        flag_list,
        bulk_flag_text,
        flag_input,
        flag_button,
        comment_box,
        comment_button,
        vspace,
        save_button,
        width=170,
    )
    tables = column(data_table_title, data_table, data_table_changed_title,
                    data_table_changed)
    doc.add_root(row(controls, tables, fig))
    doc.theme = Theme(filename="theme.yaml")

    update_selectors()
Beispiel #10
0
from bokeh.models import ColumnDataSource, Div
from bokeh.models.widgets import Slider, Select, TextInput
from bokeh.io import curdoc
from bokeh.sampledata.movies_data import movie_path


import bokeh
import netCDF4

#from collections import Dict


varoptions = ["None"]
dimoptions = ["None"]

desc = Div(text=open(join(dirname(__file__), "description.html")).read(), width=800)

# Create Input controls
#reviews = Slider(title="Minimum number of reviews", value=80, start=10, end=300, step=10)

x_axis = Select(title="X Axis", options=varoptions, value="None")
y_axis = Select(title="Y Axis", options=varoptions, value="None")
variable_axis = Select(title="Color", options=varoptions, value="None")

# Create Column Data Source that will be used by the plot
source = ColumnDataSource(data=dict(x=[], y=[], color=[]))

p = figure(plot_height=600, plot_width=700, title="", toolbar_location=None)
p.circle(x="x", y="y", color="color", source=source, size=7, line_color=None)

Beispiel #11
0
class Fit1DVisualizer(interactive.PrimitiveVisualizer):
    """
    The generic class for interactive fitting of one or more 1D functions

    Attributes:
        reinit_panel: layout containing widgets that control the parameters
                      affecting the initialization of the (x,y) array(s)
        reinit_button: the button to reconstruct the (x,y) array(s)
        tabs: layout containing all the stuff required for an interactive 1D fit
        submit_button: the button signifying a successful end to the interactive session

        config: the Config object describing the parameters are their constraints
        widgets: a dict of (param_name, widget) elements that allow the properties
                 of the widgets to be set/accessed by the calling primitive. So far
                 I'm only including the widgets in the reinit_panel
        fits: list of InteractiveModel instances, one per (x,y) array
    """
    def __init__(self,
                 data_source,
                 fitting_parameters,
                 config,
                 reinit_params=None,
                 reinit_extras=None,
                 reinit_live=False,
                 order_param="order",
                 tab_name_fmt='{}',
                 xlabel='x',
                 ylabel='y',
                 domains=None,
                 function=None,
                 title=None,
                 **kwargs):
        """
        Parameters
        ----------
        data_source : array or function
            input data or the function to calculate the input data.  The input data
            should be [x, y] or [x, y, weights] or [[x, y], [x, y],.. or [[x, y, weights], [x, y, weights]..
            or, if a function, it accepts (config, extras) where extras is a dict of values based on reinit_extras
            and returns [[x, y], [x, y].. or [[x, y, weights], [x, y, weights], ...
        fitting_parameters : list of :class:`~geminidr.interactive.fit.fit1d.FittingParameters` or :class:`~geminidr.interactive.fit.fit1d.FittingParameters`
            Description of parameters to use for `fit_1d`
        config : Config instance describing primitive parameters and limitations
        reinit_params : list of str
            list of parameter names in config related to reinitializing fit arrays.  These cause the `data_source`
            function to be run to get the updated coordinates/weights.  Should not be passed if `data_source` is
            not a function.
        reinit_extras :
            Extra parameters to show on the left side that can affect the output of `data_source` but
            are not part of the primitive configuration.  Should not be passed if `data_source` is not a function.
        reinit_live :
            If False, supplies a button to call the `data_source` function and doesn't do so automatically when inputs
            are adjusted.  If `data_source` is known to be inexpensive, you can set this to `True`
        order_param : str
            Name of the parameter this primitive uses for `order`, to infer the min/max suggested values
        tab_name_fmt : str
            Format string for naming the tabs
        xlabel : str
            String label for X axis
        ylabel : str
            String label for Y axis
        domains : list
            List of domains for the inputs
        function : str
            ID of fit_1d function to use, if not a configuration option
        title : str
            Title for UI (Interactive <Title>)
        """
        super().__init__(config=config, title=title)

        # title_div = None
        # if title is not None:
        #     title_div = Div(text='<h2>%s</h2>' % title)

        # Make the widgets accessible from external code so we can update
        # their properties if the default setup isn't great
        self.widgets = {}

        # Make the panel with widgets to control the creation of (x, y) arrays

        # Function - either a dropdown or a label for the single option
        if 'function' in config._fields:
            fn = config.function
            fn_allowed = [k for k in config._fields['function'].allowed.keys()]

            # Dropdown for selecting fit_1D function
            self.function = Select(title="Fitting Function:",
                                   value=fn,
                                   options=fn_allowed)

            def fn_select_change(attr, old, new):
                def refit():
                    for fit in self.fits:
                        fit.set_function(new)
                        fit.perform_fit()

                self.do_later(refit)

            self.function.on_change('value', fn_select_change)
        else:
            if function is None:
                function = 'chebyshev'
            self.function = Div(text='Function: %s' % function)

        if reinit_params is not None or reinit_extras is not None:
            # Create left panel
            reinit_widgets = self.make_widgets_from_config(
                reinit_params, reinit_extras, reinit_live)

            # This should really go in the parent class, like submit_button
            if not reinit_live:
                self.reinit_button = bm.Button(label="Reconstruct points")
                self.reinit_button.on_click(self.reconstruct_points)
                self.make_modal(
                    self.reinit_button,
                    "<b>Recalculating Points</b><br/>This may take 20 seconds")
                reinit_widgets.append(self.reinit_button)

            self.reinit_panel = column(self.function, *reinit_widgets)
        else:
            # left panel with just the function selector (Chebyshev, etc.)
            self.reinit_panel = column(self.function)

        # Grab input coordinates or calculate if we were given a callable
        # TODO revisit the raging debate on `callable` for Python 3
        if callable(data_source):
            self.reconstruct_points_fn = data_source
            data = data_source(config, self.extras)
            # For this, we need to remap from
            # [[x1, y1, weights1], [x2, y2, weights2], ...]
            # to allx=[x1,x2..] ally=[y1,y2..] all_weights=[weights1,weights2..]
            allx = list()
            ally = list()
            all_weights = list()
            for dat in data:
                allx.append(dat[0])
                ally.append(dat[1])
                if len(dat) >= 3:
                    all_weights.append(dat[2])
            if len(all_weights) == 0:
                all_weights = None
        else:
            self.reconstruct_points_fn = None
            if reinit_params:
                raise ValueError(
                    "Saw reinit_params but data_source is not a callable")
            if reinit_extras:
                raise ValueError(
                    "Saw reinit_extras but data_source is not a callable")
            allx = data_source[0]
            ally = data_source[1]
            if len(data_source) >= 3:
                all_weights = data_source[2]
            else:
                all_weights = None

        # Some sanity checks now
        if isinstance(fitting_parameters, list):
            if not (len(fitting_parameters) == len(allx) == len(ally)):
                raise ValueError("Different numbers of models and coordinates")
            self.nfits = len(fitting_parameters)
        else:
            if allx.size != ally.size:
                raise ValueError("Different (x, y) array sizes")
            self.nfits = 1

        self.reinit_extras = [] if reinit_extras is None else reinit_extras

        kwargs.update({'xlabel': xlabel, 'ylabel': ylabel})
        if order_param and order_param in self.config._fields:
            field = self.config._fields[order_param]
            if hasattr(field, 'min') and field.min:
                kwargs['min_order'] = field.min
            else:
                kwargs['min_order'] = 1
            if hasattr(field, 'max') and field.max:
                kwargs['max_order'] = field.max
            else:
                kwargs['max_order'] = field.default * 2
        else:
            kwargs['min_order'] = 1
            kwargs['max_order'] = 10

        self.tabs = bm.Tabs(tabs=[], name="tabs")
        self.tabs.sizing_mode = 'scale_width'
        self.fits = []
        if self.nfits > 1:
            if domains is None:
                domains = [None] * len(fitting_parameters)
            if all_weights is None:
                all_weights = [None] * len(fitting_parameters)
            for i, (fitting_parms, domain, x, y, weights) in \
                    enumerate(zip(fitting_parameters, domains, allx, ally, all_weights), start=1):
                tui = Fit1DPanel(self, fitting_parms, domain, x, y, weights,
                                 **kwargs)
                tab = bm.Panel(child=tui.component,
                               title=tab_name_fmt.format(i))
                self.tabs.tabs.append(tab)
                self.fits.append(tui.fit)
        else:
            tui = Fit1DPanel(self, fitting_parameters[0], domains, allx[0],
                             ally[0], all_weights[0], **kwargs)
            tab = bm.Panel(child=tui.component, title=tab_name_fmt.format(1))
            self.tabs.tabs.append(tab)
            self.fits.append(tui.fit)

    def visualize(self, doc):
        """
        Start the bokeh document using this visualizer.

        This call is responsible for filling in the bokeh document with
        the user interface.

        Parameters
        ----------
        doc : :class:`~bokeh.document.Document`
            bokeh document to draw the UI in
        """
        super().visualize(doc)
        col = column(self.tabs, )
        col.sizing_mode = 'scale_width'
        layout = column(row(self.reinit_panel, col),
                        self.submit_button,
                        sizing_mode="stretch_width")
        doc.add_root(layout)

    def reconstruct_points(self):
        """
        Reconstruct the initial points to work with.

        This is expected to be expensive.  The core inputs
        are separated out in the UI as they are too slow to
        be interactive.  When a user is ready and submits
        updated core config parameters, this is what gets
        executed.  The configuration is updated with the
        new values form the user.  The UI is disabled and the
        expensive function is wrapped in the bokeh Tornado
        event look so the modal dialog can display.
        """
        if hasattr(self, 'reinit_button'):
            self.reinit_button.disabled = True

        def fn():
            """Top-level code to update the Config with the values from the widgets"""
            config_update = {k: v.value for k, v in self.widgets.items()}
            for extra in self.reinit_extras:
                del config_update[extra]
            for k, v in config_update.items():
                print(f'{k} = {v}')
            self.config.update(**config_update)

        self.do_later(fn)

        if self.reconstruct_points_fn is not None:

            def rfn():
                all_coords = self.reconstruct_points_fn(
                    self.config, self.extras)
                for fit, coords in zip(self.fits, all_coords):
                    if len(coords) > 2:
                        fit.weights = coords[2]
                    else:
                        fit.weights = None
                    fit.weights = fit.populate_bokeh_objects(coords[0],
                                                             coords[1],
                                                             fit.weights,
                                                             mask=None)
                    fit.perform_fit()
                if hasattr(self, 'reinit_button'):
                    self.reinit_button.disabled = False

            self.do_later(rfn)

    def results(self):
        """
        Get the results of the interactive fit.

        This gets the list of `~gempy.library.fitting.fit_1D` fits of
        the data to be used by the caller.

        Returns
        -------
        list of `~gempy.library.fitting.fit_1D`
        """
        return [fit.model.fit for fit in self.fits]
Beispiel #12
0
    def __init__(self,
                 data_source,
                 fitting_parameters,
                 config,
                 reinit_params=None,
                 reinit_extras=None,
                 reinit_live=False,
                 order_param="order",
                 tab_name_fmt='{}',
                 xlabel='x',
                 ylabel='y',
                 domains=None,
                 function=None,
                 title=None,
                 **kwargs):
        """
        Parameters
        ----------
        data_source : array or function
            input data or the function to calculate the input data.  The input data
            should be [x, y] or [x, y, weights] or [[x, y], [x, y],.. or [[x, y, weights], [x, y, weights]..
            or, if a function, it accepts (config, extras) where extras is a dict of values based on reinit_extras
            and returns [[x, y], [x, y].. or [[x, y, weights], [x, y, weights], ...
        fitting_parameters : list of :class:`~geminidr.interactive.fit.fit1d.FittingParameters` or :class:`~geminidr.interactive.fit.fit1d.FittingParameters`
            Description of parameters to use for `fit_1d`
        config : Config instance describing primitive parameters and limitations
        reinit_params : list of str
            list of parameter names in config related to reinitializing fit arrays.  These cause the `data_source`
            function to be run to get the updated coordinates/weights.  Should not be passed if `data_source` is
            not a function.
        reinit_extras :
            Extra parameters to show on the left side that can affect the output of `data_source` but
            are not part of the primitive configuration.  Should not be passed if `data_source` is not a function.
        reinit_live :
            If False, supplies a button to call the `data_source` function and doesn't do so automatically when inputs
            are adjusted.  If `data_source` is known to be inexpensive, you can set this to `True`
        order_param : str
            Name of the parameter this primitive uses for `order`, to infer the min/max suggested values
        tab_name_fmt : str
            Format string for naming the tabs
        xlabel : str
            String label for X axis
        ylabel : str
            String label for Y axis
        domains : list
            List of domains for the inputs
        function : str
            ID of fit_1d function to use, if not a configuration option
        title : str
            Title for UI (Interactive <Title>)
        """
        super().__init__(config=config, title=title)

        # title_div = None
        # if title is not None:
        #     title_div = Div(text='<h2>%s</h2>' % title)

        # Make the widgets accessible from external code so we can update
        # their properties if the default setup isn't great
        self.widgets = {}

        # Make the panel with widgets to control the creation of (x, y) arrays

        # Function - either a dropdown or a label for the single option
        if 'function' in config._fields:
            fn = config.function
            fn_allowed = [k for k in config._fields['function'].allowed.keys()]

            # Dropdown for selecting fit_1D function
            self.function = Select(title="Fitting Function:",
                                   value=fn,
                                   options=fn_allowed)

            def fn_select_change(attr, old, new):
                def refit():
                    for fit in self.fits:
                        fit.set_function(new)
                        fit.perform_fit()

                self.do_later(refit)

            self.function.on_change('value', fn_select_change)
        else:
            if function is None:
                function = 'chebyshev'
            self.function = Div(text='Function: %s' % function)

        if reinit_params is not None or reinit_extras is not None:
            # Create left panel
            reinit_widgets = self.make_widgets_from_config(
                reinit_params, reinit_extras, reinit_live)

            # This should really go in the parent class, like submit_button
            if not reinit_live:
                self.reinit_button = bm.Button(label="Reconstruct points")
                self.reinit_button.on_click(self.reconstruct_points)
                self.make_modal(
                    self.reinit_button,
                    "<b>Recalculating Points</b><br/>This may take 20 seconds")
                reinit_widgets.append(self.reinit_button)

            self.reinit_panel = column(self.function, *reinit_widgets)
        else:
            # left panel with just the function selector (Chebyshev, etc.)
            self.reinit_panel = column(self.function)

        # Grab input coordinates or calculate if we were given a callable
        # TODO revisit the raging debate on `callable` for Python 3
        if callable(data_source):
            self.reconstruct_points_fn = data_source
            data = data_source(config, self.extras)
            # For this, we need to remap from
            # [[x1, y1, weights1], [x2, y2, weights2], ...]
            # to allx=[x1,x2..] ally=[y1,y2..] all_weights=[weights1,weights2..]
            allx = list()
            ally = list()
            all_weights = list()
            for dat in data:
                allx.append(dat[0])
                ally.append(dat[1])
                if len(dat) >= 3:
                    all_weights.append(dat[2])
            if len(all_weights) == 0:
                all_weights = None
        else:
            self.reconstruct_points_fn = None
            if reinit_params:
                raise ValueError(
                    "Saw reinit_params but data_source is not a callable")
            if reinit_extras:
                raise ValueError(
                    "Saw reinit_extras but data_source is not a callable")
            allx = data_source[0]
            ally = data_source[1]
            if len(data_source) >= 3:
                all_weights = data_source[2]
            else:
                all_weights = None

        # Some sanity checks now
        if isinstance(fitting_parameters, list):
            if not (len(fitting_parameters) == len(allx) == len(ally)):
                raise ValueError("Different numbers of models and coordinates")
            self.nfits = len(fitting_parameters)
        else:
            if allx.size != ally.size:
                raise ValueError("Different (x, y) array sizes")
            self.nfits = 1

        self.reinit_extras = [] if reinit_extras is None else reinit_extras

        kwargs.update({'xlabel': xlabel, 'ylabel': ylabel})
        if order_param and order_param in self.config._fields:
            field = self.config._fields[order_param]
            if hasattr(field, 'min') and field.min:
                kwargs['min_order'] = field.min
            else:
                kwargs['min_order'] = 1
            if hasattr(field, 'max') and field.max:
                kwargs['max_order'] = field.max
            else:
                kwargs['max_order'] = field.default * 2
        else:
            kwargs['min_order'] = 1
            kwargs['max_order'] = 10

        self.tabs = bm.Tabs(tabs=[], name="tabs")
        self.tabs.sizing_mode = 'scale_width'
        self.fits = []
        if self.nfits > 1:
            if domains is None:
                domains = [None] * len(fitting_parameters)
            if all_weights is None:
                all_weights = [None] * len(fitting_parameters)
            for i, (fitting_parms, domain, x, y, weights) in \
                    enumerate(zip(fitting_parameters, domains, allx, ally, all_weights), start=1):
                tui = Fit1DPanel(self, fitting_parms, domain, x, y, weights,
                                 **kwargs)
                tab = bm.Panel(child=tui.component,
                               title=tab_name_fmt.format(i))
                self.tabs.tabs.append(tab)
                self.fits.append(tui.fit)
        else:
            tui = Fit1DPanel(self, fitting_parameters[0], domains, allx[0],
                             ally[0], all_weights[0], **kwargs)
            tab = bm.Panel(child=tui.component, title=tab_name_fmt.format(1))
            self.tabs.tabs.append(tab)
            self.fits.append(tui.fit)
Beispiel #13
0
    def __init__(self,
                 visualizer,
                 fitting_parameters,
                 domain,
                 x,
                 y,
                 weights=None,
                 min_order=1,
                 max_order=10,
                 xlabel='x',
                 ylabel='y',
                 plot_width=600,
                 plot_height=400,
                 plot_residuals=True,
                 enable_user_masking=True):
        """
        Panel for visualizing a 1-D fit, perhaps in a tab

        Parameters
        ----------
        visualizer : :class:`~geminidr.interactive.fit.fit1d.Fit1DVisualizer`
            visualizer to associate with
        fitting_parameters : dict
            parameters for this fit
        domain : list of pixel coordinates
            Used for new fit_1D fitter
        x : :class:`~numpy.ndarray`
            X coordinate values
        y : :class:`~numpy.ndarray`
            Y coordinate values
        min_order : int
            minimum order in UI
        max_order : int
            maximum order in UI
        xlabel : str
            label for X axis
        ylabel : str
            label for Y axis
        plot_width : int
            width of plot area in pixels
        plot_height : int
            height of plot area in pixels
        plot_residuals : bool
            True if we want the lower plot showing the differential between the fit and the data
        grow_slider : bool
            True if we want the slider for modifying growth radius
        """
        # Just to get the doc later
        self.visualizer = visualizer

        self.info_div = Div()

        # Make a listener to update the info panel with the RMS on a fit
        def update_info(info_div, f):
            info_div.update(text='<b>RMS:</b> {rms:.4f}'.format(rms=f.rms))

        listeners = [
            lambda f: update_info(self.info_div, f),
        ]

        self.fitting_parameters = fitting_parameters
        self.fit = InteractiveModel1D(fitting_parameters,
                                      domain,
                                      x,
                                      y,
                                      weights,
                                      listeners=listeners)

        fit = self.fit
        order_slider = interactive.build_text_slider("Order",
                                                     fit.order,
                                                     1,
                                                     min_order,
                                                     max_order,
                                                     fit,
                                                     "order",
                                                     fit.perform_fit,
                                                     throttled=True)
        self.sigma_upper_slider = interactive.build_text_slider(
            "Sigma (Upper)",
            fitting_parameters["sigma_upper"],
            0.01,
            1,
            10,
            fitting_parameters,
            "sigma_upper",
            self.sigma_slider_handler,
            throttled=True)
        self.sigma_lower_slider = interactive.build_text_slider(
            "Sigma (Lower)",
            fitting_parameters["sigma_lower"],
            0.01,
            1,
            10,
            fitting_parameters,
            "sigma_lower",
            self.sigma_slider_handler,
            throttled=True)
        sigma_button = bm.CheckboxGroup(
            labels=['Sigma clip'], active=[0] if self.fit.sigma_clip else [])
        sigma_button.on_change('active', self.sigma_button_handler)
        controls_column = [
            order_slider,
            row(self.sigma_upper_slider, sigma_button)
        ]
        controls_column.append(self.sigma_lower_slider)
        controls_column.append(
            interactive.build_text_slider("Max iterations",
                                          fitting_parameters["niter"], 1, 0,
                                          10, fitting_parameters, "niter",
                                          fit.perform_fit))
        controls_column.append(
            interactive.build_text_slider("Grow", fitting_parameters["grow"],
                                          1, 0, 10, fitting_parameters, "grow",
                                          fit.perform_fit))

        mask_button = bm.Button(label="Mask",
                                align='center',
                                button_type='primary',
                                width_policy='min')
        mask_button.on_click(self.mask_button_handler)

        unmask_button = bm.Button(label="Unmask",
                                  align='center',
                                  button_type='primary',
                                  width_policy='min')
        unmask_button.on_click(self.unmask_button_handler)

        controller_div = Div()
        self.info_div = Div()

        if enable_user_masking:
            controls = column(*controls_column, row(mask_button,
                                                    unmask_button),
                              controller_div, self.info_div)
        else:
            controls = column(*controls_column, controller_div, self.info_div)

        # Now the figures
        x_range = None
        y_range = None
        try:
            if self.fit.data and 'x' in self.fit.data.data and len(
                    self.fit.data.data['x']) >= 2:
                x_min = min(self.fit.data.data['x'])
                x_max = max(self.fit.data.data['x'])
                x_pad = (x_max - x_min) * 0.1
                x_range = Range1d(x_min - x_pad, x_max + x_pad)
            if self.fit.data and 'y' in self.fit.data.data and len(
                    self.fit.data.data['y']) >= 2:
                y_min = min(self.fit.data.data['y'])
                y_max = max(self.fit.data.data['y'])
                y_pad = (y_max - y_min) * 0.1
                y_range = Range1d(y_min - y_pad, y_max + y_pad)
        except:
            pass  # ok, we don't *need* ranges...
        if enable_user_masking:
            tools = "pan,wheel_zoom,box_zoom,reset,lasso_select,box_select,tap"
        else:
            tools = "pan,wheel_zoom,box_zoom,reset"
        p_main = figure(plot_width=plot_width,
                        plot_height=plot_height,
                        title='Fit',
                        x_axis_label=xlabel,
                        y_axis_label=ylabel,
                        tools=tools,
                        output_backend="webgl",
                        x_range=x_range,
                        y_range=y_range)
        p_main.height_policy = 'fixed'
        p_main.width_policy = 'fit'

        class Fit1DRegionListener(GIRegionListener):
            """
            Wrapper class so we can just detect when a bands are finished.

            We don't want to do an expensive recalc as a user is dragging
            a band around.
            """
            def __init__(self, fn):
                """
                Create a band listener that just updates on `finished`
                Parameters
                ----------
                fn : function
                    function to call when band is finished.
                """
                self.fn = fn

            def adjust_region(self, region_id, start, stop):
                pass

            def delete_region(self, region_id):
                self.fn()

            def finish_regions(self):
                self.fn()

        self.band_model = GIRegionModel()

        def update_regions():
            self.fit.model.regions = self.band_model.build_regions()

        self.band_model.add_listener(Fit1DRegionListener(update_regions))
        self.band_model.add_listener(
            Fit1DRegionListener(self.band_model_handler))

        connect_figure_extras(p_main, None, self.band_model)

        Controller(p_main,
                   None,
                   self.band_model,
                   controller_div,
                   mask_handlers=(self.mask_button_handler,
                                  self.unmask_button_handler))
        fig_column = [p_main]

        if plot_residuals:
            x_range = None
            try:
                if self.fit.data and 'x' in self.fit.data.data and len(
                        self.fit.data.data['x']) >= 2:
                    x_min = min(self.fit.data.data['x'])
                    x_max = max(self.fit.data.data['x'])
                    x_pad = (x_max - x_min) * 0.1
                    x_range = Range1d(x_min - x_pad, x_max + x_pad)
            except:
                pass  # ok, we don't *need* ranges...
            p_resid = figure(plot_width=plot_width,
                             plot_height=plot_height // 2,
                             title='Fit Residuals',
                             x_axis_label=xlabel,
                             y_axis_label='delta' + ylabel,
                             tools="pan,box_zoom,reset",
                             output_backend="webgl",
                             x_range=x_range,
                             y_range=None)
            p_resid.height_policy = 'fixed'
            p_resid.width_policy = 'fit'
            connect_figure_extras(p_resid, None, self.band_model)
            fig_column.append(p_resid)
            # Initalizing this will cause the residuals to be calculated
            self.fit.data.data['residuals'] = np.zeros_like(self.fit.x)
            p_resid.scatter(x='x',
                            y='residuals',
                            source=self.fit.data,
                            size=5,
                            **self.fit.mask_rendering_kwargs())

        # Initializing regions here ensures the listeners are notified of the region(s)
        if "regions" in fitting_parameters and fitting_parameters[
                "regions"] is not None:
            region_tuples = cartesian_regions_to_slices(
                fitting_parameters["regions"])
            self.band_model.load_from_tuples(region_tuples)

        self.scatter = p_main.scatter(x='x',
                                      y='y',
                                      source=self.fit.data,
                                      size=5,
                                      **self.fit.mask_rendering_kwargs())
        self.fit.add_listener(self.model_change_handler)

        # TODO refactor? this is dupe from band_model_handler
        # hacking it in here so I can account for the initial
        # state of the band model (which used to be always empty)
        x_data = self.fit.data.data['x']
        for i in np.arange(len(x_data)):
            if self.band_model.contains(x_data[i]):
                self.fit.band_mask[i] = 0
            else:
                self.fit.band_mask[i] = 1

        self.fit.perform_fit()
        self.line = p_main.line(x='xlinspace',
                                y='model',
                                source=self.fit.evaluation,
                                line_width=3,
                                color='black')

        region_editor = RegionEditor(self.band_model)
        fig_column.append(region_editor.get_widget())
        col = column(*fig_column)
        col.sizing_mode = 'scale_width'
        self.component = row(controls, col)
Beispiel #14
0
    TableColumn(field="recentVol_emaAtr_diff_Atr",
                title="Volatility (ATR) Spread"),
    TableColumn(field="ExcessFwdRets", title="Excess Fwd Rets"),
    TableColumn(field="SpearmanCorr", title="Spearman Rank Correlation"),
    TableColumn(field="PearsonCorr", title="Pearson Correlation"),
    TableColumn(field="intercept", title="Line Regress Intercept"),
    TableColumn(field="slope", title="Line Regress Slope"),
    TableColumn(field="AbsValExcessFwdRets", title="Magnitude Rets"),
    TableColumn(field="StockFwdRets", title="Target Fwd Rets"),
    TableColumn(field="BenchmarkFwdRets", title="Benchmark Fwd Rets"),
    TableColumn(field="StockAdjClose", title="Target Px. (Adj Close)"),
    TableColumn(field="BenchmarkAdjClose", title="Benchmark Px (Adj Close)")
]
agg_stats_title_div = Div(
    text="""<b>Aggregated Statistics, Selected Data</b> """,
    width=1000,
    height=20,
    background="yellow")
data_table = DataTable(source=source, columns=columns, width=1000)
ts_data_corrAnalysis_title_div = Div(
    text="""<b>Correlation Analysis - Time Series Data</b> """,
    width=1000,
    height=20,
    background="yellow")
stats_data_table = DataTable(source=stats_source,
                             columns=stats_columns,
                             height=250,
                             width=1000)
period_cum_returns_title_div = Div(
    text="""<b>Periodic & Cummulative Returns, Selected Data</b> """,
    width=1000,
Beispiel #15
0
# This data source is just used to communicate / trigger the real callback
Slider_watershed.on_change('value', Slider_watershed_update)

Slider_threshold = Slider(
    start=0,
    end=100,
    value=0,
    step=1,
    title="threshold",
    width=config_main['plot_config']['tab_XCorr']['widgetbox_wdth'],
    callback_policy='mouseup')

Slider_threshold.on_change('value', Slider_threshold_update)

Div_exit = Div(
    text="""<p><b>Warning</b>: Click <b>Exit</b>
            first before closing the tab</p></b>""",
    width=config_main['plot_config']['tab_FSview_base']['widgetbox_wdth'])

BUT_exit = Button(
    label='Exit FSview',
    width=config_main['plot_config']['tab_FSview_base']['widgetbox_wdth'],
    button_type='danger')
BUT_exit.on_click(exit_update)

lout = column(
    row(gridplot([[p_dspec, p_dspecfit]], toolbar_location='right'),
        p_dspec_profile),
    row(gridplot([[p_CCmax, p_CCpeak]], toolbar_location='right'),
        column(Slider_watershed, Slider_threshold, BUT_exit, Div_exit)))

curdoc().add_root(lout)
from numpy.random import random
from sklearn.utils import resample
from sklearn.neural_network import MLPClassifier
from sklearn.preprocessing import StandardScaler
from sklearn import tree
from bokeh.layouts import column, row
# from bokeh.charts import Bar

axis_map = {"gini": "gini", "entropy": "entropy"}

desc = Div(text="""<h1>An Interactive Explorer for Churn Data</h1>
<p>
The model allows user to work on random forest machine learning model
where the user can change model's hyperparameter and select features 
to drop. The user can also change the test size.
Based on the parameters user can see the changes in the graph in realtime
</p>
<p>
Prepared by <b>Rajat Kabra</b>.<br/>
Presented to <b>Prof. Kevin Smith</b>.<br/>
Under <b>Assignment 4 of CS 235</b>.</p>
<br/>""")

df = pd.read_csv('C:\\Users\\rajat\\Desktop\\Master project\\churn.csv',
                 names=[
                     'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
                     'l', 'm', 'n', 'o'
                 ])

div = Div(
    text=
    """Your <a href="https://en.wikipedia.org/wiki/HTML">HTML</a>-supported text is initialized with the <b>text</b> argument.  The
def lorenz_tab2(plot_dict, data):
    def make_plot(src, src_raw):
        p = figure(
            plot_width=800,
            plot_height=400,
            tooltips="$name: $y{0.00%} ",
        )
        lines = [
            "deciles",
            "total_income_share",
            "net_income_share",
            "net_income_share_simulated",
        ]
        labels = [
            "Perfect equality",
            "Total income (pre tax)",
            "Total income (after tax status quo)",
            "Total income (after tax simulated reform)",
        ]
        colors = Category10[len(lines)]

        for i in range(len(lines)):
            p.line(
                "deciles",
                lines[i],
                source=src,
                line_color=colors[i],
                legend_label=labels[i],
                alpha=0.8,
                muted_color=colors[i],
                muted_alpha=0.2,
                name=labels[i],
            )
            p.circle(
                "deciles",
                lines[i],
                source=src,
                fill_color=colors[i],
                legend_label=labels[i],
                line_color=None,
                name=labels[i],
                alpha=0.8,
                muted_color=colors[i],
                muted_alpha=0.2,
            )

        p.xaxis.tags = ["numeric"]

        plot = plotstyle(p, plot_dict)

        # Table to display source data

        columns = [
            TableColumn(field="deciles", title="Deciles"),
            TableColumn(field="total_income",
                        title="Total income (before tax)"),
            TableColumn(field="net_income",
                        title="Total income (after tax status quo)"),
            TableColumn(field="net_income_simulated",
                        title="Total income (after tax reform)"),
            TableColumn(field="weights", title="Decile weights"),
        ]

        data_table = DataTable(
            source=src_raw,
            columns=columns,
            width=800,
            height=350,
            selectable=False,
            autosize_mode="fit_columns",
        )

        return plot, data_table

    src, src_raw = (
        ColumnDataSource(data["income_share_dict"]),
        ColumnDataSource(data["raw_dict"]),
    )

    plot, table = make_plot(src, src_raw)

    description = Div(
        text=plot_dict["description"],
        width=1000,
    )

    table_title = Div(
        text=
        """<b>Source data: Average (taxable) income per decile (in €)</b>""",
        width=800,
        height=20,
    )
    reference = Div(
        text=
        """Data from <a href="http://hdl.handle.net/10419/172793">Bach and Buslei 2017</a>
        table 3-2 and own calculations. Columns show average taxable income per decile in Euro.
        Capital income calculated as avg. capital tax / 0.26375.""",
        width=800,
        height=80,
    )

    layout = column(description, plot, table_title, table, reference)

    tab = Panel(child=layout, title="Lorenz curves (Reform)")

    return tab
Beispiel #18
0

def change_real_scale(shift):
    global realx_offset, new_data
    realx_offset = shift
    new_data = True
    update()


file_input = FileInput(accept=".ulg, .csv")
file_input.on_change('value', upload_new_data_sim)
file_input2 = FileInput(accept=".ulg, .csv")
file_input2.on_change('value', upload_new_data_real)

intro_text = Div(text="""<H2>Sim/Real Thiel Coefficient Calculator</H2>""",
                 width=500,
                 height=100,
                 align="center")
sim_upload_text = Paragraph(text="Upload a simulator datalog:",
                            width=500,
                            height=15)
real_upload_text = Paragraph(text="Upload a corresponding real-world datalog:",
                             width=500,
                             height=15)
#checkbox_group = CheckboxGroup(labels=["x", "y", "vx","vy","lat","lon"], active=[0, 1])

sim_reverse_button = RadioButtonGroup(labels=["Sim Default", "Reversed"],
                                      active=0)
sim_reverse_button.on_change('active', lambda attr, old, new: reverse_sim())
real_reverse_button = RadioButtonGroup(labels=["Real Default", "Reversed"],
                                       active=0)
real_reverse_button.on_change('active', lambda attr, old, new: reverse_real())
Beispiel #19
0
def kafka_spark_streamer(doc):
    try:
        div = Div(text='Just close this window please')
        doc.add_root(div)
    except Exception:
        logger.error("TABS:", exc_info=True)
Beispiel #20
0
                widgetbox(X_sampling,width=350),
                widgetbox(Y_sampling,width=350),
                widgetbox(Xselect,width=350),
                widgetbox(Yselect,width=350),
                widgetbox(Zselect,width=350),
                widgetbox(text_input,width=350),
                widgetbox(bt,width=350),
                widgetbox(radio_button_group,width=350),
                width=400),
            column(p,width=800),
        )

"""

div = Div(text='Tooltips (Double Click on a point to view)',
          width=200,
          height=100)

ldict = dict(c(dfs['threshold']))
ldictkeys = list(ldict.keys())
ldictvalues = list(ldict.values())
ldictlist = [
    '<b>' + str(ldictkeys[f]) + '</b>' + ': ' + str(ldictvalues[f])
    for f in range(len(ldictvalues))
]
ldictfinal = '\n'.join(ldictlist)

plot_text = Div(
    text=
    '<b style="color:Gray;"></b><br><b style="color:MediumSeaGreen;">Points displayed : Total points in the dataset: </b>'
    + str(len(dfs)) + ':' + str(len(df)) + '\n' +
Beispiel #21
0
        sv_hist.upper_spinner,
        sv_hist.nbins_spinner,
    ),
)

layout_utility = column(
    gridplot(
        sv_streamgraph.plots, ncols=1, toolbar_location="left", toolbar_options=dict(logo=None)
    ),
    row(
        sv_streamgraph.moving_average_spinner,
        column(Spacer(height=19), sv_streamgraph.reset_button),
    ),
)

show_overlays_div = Div(text="Show Overlays:")

layout_controls = row(
    column(
        row(sv_colormapper.select, sv_colormapper.high_color, sv_colormapper.mask_color),
        row(sv_colormapper.display_min_spinner, sv_colormapper.display_max_spinner),
        row(sv_colormapper.auto_toggle, sv_colormapper.scale_radiobuttongroup),
        show_overlays_div,
        row(sv_resolrings.toggle, sv_main.proj_toggle),
        row(sv_intensity_roi.toggle, sv_saturated_pixels.toggle),
    ),
    Spacer(width=30),
    column(
        row(sv_streamctrl.datatype_select, sv_streamctrl.rotate_image),
        sv_streamctrl.prev_image_slider,
        row(sv_streamctrl.conv_opts, sv_streamctrl.double_pixels),
Beispiel #22
0
duration1 = Slider(title=DUR1_LABEL, value=DUR1_START, start=DUR_MIN, end=DUR1_MAX, step=1)
duration2 = Slider(title=DUR2_LABEL, value=DUR2_START, start=DUR_MIN, end=DUR2_MAX, step=1)

transition1 = Slider(title=TRA1_LABEL, value=TRA1_START, start=TRA_MIN, end=TRA1_MAX, step=1)
transition2 = Slider(title=TRA2_LABEL, value=TRA2_START, start=TRA_MIN, end=TRA2_MAX, step=1)

beta1 = Slider(title=BETA1_LABEL, value=BETA1_START, start=BETA_MIN, end=BETA1_MAX, step=BETA1_STEP)
beta2 = Slider(title=BETA2_LABEL, value=BETA2_START, start=BETA_MIN, end=BETA2_MAX, step=BETA2_STEP)
beta3 = Slider(title=BETA3_LABEL, value=BETA3_START, start=BETA_MIN, end=BETA3_MAX, step=BETA3_STEP)

drate = Slider(title=DRATE_LABEL, value=DRATE_START, start=DRATE_MIN, end=DRATE_MAX, step=DRATE_STEP)

button = Button(label="Reset", button_type="default")

# text widgets
intro   = Div(text='', width=TEXT_WIDTH)
summary = Div(text='', width=TEXT_WIDTH)
stats   = Div(text='', width=TEXT_WIDTH)
notes   = Div(text='', width=TEXT_WIDTH)

# Assign widgets to the call back function
# updates are on value_throtled because this is too slow for realtime updates
for w in [population, iinfections, period, period_stdev, latent, duration1, duration2, transition1, transition2, beta1, beta2, beta3, drate ]:
    w.on_change('value_throttled', update_data)

# reset button call back
button.on_click(reset_data)

# initial plot
x = np.linspace(1, DAYS, DAYS)
y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, y11, ar_stats = get_data(x, population.value, iinfections.value, period.value, period_stdev.value, latent.value, duration1.value, duration2.value, transition1.value, transition2.value, beta1.value, beta2.value, beta3.value, DAYS, drate.value, True )
def startserver(doc):
    file_input = FileInput(accept=".ulg, .csv")
    file_input.on_change('value', upload_new_data_sim)
    file_input2 = FileInput(accept=".ulg, .csv")
    file_input2.on_change('value', upload_new_data_real)

    intro_text = Div(text="""<H2>Sim/Real Thiel Coefficient Calculator</H2>""",
                     width=500,
                     height=100,
                     align="center")
    sim_upload_text = Paragraph(text="Upload a simulator datalog:",
                                width=500,
                                height=15)
    real_upload_text = Paragraph(
        text="Upload a corresponding real-world datalog:",
        width=500,
        height=15)
    #checkbox_group = CheckboxGroup(labels=["x", "y", "vx","vy","lat","lon"], active=[0, 1])

    sim_reverse_button = RadioButtonGroup(labels=["Sim Default", "Reversed"],
                                          active=0)
    sim_reverse_button.on_change('active',
                                 lambda attr, old, new: reverse_sim())
    real_reverse_button = RadioButtonGroup(labels=["Real Default", "Reversed"],
                                           active=0)
    real_reverse_button.on_change('active',
                                  lambda attr, old, new: reverse_real())

    simsource_static.selected.on_change('indices', simselection_change)

    # The below are in case you want to see the x axis range change as you pan. Poorly documented elsewhere!
    #ts1.x_range.on_change('end', lambda attr, old, new: print ("TS1 X range = ", ts1.x_range.start, ts1.x_range.end))
    #ts2.x_range.on_change('end', lambda attr, old, new: print ("TS2 X range = ", ts2.x_range.start, ts2.x_range.end))

    ts1.x_range.on_change(
        'end', lambda attr, old, new: change_sim_scale(ts1.x_range.start))
    ts2.x_range.on_change(
        'end', lambda attr, old, new: change_real_scale(ts2.x_range.start))

    # set up layout
    widgets = column(datatype, stats)
    sim_button = column(sim_reverse_button)
    real_button = column(real_reverse_button)
    main_row = row(widgets)
    series = column(ts1, sim_button, ts2, real_button)
    layout = column(main_row, series)

    # initialize
    update()
    doc.add_root(intro_text)

    doc.add_root(sim_upload_text)
    doc.add_root(file_input)
    doc.add_root(real_upload_text)
    doc.add_root(file_input2)
    doc.add_root(layout)
    doc.title = "Flight data"

    # horizonal marker line at 1
    data_span = Span(location=1,
                     dimension='width',
                     line_color='black',
                     line_alpha=0.5,
                     line_width=1.5)
    p.add_layout(data_span)

    data_plot.set_use_time_formatter(False)
    data_plot.finalize()
Beispiel #24
0
 def subobject_view(self):
     return Div(text='%d' % self.b.a)
Beispiel #25
0
def plot_pathway_all_levels(pathway,
                            out_path="../../figures/pathways/",
                            graphs_path="../../reports/pathways/",
                            coloring=Coloring.ENTITY_TYPE,
                            graphs=None,
                            **kwargs):
    """
    Plot the interaction networks generated for a single pathway at the 3 levels; genes, proteins and proteoforms and
    using the 3 methods of constructing the interaction network.
    It locates the entities in the same coordinates as their translation products. Ex. Gene, protein and proteoform in
    the same relative location in its own plot.

    :param pathway: string id for the pathway
    :param out_path:
    :param graphs_path:
    :param coloring:
    :param graphs: [list of graphs one for each level]}
    :param v:
    :return:
    """
    name = get_pathway_name(pathway)['Name'][0]
    if len(name) == 0:
        return

    graphs = {
        config.no_sm: list(graphs[no_sm].values()),
        config.with_sm: list(graphs[config.with_sm].values()),
        config.with_unique_sm: list(graphs[config.with_unique_sm].values())
    }

    titles = {
        config.no_sm: [
            'A) Genes without SM', 'B) Proteins without SM',
            'C) Proteoforms without SM'
        ],
        config.with_sm: [
            'D) Proteins with SM', 'E) Proteins with SM',
            'F) Proteoforms with SM'
        ],
        config.with_unique_sm: [
            'G) Proteins with unique SM', 'H) Proteins with unique SM',
            'I) Proteoforms with unique SM'
        ]
    }

    inner_plot_size = kwargs[
        'inner_plot_size'] if 'inner_plot_size' in kwargs else 300
    legend_location_all = [None, None, 'right']
    plot_widths = [inner_plot_size, inner_plot_size, inner_plot_size + 160]
    outline_line_width = kwargs[
        'outline_line_width'] if 'outline_line_width' in kwargs else 1
    node_size = kwargs['node_size'] if 'node_size' in kwargs else 2
    if coloring == Coloring.ENTITY_TYPE:
        legend_location_all = ['top_right', 'top_right', 'top_right']
        plot_widths = [inner_plot_size, inner_plot_size, inner_plot_size]

    toolbar_location = kwargs[
        'toolbar_location'] if 'toolbar_location' in kwargs else None

    pos = get_positions(graphs)

    figures = {
        method: [
            plot_interaction_network(
                graphs[method][i],
                coloring=coloring,
                pos=pos[method][i],
                plot_width=plot_widths[i],
                plot_height=inner_plot_size,
                outline_line_width=outline_line_width,
                outline_line_color='#e5e5e5',
                node_size=node_size,
                toolbar_location=toolbar_location,
                title=titles[method][i],
                legend_location=legend_location_all[i],
                highlight_articulations=(kwargs['highlight_articulations']
                                         if 'highlight_articulations' in kwargs
                                         else False),
                highlight_bridges=(kwargs['highlight_bridges'] if
                                   'highlight_bridges' in kwargs else False))
            for i in range(3)
        ]
        for method in config.METHODS
    }

    if kwargs["v"] if "v" in kwargs else False:
        import os
        print("In function create_graph: ", os.getcwd())
        print(f"Output path is: {out_path}{pathway}_network.html")
    output_file = f"{out_path}{pathway}_{coloring.name}_network.html"

    title = f"<p style=\"font-weight:bold;text-align:left;font-size:22px;width:1800px;\">" \
            f"<span style=\"color:black;\">{name} ({pathway})</span>" \
            f"</p>"

    notes = f"""
    <style type="text/css">
    table {{
        border: 0px;
    }}

    .color_td {{
        border: inset 1px black;
        width: 50px
    }}

    table td#SimpleEntity {{
        background-color: {get_entity_color("SimpleEntity", "")};
    }}

    table td#EntityWithAccessionedSequence {{
        background-color: {get_entity_color("", "proteins")};
    }}

    table td#IO {{
        background-color: {COLOR_IO};
    }}

    table td#CO {{
        background-color: {COLOR_CO};
    }}

    table td#RO {{
        background-color: {COLOR_RO};
    }}

    table td#C {{
        background-color: {COLOR_CC};
    }}
</style>

<table>
    <tr>
        <td id="SimpleEntity" class="color_td"></td>
        <td>Small molecules</td>
    </tr>
    <tr>
        <td id="EntityWithAccessionedSequence" class="color_td"></td>
        <td>Genes, Proteins, Proteoforms</td>
    </tr>
    """
    # <tr>
    #     <td id="IO" class="color_td"></td>
    #     <td>Input -- Output</td>
    # </tr>
    # <tr>
    #     <td id="CO" class="color_td"></td>
    #     <td>Catalyst -- Output</td>
    # </tr>
    # <tr>
    #     <td id="RO" class="color_td"></td>
    #     <td>Regulator -- Output</td>
    # </tr>
    # <tr>
    #     <td id="C" class="color_td"></td>
    #     <td>Component -- Component</td>
    # </tr>
    notes += """
    </table>
    """

    l = layout([
        [Div(text=f"{title}")],
        # [Div(text=notes)],
        figures[config.no_sm],
        figures[config.with_sm],
        figures[config.with_unique_sm]
    ])

    show(l)
    print(f"Generated figure: {output_file}")
    return l
Beispiel #26
0
def prepare_server(
    doc,
    input_data,
    cell_stack,
    cell_markers=None,
    default_umap_marker=None,
    default_cell_marker=None,
):
    @lru_cache()
    def get_data(m=None):
        d = input_data
        if m is not None:
            m_v = d[m]
            if np.issubdtype(m_v.dtype, np.number):
                d["marker_val_num"] = m_v
            else:
                d["marker_val_cat"] = m_v
        if "marker_val_num" not in d:
            d["marker_val_num"] = np.arange(d.shape[0])
        if "marker_val_cat" not in d:
            d["marker_val_cat"] = np.full(d.shape[0], "a")
        return d

    @lru_cache()
    def get_cat_colors(n):
        return Colorblind[max(3, n)][:n]

    @lru_cache()
    def marker_cols(lower=False):
        markers = list(sorted(input_data.columns, key=lambda x: x.lower()))
        if lower:
            return {x.lower(): x for x in markers}
        return markers

    @lru_cache()
    def image_markers(lower=False, mapping=False):
        if mapping:
            return {
                y: j
                for j, y in sorted(
                    (
                        (i, x)
                        for i, x in enumerate(image_markers(lower=lower, mapping=False))
                    ),
                    key=lambda x: x[1].lower(),
                )
            }
        if lower:
            return [x.lower() for x in image_markers(lower=False, mapping=False)]
        return (
            cell_markers
            if cell_markers is not None
            else [f"Marker {i + 1}" for i in range(cell_stack.shape[1])]
        )

    input_data = input_data.copy()

    # Marker selection for UMAP plots
    ###########################################################################

    if default_umap_marker is None:
        default_umap_marker = marker_cols()[0]
    marker_select = Select(
        value=default_umap_marker, options=marker_cols(), title="Color UMAP by"
    )
    marker_input = AutocompleteInput(
        completions=marker_cols() + list(marker_cols(lower=True).keys()),
        min_characters=1,
        placeholder="Search for marker",
    )
    marker_slider = RangeSlider(
        start=0, end=1, value=(0, 1), step=0.1, orientation="vertical", direction="rtl"
    )

    # Data sources
    ###########################################################################

    source = ColumnDataSource(data=get_data(None))
    image_source = ColumnDataSource(data=dict(image=[], dw=[], dh=[]))

    # UMAP scatter plot for numeric data
    ###########################################################################

    umap_figure = figure(
        plot_width=800,
        plot_height=500,
        tools="pan,wheel_zoom,lasso_select,box_select,tap,reset",
        active_scroll="wheel_zoom",
        active_drag="box_select",
        active_tap="tap",
        toolbar_location="left",
    )
    marker_mapper = linear_cmap(
        field_name="marker_val_num",
        palette=inferno(10)[:-1],
        low=0,
        high=500,
        high_color=None,
    )
    umap_scatter_renderer = umap_figure.circle(
        "d1",
        "d2",
        size=8,
        source=source,
        fill_alpha=0.5,
        line_alpha=0.9,
        fill_color=marker_mapper,
        line_color=marker_mapper,
        selection_fill_alpha=0.8,
        selection_line_alpha=1,
        selection_line_color="black",
        nonselection_alpha=0.2,
        hover_line_color="black",
    )
    umap_color_bar = ColorBar(
        color_mapper=marker_mapper["transform"], width=12, location=(0, 0)
    )
    umap_figure.add_layout(umap_color_bar, "right")
    umap_figure.add_tools(
        HoverTool(tooltips=None, renderers=[umap_scatter_renderer], mode="mouse")
    )

    # UMAP scatter plot for categorical data
    ###########################################################################

    umap_figure_cat = figure(
        plot_width=800,
        plot_height=500,
        tools="pan,wheel_zoom,lasso_select,box_select,tap,reset",
        active_scroll="wheel_zoom",
        active_drag="box_select",
        active_tap="tap",
        x_range=umap_figure.x_range,
        y_range=umap_figure.y_range,
        toolbar_location="left",
    )
    marker_mapper_cat = factor_cmap(
        field_name="marker_val_cat", palette=["#000000"], factors=["a"]
    )
    umap_figure_cat.circle(
        "d1",
        "d2",
        size=8,
        source=source,
        legend_field="marker_val_cat",
        alpha=0.7,
        fill_color=marker_mapper_cat,
        line_color=None,
        selection_alpha=0.9,
        selection_line_color="black",
        nonselection_alpha=0.5,
    )
    umap_figure_cat.legend.location = "top_right"
    umap_figure_cat.legend.orientation = "vertical"

    # Cell picture plot
    ###########################################################################

    default_cell_marker = (
        0
        if default_cell_marker is None
        else image_markers(mapping=True)[default_cell_marker]
    )
    cell_markers_select = Select(
        value=str(default_cell_marker),
        options=list((str(i), x) for x, i in image_markers(mapping=True).items()),
        title="Marker cell image",
    )
    cell_marker_input = AutocompleteInput(
        completions=list(image_markers()) + list(image_markers(lower=True)),
        min_characters=1,
        placeholder="Search for marker",
    )
    cell_slider = RangeSlider(
        start=0, end=1, value=(0, 1), orientation="vertical", direction="rtl"
    )
    metric_select = RadioButtonGroup(active=0, labels=CELL_IMAGE_METRICS[0])
    stats = PreText(text="", width=100)

    cell_mapper = bokeh.models.mappers.LinearColorMapper(
        viridis(20), low=0, high=1000, high_color=None
    )
    cell_color_bar = ColorBar(color_mapper=cell_mapper, width=12, location=(0, 0))
    cell_figure = figure(
        plot_width=450,
        plot_height=350,
        tools="pan,wheel_zoom,reset",
        toolbar_location="left",
    )
    cell_image = cell_figure.image(
        image="image",
        color_mapper=cell_mapper,
        x=0,
        y=0,
        dw="dw",
        dh="dh",
        source=image_source,
    )
    cell_figure.add_layout(cell_color_bar, "right")

    # Edit data of selected cells
    ###########################################################################

    edit_selection_col = TextInput(title="Column")
    edit_selection_val = TextInput(title="Value")
    edit_selection_submit = Button(
        label="Submit change", button_type="primary", align=("start", "end")
    )
    edit_selecton_log = PreText(text="")

    download_button = Button(
        label="Download cell data", button_type="success", align=("start", "end")
    )
    download_button.js_on_click(CustomJS(args=dict(source=source), code=DOWNLOAD_JS))

    # Callbacks for buttons and widgets
    ###########################################################################

    def marker_change(attrname, old, new):
        update()

    def cell_slider_change(attrname, old, new):
        cell_mapper.low = new[0]
        cell_mapper.high = new[1]

    def marker_slider_change(attrname, old, new):
        marker_mapper["transform"].low = new[0]
        marker_mapper["transform"].high = new[1]

    def update(update_range=True):
        m = marker_select.value
        d = get_data(m)
        source.data = d
        numeric_marker = np.issubdtype(d[m].dtype, np.number)
        if not numeric_marker:
            levels = list(sorted(set(d["marker_val_cat"])))
            marker_mapper_cat["transform"].palette = get_cat_colors(len(levels))
            marker_mapper_cat["transform"].factors = levels
        elif update_range and numeric_marker:
            marker_max = round_signif(d["marker_val_num"].max())
            marker_min = round_signif(d["marker_val_num"].min())
            marker_slider.start = marker_min
            marker_slider.end = marker_max
            marker_slider.step = round_signif((marker_max - marker_min) / 50)
            marker_slider.value = tuple(
                map(round_signif, np.percentile(d["marker_val_num"], [5, 95]))
            )
        umap_figure.visible = numeric_marker
        umap_figure_cat.visible = not numeric_marker
        marker_slider.visible = numeric_marker

    def selection_change(attrname, old, new):
        m = marker_select.value
        data = get_data(m)
        selected = source.selected.indices
        if not selected:
            return
        data = data.iloc[selected, :]
        mean_image = CELL_IMAGE_METRICS[1][metric_select.active](
            cell_stack[selected, int(cell_markers_select.value), :, :], axis=0
        )
        image_source.data = {
            "image": [mean_image],
            "dw": [cell_stack.shape[1]],
            "dh": [cell_stack.shape[2]],
        }
        image_extr = round_signif(mean_image.min()), round_signif(mean_image.max())
        cell_slider.start = image_extr[0]
        cell_slider.end = image_extr[1]
        cell_slider.step = round_signif((image_extr[1] - image_extr[0]) / 50)
        cell_slider.value = image_extr
        stats.text = "n cells: " + str(len(selected))

    def mark_selection():
        get_data.cache_clear()
        col = edit_selection_col.value
        if col is None or col == "":
            return
        if col not in input_data:
            input_data[col] = np.full(input_data.shape[0], "NA")
        col_type = input_data[col].dtype
        idx = source.selected.indices
        try:
            val = np.full(len(idx), edit_selection_val.value).astype(col_type)
            input_data.loc[input_data.index[idx], col] = val
        except Exception as e:
            edit_selecton_log.text = (
                f'Failed to edit cells. Exception: "{e}"\n' + edit_selecton_log.text
            )
        else:
            edit_selecton_log.text = (
                f'Edited {len(source.selected.indices)} cells. {col}="{edit_selection_val.value}"\n'
                + edit_selecton_log.text
            )
        update(update_range=False)
        old_marker_cols = set(marker_cols())
        marker_cols.cache_clear()
        if old_marker_cols != set(marker_cols()):
            marker_select.options = marker_cols()
            marker_input.completions = marker_cols() + list(
                marker_cols(lower=True).keys()
            )

    def autocomplete_change(attrname, old, new):
        if new not in marker_cols():
            try:
                new = marker_cols(lower=True)[new]
            except KeyError:
                return
        marker_select.value = new
        marker_input.value = None

    def autocomplete_cell_change(attrname, old, new):
        try:
            idx = image_markers(mapping=True)[new]
        except KeyError:
            try:
                idx = image_markers(lower=True, mapping=True)[new]
            except KeyError:
                return
        cell_markers_select.value = str(idx)
        cell_marker_input.value = None

    source.selected.on_change("indices", selection_change)
    marker_select.on_change("value", marker_change)
    marker_slider.on_change("value", marker_slider_change)
    cell_slider.on_change("value", cell_slider_change)
    metric_select.on_change("active", selection_change)
    cell_markers_select.on_change("value", selection_change)
    edit_selection_submit.on_click(mark_selection)
    marker_input.on_change("value", autocomplete_change)
    cell_marker_input.on_change("value", autocomplete_cell_change)

    # set up layout
    layout = column(
        row(
            column(
                marker_select,
                marker_input,
                row(umap_figure, marker_slider),
                umap_figure_cat,
            ),
            column(
                cell_markers_select,
                cell_marker_input,
                metric_select,
                row(cell_figure, cell_slider),
                stats,
            ),
        ),
        Div(text="Change data for selected cells"),
        row(
            edit_selection_col,
            edit_selection_val,
            edit_selection_submit,
            download_button,
        ),
        edit_selecton_log,
    )

    # initialize
    update()

    doc.add_root(layout)
    doc.title = "UMAP projection"
Beispiel #27
0
        {{ plot_div|indent(8) }}
        {{ plot_script|indent(8) }}
    </body>
</html>
"""
)

p = Paragraph(text="The divs below were configured with additional css_classes:")

div1 = Div(
    text="""
<p> This Bokeh Div adds the style classes:<p>
<pre>
.custom {
    border-radius: 0.5em;
    padding: 1em;
}
.custom-1 {
    border: 3px solid #2397D8;
}
</pre>
"""
)
div1.css_classes = ["custom", "custom-1"]

div2 = Div(
    text="""
<p> This Bokeh Div adds the style classes:<p>
<pre>
.custom {
    border-radius: 0.5em;
    padding: 1em;
Beispiel #28
0
def create_plot():

    #Data
    data = mid_stat.copy()

    #Borough
    boro_val = select1.value
    boros = [
        'No Preference', 'Manhattan', 'Bronx', 'Brooklyn', 'Queens',
        'Staten Island'
    ]

    if boro_val != boros[0]:
        data = data[data['borough'] == boro_val]

    #Mean Scores
    math_range = slider21.value
    ela_range = slider22.value

    data = data[(data['mean_score_math'] >= math_range[0])
                & (data['mean_score_math'] <= math_range[1])]
    data = data[(data['mean_score_ela'] >= ela_range[0])
                & (data['mean_score_ela'] <= ela_range[1])]

    #Total Enrollment
    enroll_range = slider3.value
    data = data[(data['total_enrollment'] >= enroll_range[0])
                & (data['total_enrollment'] <= enroll_range[1])]

    #Class size
    class_range = slider4.value
    data = data[(data['pupil_teacher_ratio'] >= class_range[0])
                & (data['pupil_teacher_ratio'] <= class_range[1])]

    #Sports
    s = select51.value
    sports = [
        'No Preference', 'Dance and Fitness', 'Outdoor', 'Water Sports ',
        'Martial Arts ', 'Racquet Sports', 'Ball Teamsports'
    ]

    if s == sports[1]:
        data = data[data['sports'].str.lower().str.contains(
            'salsa|zumba|step|weight|yoga|step|dance|fitness|cheer|gym')]
    elif s == sports[2]:
        data = data[data['sports'].str.lower().str.contains(
            'track|run|board|climb')]
    elif s == sports[3]:
        data = data[data['sports'].str.lower().str.contains('row|swim')]
    elif s == sports[4]:
        data = data[data['sports'].str.lower().str.contains(
            'martial|karate|wrest|judo')]
    elif s == sports[5]:
        data = data[data['sports'].str.lower().str.contains(
            'tennis|squash|ping')]
    elif s == sports[6]:
        data = data[data['sports'].str.lower().str.contains(
            'lacrosse|ball|rugby|soccer|frisbee')]

    #Electives
    e = select52.value
    elect = ['No Preference', 'Technology', 'Creativity', 'Society']

    if e == elect[1]:
        data = data[data['electives'].str.lower().str.contains(
            'tech|coding|computer|web|movie|program|stem')]
    elif e == elect[2]:
        data = data[data['electives'].str.lower().str.contains(
            'guitar|band|vocal|music|drama|instrument|danc|art|theat|writ|choir'
        )]
    elif e == elect[3]:
        data = data[data['electives'].str.lower().str.contains(
            'language|cult|social|leader|spanish')]

    #Cross off
    offer_idx = checkbox52.active
    offer = ['uniform', 'extendedday', 'summersession', 'weekendprogram']
    offer_choice = [offer[idx] for idx in offer_idx]

    for off in offer_choice:
        data = data[data[off] == True]

    #Gender
    male_range = slider61.value
    female_range = slider62.value
    data = data[(data['male_rate'] >= male_range[0])
                & (data['male_rate'] <= male_range[1])]
    data = data[(data['female_rate'] >= female_range[0])
                & (data['female_rate'] <= female_range[1])]

    #Etnicities
    div_range = slider7.value
    data = data[(data['diversity_index'] >= div_range[0])
                & (data['diversity_index'] <= div_range[1])]

    #Rental
    rent_idx = radio_button81.active

    if rent_idx == 1:
        data = data[data['rent_level'] <= 1]
    elif rent_idx == 2:
        data = data[data['rent_level'] <= 2]
    elif rent_idx == 3:
        data = data[data['rent_level'] >= 3]

    #Crime
    crime_idx = radio_button82.active

    if crime_idx == 1:
        data = data[data['crime_rate'] < 30]
    elif crime_idx == 2:
        data = data[(data['crime_rate'] >= 30) & (data['crime_rate'] < 60)]
    elif crime_idx == 3:
        data = data[data['crime_rate'] > 60]

    #Make data dict and columnsource
    data_dict = data.to_dict('list')
    source = ColumnDataSource(data_dict)

    w = 80

    div0 = Div(text="<b> Schools matching Preferences: {} </b>".format(
        len(data)),
               style={'font-size': '150%'})

    columns = [
        TableColumn(field="dbn", title="School DBN", width=w),
        TableColumn(field="mean_score_math", title="Math Score", width=w),
        TableColumn(field="mean_score_ela", title="ELA Score", width=w),
        TableColumn(field="male_rate", title="% Male", width=w),
        TableColumn(field="female_rate", title="% Female", width=w),
        TableColumn(field="black_rate", title="% Black", width=w),
        TableColumn(field="white_rate", title="% White", width=w),
        TableColumn(field="asian_rate", title="% Asian", width=w),
        TableColumn(field="hispanic_rate", title="% Hispanic", width=w),
        TableColumn(field="avg_rent_per_sqft", title="Rent per sqft", width=w),
        TableColumn(field="crime_rate", title="Crime rate", width=w),
        TableColumn(field="sports", title="Sports", width=800),
        TableColumn(field="electives", title="Electives", width=800)
    ]
    data_table = DataTable(source=source,
                           columns=columns,
                           width=800,
                           height=180,
                           fit_columns=False)

    #Get map
    NY = [
        -73.935242,
        40.730610,
    ]
    x1, y1 = geographic_to_web_mercator(NY[0], NY[1])
    tile_provider = get_provider(CARTODBPOSITRON)

    # range bounds supplied in web mercator coordinates
    w = 40000
    m = figure(x_range=(x1 - w, x1 + w),
               y_range=(y1 - w, y1 + w),
               height=500,
               width=600,
               x_axis_location=None,
               y_axis_location=None,
               toolbar_location='below',
               tools="pan,wheel_zoom,reset",
               active_scroll='auto')
    m.add_tile(tile_provider)
    circles = m.circle(x="mercx",
                       y="mercy",
                       size=8,
                       source=source,
                       fill_color="midnightblue",
                       fill_alpha=1)
    tooltips = [('Name', "@school_name"), ('Address', "@address")]
    m.add_tools(HoverTool(renderers=[circles], tooltips=tooltips))

    return data_table, m, div0
def fill_data_source(deconvolution_data):
    p.text = "Visualizations are being produced..."

    img_width = deconvolution_data[0][0].shape[0]
    img_height = deconvolution_data[0][0].shape[1]

    # get original image
    try:
        images_folder = join(UPLOAD_FOLDER, user, file, 'images')
        image_name = listdir(images_folder)[-1]
        orig_img = np.array(
            Image.open(join(images_folder, image_name)).resize(
                (img_width, img_height)))
    except FileNotFoundError:
        raise FileNotFoundError(
            str(e) +
            '. No visualization input image found in the image folder')

    # create plot for the original image
    orig_img_fig = figure(title="Original Image",
                          plot_width=250,
                          plot_height=250,
                          tools="reset, save, pan",
                          x_range=Range1d(0, img_width, bounds=(0, img_width)),
                          y_range=Range1d(0,
                                          img_height,
                                          bounds=(0, img_height)),
                          outline_line_color="black",
                          outline_line_width=3)
    orig_img_fig.add_tools(BoxZoomTool(match_aspect=True))
    orig_img_fig.axis.visible = False
    orig_img_fig.toolbar.logo = None

    add_image_from_array(orig_img_fig, orig_img)

    layout.children.append(orig_img_fig)

    figures = []

    # loop through deconvolution data
    for array, layer_name, feat_map_no in deconvolution_data:

        name = "{}_{}".format(layer_name, feat_map_no)
        title = "#{} in {}".format(feat_map_no, layer_name)

        fig = figure(title=title,
                     tools="reset, save, pan",
                     plot_width=250,
                     plot_height=250,
                     outline_line_color="black",
                     outline_line_width=3,
                     x_range=orig_img_fig.x_range,
                     y_range=orig_img_fig.y_range)
        fig.add_tools(BoxZoomTool(match_aspect=True))
        fig.axis.visible = False
        fig.toolbar.logo = None
        fig.min_border_left = 20

        add_image_from_source(fig, deconvolution_source, array, name)

        figures.append(fig)

    # make a grid of the feature maps
    grid = gridplot(figures, ncols=4, toolbar_options=dict(logo=None))

    layout.children.append(
        Div(text="<div align='center'><b>Feature Map Visualizations</b></div>",
            width=1000))
    layout.children.append(grid)
    p.text = ""
Beispiel #30
0
def test_layout_constructor(panel):
    div1 = Div()
    div2 = Div()
    layout = panel(div1, div2)

    assert all(isinstance(p, Bokeh) for p in layout.objects)
heimdall_source = ColumnDataSource(data=dict(x=[], y=[]))
sigproc_source = ColumnDataSource(data=dict(
    disp=[], dedisp=[],
    conv=[]))  #This will change depending upon the input from sigproc

##################### Creating the interface for the candidate viewer #####################

#UTC input text box
utc_input = TextInput(value="Enter UTC here",
                      title="UTC (YYYY-MM-DD-HH:SS:SS)")
SAMPLE_UTC = "2018-04-08-11:08:23"
print SAMPLE_UTC

# Error text box
errbox = Div(text="", width=800)
errtext = open(os.path.join(os.path.dirname(__file__), "errbox.html")).read()

#Candidate viewer plot
x_axis = Select(title="X-axis", options=sorted(HeimdallHeader), value="snr")
y_axis = Select(title="Y-axis", options=sorted(HeimdallHeader), value="dm")

candview = figure(plot_height=600,
                  plot_width=800,
                  title="Candidate Viewer",
                  tools=['tap', 'pan', 'wheel_zoom', 'reset'])
candview_plot = candview.circle(x='x', y='y', source=heimdall_source, size=6)

#Create range sliders for filtering the candidates in the candview plot - (can add more eventually)
snr_range = RangeSlider(title="SNR", start=0, end=10, value=(0, 10), step=1)
dm_range = RangeSlider(title="DM", start=0, end=10, value=(0, 10), step=1)
Beispiel #32
0
 def create_layout(self):
     hr = Div(text="<hr />", style={"width": "100%"})
     return column(self.app_select, self.model_select, self.field_select,
                   hr, self.field_info)
Beispiel #33
0
    def bkapp(self, doc):
        basePath = self.basePath
        npyPath = self.npyPath
        covMapDict = self.covMapDict

        self.logger.debug('basePath: ' + str(basePath))
        self.logger.debug('npyPath: ' + str(npyPath))
        self.logger.debug('covMapDict: ' + str(covMapDict))

        # Retrieving Data
        #-----------------------------------------------------------------
        # Loading in data
        curPath = os.getcwd()

        # Loading distance difference matrices
        self.logger.info('Reading npy matrices from: ' + str(npyPath))
        npyNameList = [npyFile for npyFile in os.listdir(npyPath) \
                               if (npyFile[-3:] == 'npy') \
                               and ('Minus' in npyFile) \
                               and ('Scaled' not in npyFile)]

        self.logger.debug('npyNameList: ' + str(npyNameList))

        npyList = [None] * len(npyNameList)
        for i, npyName in enumerate(npyNameList):
            npyList[i] = np.load(os.path.join(npyPath, npyName))

        self.logger.debug('npyList: ' + str(npyList))

        # Loading and defining dictionaries to map to and fro residue pairs to
        # the corresponding submatrices
        invCovMapDict = {str(value): key for key, value in covMapDict.items()}

        # Loading Covariance Matrix and helper class to split submatrices
        self.logger.info('Loading CovarianceMatrix.npy')
        covarianceMatrix = np.load(os.path.join(basePath, \
                                                'CovarianceMatrix.npy'))
        self.covSize = covarianceMatrix.shape[0]
        self.logger.info('Loaded CovarianceMatrix.npy')
        cSubmatrix = CovSubmatrix()
        #-----------------------------------------------------------------

        # Interactive Plot Tools
        TOOLS = 'hover,save,pan,box_zoom,reset,wheel_zoom'

        # Defining color values
        vmin = -5
        vmax = 5

        # New Color Map Bokeh
        blueRedColors = [
            '#FF0000', '#FF1111', '#FF2222', '#FF3333', '#FF4444', '#FF5555',
            '#FF6666', '#FF7777', '#FF8888', '#FF9999', '#FFAAAA', '#FFBBBB',
            '#FFCCCC', '#FFDDDD', '#FFEEEE', '#FFFFFF', '#EEEEFF', '#DDDDFF',
            '#CCCCFF', '#BBBBFF', '#AAAAFF', '#9999FF', '#8888FF', '#7777FF',
            '#6666FF', '#5555FF', '#4444FF', '#3333FF', '#2222FF', '#1111FF',
            '#0000FF'
        ]

        # Creating list
        axesXMax = npyList[0].shape[0]
        if int(self.scale) != int(npyList[0].shape[0]):
            axesXMax = self.scale
        axesYMax = npyList[0].shape[1]
        if int(self.scale) != int(npyList[0].shape[1]):
            axesYMax = self.scale

        xyPairList = [None] * axesXMax * axesYMax

        for i in range(0, axesXMax):
            for j in range(0, axesYMax):
                xyPairList[i + j * axesXMax] = (i + 1, j + 1)

        self.logger.debug('xyPairList: ' + str(xyPairList))
        self.logger.debug('type: xyPairList: ' + str(type(xyPairList)))

        # Reshaping source values in order to shift indices from starting
        # with 0 to starting with 1
        xVals = np.transpose(xyPairList)[0]
        yVals = np.transpose(xyPairList)[1]
        covVals = npyList[0].flatten()
        self.logger.debug('npyList: ' + str(npyList))
        self.logger.debug('covVals: ' + str(covVals))

        # Checks to see if the specified scale matches
        axesLength = int(np.sqrt(len(covVals)))
        self.indexDict = None
        self.scaledRangeDict = None
        if axesLength != int(self.scale):
            axesLength = self.scale
            newMatrix, self.indexDict = self.rescaleMatrix(covVals, self.scale)
            covVals = newMatrix.flatten()

        # Creating a dictionary mapping the new indices to
        # strings describing the ranges of the original indices
        if self.indexDict is not None:
            self.scaledRangeDict = self.serializeIndexDict(self.indexDict)

            # Saving the scaled index mapping to file
            indexDictFilepath = os.path.join(basePath, 'scaledIndexMap.npy')
            np.save(indexDictFilepath, self.indexDict, allow_pickle=True)
            self.logger.info('Saving the scaled index mapping to: ' \
                             + str(indexDictFilepath))

        self.logger.debug('scaledRangeDict: ' + str(self.scaledRangeDict))

        # Defining fields to be displayed in hover tooltips
        source = ColumnDataSource(
            data={
                'x': xVals.flatten(),
                'y': yVals.flatten(),
                'covValues': covVals.flatten()
            })

        tooltipList = [('xCoord', '@x'), ('yCoord', '@y'),
                       ('Magnitude', '@covValues')]

        # Defining color map
        color_mapper = LinearColorMapper(palette=blueRedColors,
                                         low=vmin,
                                         high=vmax)

        color_bar = ColorBar(color_mapper=color_mapper,
                             label_standoff=12,
                             border_line_color=None, location=(0,0),
                             ticker=BasicTicker(\
                                desired_num_ticks=len(blueRedColors)))

        # Plotting
        self.logger.info('Determining axis scaling.')
        if self.scaledRangeDict is not None:
            plotLabel = FactorRange(
                factors=[i for i in self.scaledRangeDict.values()],
                bounds=(0.5, len(self.scaledRangeDict.keys()) + 0.5),
                factor_padding=0.0,
                range_padding_units="percent",
                range_padding=0)
        else:
            plotLabel = FactorRange(
                            factors=[str(int(i+1)) \
                                     for i in range(axesLength)],
                           bounds=(0.5, axesLength + 0.5))

        self.logger.info('Creating initial figure')
        # Primary display for directly interacting with the matrices
        plot = figure(x_range=plotLabel,
                      y_range=plotLabel,
                      tools=TOOLS,
                      toolbar_location='below',
                      tooltips=tooltipList)

        plot.add_tools(EnhanceTool())

        plot.xaxis.major_label_orientation = math.pi / 2

        self.logger.info('Creating initial primary plot')
        plot.rect(x='x',
                  y='y',
                  width=1,
                  height=1,
                  source=source,
                  fill_color={
                      'field': 'covValues',
                      'transform': color_mapper
                  },
                  line_color=None)

        plot.title = Title(text='Distance Difference Matrix: ' \
                           + npyNameList[0], \
                           align='center')

        plot.add_layout(color_bar, 'right')

        # Secondary display for interacting with queued covariance submatrices
        plot2 = figure(x_range=plotLabel,
                       y_range=plotLabel,
                       tools=TOOLS,
                       toolbar_location='below',
                       tooltips=tooltipList)
        plot2.add_tools(EnhanceTool())
        plot2.xaxis.major_label_orientation = math.pi / 2

        source2 = ColumnDataSource(
            data={
                'x': xVals.flatten(),
                'y': yVals.flatten(),
                'covValues': [0 for i in covVals.flatten()]
            })

        self.logger.info('Creating initial secondary plot')
        plot2.rect(x='x',
                   y='y',
                   width=1,
                   height=1,
                   source=source2,
                   fill_color={
                       'field': 'covValues',
                       'transform': color_mapper
                   },
                   line_color=None)

        plot2.title = Title(text='Queued Covariance Submatrices',
                            align='center')

        plot2.add_layout(color_bar, 'right')

        # Creating a dictionary of distance difference matrices based off of
        # order they are loaded in
        self.logger.debug('Creating distance difference matrix mapping')
        matrixDict = {}
        for i, npy in enumerate(npyList):
            if i not in matrixDict.keys():
                matrixDict[str(i)] = npyList[i].flatten()

        # Python Callbacks
        # ------------------------------------------------------------------

        # Takes a flattened matrix and updates the plot to its values
        def patchMatrixValues(newMatrix, source=source):
            if (int(self.scale) \
                    != int(math.ceil(math.sqrt(newMatrix.shape[0])))):

                newMatrix, indexDict = self.rescaleMatrix(
                    newMatrix, self.scale)
                newMatrix = newMatrix.flatten()
            patch_id = [i for i in range(len(source.data['covValues']))]
            patch = newMatrix
            source.patch({'covValues': list(zip(patch_id, patch))})

        # Slider Callback
        # Changes the distance difference matrix displayed based off of the index
        # that the slider is set to
        def sliderCallback(attr, old, new):
            plot.x_range.factors = [
                str(i) for i in self.scaledRangeDict.values()
            ]
            plot.x_range.factors = [
                str(i) for i in self.scaledRangeDict.values()
            ]
            f = str(new)
            covValues = source.data['covValues']
            axesLength = math.sqrt(len(covValues))
            patchMatrixValues(matrixDict[f])
            plot.title.text = 'Distance Difference Matrix: ' + npyNameList[new]

        # Click callback for moving from distance difference matrices to
        # covariance submatrices
        def clickCallback(event):
            plot.x_range.factors = [
                str(i) for i in self.scaledRangeDict.values()
            ]
            plot.x_range.factors = [
                str(i) for i in self.scaledRangeDict.values()
            ]
            start_time = time.time()
            axesLength = math.sqrt(len(source.data['covValues']))
            xCoord = math.floor(event.x - 0.5)
            yCoord = math.floor(event.y - 0.5)

            # Only accessing covariance submatrix if the click is not along
            # the diagonal
            if ((xCoord != yCoord) and (xCoord >= 0)
                    and (xCoord < axesLength + 1) and (yCoord >= 0)
                    and (yCoord < axesLength + 1)):
                # Handles coordinates "mirrored" across the diagonal
                if (xCoord > yCoord):
                    temp = xCoord
                    xCoord = yCoord
                    yCoord = temp
                coordString = '(' + str(xCoord) + ', ' + str(yCoord) + ')'
                # Handles submatrix access for non-scaled indices
                subMatrix = None
                if self.indexDict is None:
                    covIndex = invCovMapDict[coordString]
                    resPairString = '[' + coordString + ']'
                    subMatrix = cSubmatrix.generateSubmatrix(
                        covarianceMatrix,
                        covMapDict,
                        residuePairList=resPairString,
                        allResidues=False,
                        baseDirectory=None).flatten()
                    self.logger.debug('Submatrix for x=' + str(xCoord) \
                                       + ', y=' + str(yCoord) + ': ' \
                                       + str(subMatrix))
                # Handles submatrix access for scaled/mapped indices/ranges
                else:
                    resPairString = ''
                    for xIndex in self.indexDict[xCoord]:
                        for yIndex in self.indexDict[yCoord]:
                            if len(resPairString) > 0:
                                resPairString += ','
                            resPairString += '(' + str(xIndex) \
                                             + ', ' + str(yIndex) + ')'
                    resPairString = '[' + resPairString + ']'
                    if self.queueState == False:
                        subMatrixList = cSubmatrix.generateSubmatrix(
                            covarianceMatrix,
                            covMapDict,
                            residuePairList=resPairString,
                            allResidues=False,
                            baseDirectory=None,
                            scale=self.scale)
                        subMatrixArray = np.array(subMatrixList)
                        # Multiple submatrices case, takes the average of
                        # given submatrices
                        if len(subMatrixArray.shape) >= 3:
                            subMatrix = np.average(subMatrixArray, axis=0)
                        else:
                            subMatrix = subMatrixList
                    else:
                        self.logger.debug('Appending ' + str(resPairString) \
                                          + ' to queueList')
                        self.queueList.append([
                            int(xCoord + 1),
                            int(yCoord + 1),
                            str(resPairString)
                        ])
                        toQueueDiv.text += ' (' + str(xCoord+1) + ','\
                                        + str(yCoord+1)+'),'

                if self.queueState == False:
                    patchMatrixValues(subMatrix)

                    # Changing plot title name to reflect the covariance pair
                    # with which the covariance submatrix is plotted in respect to
                    xCoord += 1
                    yCoord += 1
                    displayString = '(' + str(xCoord) + ', ' + str(
                        yCoord) + ')'
                    plot.title.text = 'Covariance Submatrix: Residue Pair: ' \
                                      + displayString

            # TODO: When speed comparisons are done, remove the time printouts
            print('Time to compute submatrix: ' +
                  str(time.time() - start_time))

        # Distance Difference Matrix Display Callback
        # Shows current distance difference matrix if not already shown
        def ddCallback(event):
            plot.x_range.factors = [
                str(i) for i in self.scaledRangeDict.values()
            ]
            plot.x_range.factors = [
                str(i) for i in self.scaledRangeDict.values()
            ]
            f = str(slider.value)
            patchMatrixValues(matrixDict[f])
            plot.title.text = 'Distance Difference Matrix: ' \
                              + npyNameList[int(f)]

        # Reset Button Callback
        # Resets display to the 0th index distance difference matrix
        def resetCallback(event):
            plot.x_range.factors = [
                str(i) for i in self.scaledRangeDict.values()
            ]
            plot.x_range.factors = [
                str(i) for i in self.scaledRangeDict.values()
            ]
            slider.value = 0
            f = str(slider.value)
            patchMatrixValues(matrixDict[f])
            plot.title.text = 'Distance Difference Matrix: ' \
                              + npyNameList[0]

        # Forward Button Callback
        # Moves DD Index forward by 1 and displays DD matrix
        def forwardCallback(event):
            plot.x_range.factors = [
                str(i) for i in self.scaledRangeDict.values()
            ]
            plot.x_range.factors = [
                str(i) for i in self.scaledRangeDict.values()
            ]
            if slider.value < len(matrixDict.keys()) - 1:
                slider.value = slider.value + 1
                f = str(slider.value)
                patchMatrixValues(matrixDict[f])
                plot.title.text = 'Distance Difference Matrix: ' \
                                  + npyNameList[int(f)]

        # Backward Button Callback
        # Moves DD Index backward by 1 and displays DD matrix
        def backwardCallback(event):
            plot.x_range.factors = [
                str(i) for i in self.scaledRangeDict.values()
            ]
            plot.x_range.factors = [
                str(i) for i in self.scaledRangeDict.values()
            ]
            if slider.value > 0:
                slider.value = slider.value - 1
                f = str(slider.value)
                patchMatrixValues(matrixDict[f])
                plot.title.text = 'Distance Difference Matrix: ' + npyNameList[
                    int(f)]

        # Forward Queue Callback
        # Moves down the queue to display the next covariance submatrix
        def forwardQCallback(event):
            plot.x_range.factors = [
                str(i) for i in self.scaledRangeDict.values()
            ]
            plot.x_range.factors = [
                str(i) for i in self.scaledRangeDict.values()
            ]
            if ((self.curQueue is None) and (len(self.queueMatrices) == 0)):
                return
            elif ((self.curQueue is None) and (len(self.queueMatrices) >= 0)):
                self.curQueue = 0
                patchMatrixValues(self.queueMatrices[self.curQueue], source2)
                plot2.title.text = 'Queued Covariance Submatrices: '\
                                   + 'Residue Pair: ' \
                                   + self.queueNameList[self.curQueue]
                indexDiv.text = 'Index: ' + str(self.curQueue)
            elif (self.curQueue >= len(self.queueMatrices)):
                return
            elif (self.curQueue < (len(self.queueMatrices) - 1)):
                self.curQueue += 1
                print('Acessing curQueue: ' + str(self.curQueue))
                print('len(self.queueMatrices): ' +
                      str(len(self.queueMatrices)))
                patchMatrixValues(self.queueMatrices[self.curQueue], source2)
                plot2.title.text = 'Queued Covariance Submatrices: '\
                                   + 'Residue Pair: ' \
                                   + self.queueNameList[self.curQueue]
                indexDiv.text = 'Index: ' + str(self.curQueue)

        # Backward Queue Callback
        # Moves up the queue to display the previous covariance submatrix
        def backwardQCallback(event):
            plot.x_range.factors = [
                str(i) for i in self.scaledRangeDict.values()
            ]
            plot.x_range.factors = [
                str(i) for i in self.scaledRangeDict.values()
            ]
            if ((self.curQueue is None) and (len(self.queueMatrices) == 0)):
                return
            elif ((self.curQueue is None) and (len(self.queueMatrices) >= 0)):
                self.curQueue = 0
                patchMatrixValues(self.queueMatrices[self.curQueue], source2)
                plot2.title.text = 'Queued Covariance Submatrices: '\
                                   + 'Residue Pair: ' \
                                   + self.queueNameList[self.curQueue]
                indexDiv.text = 'Index: ' + str(self.curQueue)
            elif (self.curQueue >= len(self.queueMatrices)):
                return
            elif (self.curQueue > 0):
                self.curQueue -= 1
                self.logger.debug('Accessing curQueue: ' + str(self.curQueue))
                self.logger.debug('len(self.queueMatrices): ' \
                                  + str(len(self.queueMatrices)))
                patchMatrixValues(self.queueMatrices[self.curQueue], source2)
                plot2.title.text = 'Queued Covariance Submatrices: '\
                                   + 'Residue Pair: ' \
                                   + self.queueNameList[self.curQueue]
                indexDiv.text = 'Index: ' + str(self.curQueue)

        # Queue Button Callback
        # Toggles queueing mode for residue pairs/ranges
        def queueCallback(event):
            # Turning on queuing
            if self.queueState == False:
                self.queueState = True
                toQueueDiv.text = 'Queued Covariance Submatrices:'
                statusDiv.text = 'Status: Queuing residue pairs'
            # Turning off queuing and then patching the covariance submatrices
            # to secondary plot
            else:
                self.queueState = False
                qList = self.queueList
                self.queueList = []
                # TODO: Bokeh doesn't update display until after loop runs
                statusDiv.text = 'Status: Computing covariance submatrices'
                for matrixPak in qList:
                    xCoord = int(matrixPak[0])
                    yCoord = int(matrixPak[1])
                    resPairString = str(matrixPak[2])
                    subMatrixArray = np.array(
                        cSubmatrix.generateSubmatrix(
                            covarianceMatrix,
                            covMapDict,
                            residuePairList=resPairString,
                            allResidues=False,
                            baseDirectory=None,
                            scale=self.scale))
                    # Multiple submatrices case, takes the average of
                    # given submatrices
                    if len(subMatrixArray.shape) >= 3:
                        subMatrix = np.average(subMatrixArray, axis=0)
                    else:
                        subMatrix = subMatrixList

                    self.queueMatrices.append(subMatrix)
                    patchMatrixValues(subMatrix, source2)

                    # Changing plot title name to reflect the covariance pair
                    # with which the covariance submatrix is plotted in respect
                    # to
                    xCoord += 1
                    yCoord += 1
                    displayString = '(' + str(xCoord) + ', ' + str(
                        yCoord) + ')'
                    self.queueNameList.append(displayString)
                    plot2.title.text = 'Queued Covariance Submatrix: ' \
                                      + 'Residue Pair: ' \
                                      + displayString
                    computedDiv.text = 'Computed Submatrices: ' \
                                       + str(sorted(set(self.queueNameList)))
                    totalNumberDiv.text = '/' + str(len(self.queueMatrices))
                statusDiv.text = 'Status: Submatrix computation complete. Idling'

        # "Enhances" the selected region by taking the range of residues and
        # redisplays the plot so it shows only this range of residues at the
        # given resolution
        def zoomSelectCallback(event, matrixType="dd"):
            geometry = event.geometry
            f = str(slider.value)
            # Retrieving the boundaries of the rectangular selection
            # The -0.5 offset accounts for the offset of each square from
            # the original axis
            x0 = math.floor(geometry['x0'] - 0.5)
            x1 = math.floor(geometry['x1'] - 0.5)
            y0 = math.floor(geometry['y0'] - 0.5)
            y1 = math.floor(geometry['y1'] - 0.5)

            # Retrieving the boundaries of the current matrix
            # (in terms of currently displayed coordinates)
            sourceDF = source.to_df()
            xi = min(sourceDF['x'])
            xf = max(sourceDF['x'])
            yi = min(sourceDF['y'])
            yf = max(sourceDF['y'])

            width = x1 - x0
            height = y1 - y0

            # Use these values to get information about what scale
            # the matrix is and is going to be
            # self.scale
            # self.covSize -> need to find size for distance difference
            #                 matrices and make a separate case for them?
            # Also need to figure out how to deal with asymmetric boundaries
            # where width/height are not equal
            # binSize - the number of units in a given bin
            axesSize = int(math.sqrt(len(list(matrixDict.values())[0])))
            if ((matrixType == "dd") or (matrixType is None)):
                matrix = matrixDict[str(slider.value)].reshape(
                    axesSize, axesSize)
            elif (matrixType == "covMatrix"):
                indexDiv = int(self.curQueue)
                matrix = self.queueMatrices[indexDiv].reshape(
                    axesSize, axesSize)

            binSize = int(math.ceil(axesSize / self.scale))
            if ((x0 + max(width, height)) <= axesSize / binSize):
                xUpperBound = x0 + max(width, height)
                xLowerBound = x0
            else:
                if ((x1 - max(width, height)) >= 0):
                    xUpperBound = x1
                    xLowerBound = x1 - max(width, height)
                else:
                    xUpperBound = int(axesSize / binSize)
                    xLowerBound = int(axesSize / binSize - x1)

            if ((y0 + max(width, height)) <= axesSize / binSize):
                yUpperBound = y0 + max(width, height)
                yLowerBound = y0
            else:
                if ((y1 - max(width, height)) >= 0):
                    yUpperBound = y1
                    yLowerBound = y1 - max(width, height)
                else:
                    yUpperBound = int(axesSize / binSize)
                    yLowerBound = int(axesSize / binSize - y1)

            if ((xUpperBound - xLowerBound) > (yUpperBound - yLowerBound)):
                yUpperBound = xUpperBound
                yLowerBound = xLowerBound
            if ((xUpperBound - xLowerBound) < (yUpperBound - yLowerBound)):
                xUpperBound = yUpperBound
                xLowerBound = yLowerBound

            zoomedMatrix = matrix[xLowerBound * binSize:xUpperBound * binSize,
                                  yLowerBound * binSize:yUpperBound * binSize]

            # Modifying axes labels to reflect the zoomedMatrix
            # Parsing the boundaries to determine the raw index range
            xIndexMax = int(self.scaledRangeDict[xUpperBound].split('-')[1])
            xIndexMin = int(self.scaledRangeDict[xLowerBound].split('-')[0])
            yIndexMax = int(self.scaledRangeDict[yUpperBound].split('-')[1])
            yIndexMin = int(self.scaledRangeDict[yLowerBound].split('-')[0])

            # Partitioning the elements into self.scale number of bins
            numElements = xIndexMax - xIndexMin
            xIndexDict = self.partitionIndices(numElements,
                                               self.scale,
                                               offset=xIndexMin)
            yIndexDict = self.partitionIndices(numElements,
                                               self.scale,
                                               offset=yIndexMin)

            xRangeDict = self.serializeIndexDict(xIndexDict)
            yRangeDict = self.serializeIndexDict(yIndexDict)

            plot.x_range.factors = [i for i in xRangeDict.values()]
            plot.y_range.factors = [i for i in yRangeDict.values()]

            zoomedMatrix = zoomedMatrix.flatten()
            patchMatrixValues(zoomedMatrix, source)

        # ------------------------------------------------------------------

        # Creating buttons and linking them to their corresponding callbacks

        # Buttons to navigate distance difference matrices
        buttonBack = Button(label="Back", button_type="success")
        buttonBack.on_event(ButtonClick, backwardCallback)
        buttonDD = Button(label="Show Distance Difference",
                          button_type="success")
        buttonDD.on_event(ButtonClick, ddCallback)
        buttonForward = Button(label="Forward", button_type="success")
        buttonForward.on_event(ButtonClick, forwardCallback)

        buttonBar = row(buttonBack, buttonDD, buttonForward)

        buttonReset = Button(label="Reset", button_type="success")
        buttonReset.on_event(ButtonClick, resetCallback)

        # Slider to also navigate distance difference matrices
        slider = Slider(start=0,
                        end=len(npyList) - 1,
                        value=0,
                        step=1,
                        title="index")
        slider.on_change('value', sliderCallback)

        # Zoom button for distance difference matrices/non-queued
        # covariance submatrices
        plot.on_event(SelectionGeometry, zoomSelectCallback)
        plot2.on_event(SelectionGeometry, zoomSelectCallback)

        # Creating a layout from plot elements
        self.queueList = []
        self.queueState = False
        self.curQueue = None
        self.queueMatrices = []
        self.queueNameList = []
        plot.on_event('tap', clickCallback)

        # Queue Buttons
        queueButton = Button(label="Queue", button_type="success")
        queueButton.on_event(ButtonClick, queueCallback)
        qBar = row(queueButton)

        # Buttons to navigate queued covariance submatrices
        qButtonBack = Button(label="Back", button_type="success")
        qButtonBack.on_event(ButtonClick, backwardQCallback)

        qButtonForward = Button(label="Forward", button_type="success")
        qButtonForward.on_event(ButtonClick, forwardQCallback)
        qNavBar = row(qButtonBack, qButtonForward)

        # Div Widgets to show which submatrix is displayed
        indexDiv = Div(text="""Index: N/A""", \
                           width=70, height=25)
        totalNumberDiv = Div(text="""/0""",\
                             width=100, height=25)
        indexDivBar = row(indexDiv, totalNumberDiv)

        # Div Widget to show which residue pairs are queued
        toQueueDiv = Div(text="""Queued Covariance Submatrices:""", \
                      width=600, height=50)

        # Div Widget to show which residue pairs are computed
        computedDiv = Div(text="""Computed Submatrices:""", \
                       width=600, height=50)

        # Div Widget to show
        statusDiv = Div(text="""Status: Nothing Queued""", \
                        width=600, height=25)

        testTitle = Title(text='Test Title', align='center')

        layout = row(
            column(plot, qBar, buttonBar, slider, buttonReset),
            column(plot2, qNavBar, statusDiv, indexDivBar, toQueueDiv,
                   computedDiv))

        # Adding the plot to the server's document
        server_doc = doc
        server_doc.add_root(layout)
        server_doc.title = "Distance Difference App"