Exemplo n.º 1
0
def create_alpha_diversity_tab():
    img_shannon = '<img src="plot_shannon.png" />'
    img_shannon_diff = '<img src="plot_shannon_diff.png" />'
    div_plot_shannon = Div(text=img_shannon)
    source = ColumnDataSource(data=dict(
        active=[img_shannon, img_shannon_diff]))
    checkbox_callback = CustomJS(args=dict(source=source),
                                 code="""
        if(this.active.length > 0) {
            div_plot_shannon.text = source.data['active'][1];
        } else {
            div_plot_shannon.text = source.data['active'][0];
        }
    """)
    checkbox_group = CheckboxGroup(
        labels=["Absolute differences to gold standard"],
        active=[],
        width=300,
        css_classes=['bk-checkbox-shannon'])
    checkbox_group.js_on_click(checkbox_callback)
    checkbox_callback.args["div_plot_shannon"] = div_plot_shannon

    shannon_column = column(checkbox_group,
                            div_plot_shannon,
                            responsive=True,
                            css_classes=[
                                'bk-shannon-plots', 'bk-width-auto',
                                'bk-width-auto-main'
                            ])

    shannon_panel = Panel(child=shannon_column, title='Shannon')
    tabs_plots = Tabs(tabs=[shannon_panel],
                      css_classes=['bk-tabs-margin', 'bk-tabs-margin-lr'])
    return tabs_plots
Exemplo n.º 2
0
dropdown_disabled.on_click(
    lambda value: print('dropdown_disabled: %s' % value))
dropdown_disabled.js_on_click(
    CustomJS(
        code="console.log('dropdown_disabled: ' + this.value, this.toString())"
    ))

#dropdown_split = Dropdown(label="Split button", button_type="danger", menu=menu, default_value="default")
#dropdown_split.on_click(lambda value: print('dropdown_split: %s' % value))
#dropdown_split.js_on_click(CustomJS(code="console.log('dropdown_split: ' + this.value, this.toString())"))

checkbox_group = CheckboxGroup(labels=["Option 1", "Option 2", "Option 3"],
                               active=[0, 1])
checkbox_group.on_click(lambda value: print('checkbox_group: %s' % value))
checkbox_group.js_on_click(
    CustomJS(
        code="console.log('checkbox_group: ' + this.active, this.toString())"))

radio_group = RadioGroup(labels=["Option 1", "Option 2", "Option 3"], active=0)
radio_group.on_click(lambda value: print('radio_group: %s' % value))
radio_group.js_on_click(
    CustomJS(
        code="console.log('radio_group: ' + this.active, this.toString())"))

checkbox_button_group = CheckboxButtonGroup(
    labels=["Option 1", "Option 2", "Option 3"], active=[0, 1])
checkbox_button_group.on_click(
    lambda value: print('checkbox_button_group: %s' % value))
checkbox_button_group.js_on_click(
    CustomJS(
        code=
                     args={
                         'aline': aline,
                         'bline': bline
                     })

callback2 = CustomJS(code="""cline.visible = false; // aline and etc.. are 
                             dline.visible = false; // passed in from args
        
                            // cb_obj is injected in thanks to the callback
                             if (cb_obj.active.includes(0)){cline.visible = true;} 
                                // 0 index box is aline
                             if (cb_obj.active.includes(1)){dline.visible = true;} 
                                // 1 index box is bline
                            """,
                     args={
                         'cline': cline,
                         'dline': dline
                     })

checkboxes1.js_on_click(callback1)
checkboxes2.js_on_click(callback2)

layout1 = row(p1, checkboxes1)
layout2 = row(p2, checkboxes2)
layout = column(layout1, layout2)
# output_file('BV2_DUT_sensors_134_sections.html')
# show(column(p1, p2, checkboxes))
curdoc().add_root(layout)
curdoc().title = "Temperatures_BV12"

show(layout)
Exemplo n.º 4
0
def DesnivelPositivoAcumulado(DatosBokeh, EjeX, MetricasAuxiliares):
    """
        GRAFICO AREA | DESNIVEL POSITIVO ACUMULADO
    """

    # Creacion del diccionario de metricas auxiliares
    DiccionarioVariables = ParametrosVariables(DatosBokeh)

    # Generacion del codigo JavaScript que habilita la visualizacion de metricas auxiliares
    CodigoJS = GeneracionCodigoJS(MetricasAuxiliares)

    # Asignacion de tamaño del punto en graficas discretas
    SizeCircle = FunctionSizeCircle(DatosBokeh)

    # Creacion de un grafica
    PLT = figure(width=1000,
                 height=400,
                 x_range=(DatosBokeh.data[EjeX].min(),
                          DatosBokeh.data[EjeX].max()),
                 y_range=(LimiteEjeY(DatosBokeh, 'DESNIVEL POSITIVO',
                                     'Inferior'),
                          LimiteEjeY(DatosBokeh, 'DESNIVEL POSITIVO',
                                     'Superior')),
                 tools='',
                 toolbar_location=None)

    # Creacion del area bajo la linea de la metrica a partir del CDS
    Area = DatosBokeh.to_df().copy().reset_index()[[
        EjeX, 'DesnivelPositivo[m]'
    ]].set_index(EjeX)
    Area.rename(columns={'DesnivelPositivo[m]': 'Area'}, inplace=True)
    AreaBottom = Area[::-1]
    AreaBottom['Area'] = 0
    PLT.patch(x=hstack((AreaBottom.index, Area.index)),
              y=hstack((AreaBottom['Area'], Area['Area'])),
              color=Lavender[0],
              alpha=1,
              line_color=None)

    # Inclusion de datos
    PLT_Linea = PLT.line(EjeX,
                         'DesnivelPositivo[m]',
                         source=DatosBokeh,
                         color=Lavender[1],
                         line_width=2,
                         line_cap='round')
    PLT.add_tools(
        HoverTool(tooltips=[('', '@{DesnivelPositivo[m]}{int} m')],
                  renderers=[PLT_Linea],
                  mode='vline'))

    # Inclusion de lineas auxiliares
    ListadoMetricasAuxiliares = {}
    for Metrica in MetricasAuxiliares:
        if DiccionarioVariables[Metrica]['Tipo'] == 'circle':
            ListadoMetricasAuxiliares[
                'l' + str(MetricasAuxiliares.index(Metrica))] = PLT.circle(
                    EjeX,
                    DiccionarioVariables[Metrica]['Variable'].split('[', 1)[0]
                    + DiccionarioVariables['DESNIVEL POSITIVO']['Sufijo'],
                    source=DiccionarioVariables[Metrica]['CDS'],
                    size=SizeCircle,
                    line_color=DiccionarioVariables[Metrica]['Color'],
                    color=DiccionarioVariables[Metrica]['Color'],
                    **DiccionarioVariables[Metrica]['Propiedades'])
        elif DiccionarioVariables[Metrica]['Tipo'] == 'step':
            ListadoMetricasAuxiliares[
                'l' + str(MetricasAuxiliares.index(Metrica))] = PLT.step(
                    EjeX,
                    DiccionarioVariables[Metrica]['Variable'].split('[', 1)[0]
                    + DiccionarioVariables['DESNIVEL POSITIVO']['Sufijo'],
                    source=DiccionarioVariables[Metrica]['CDS'],
                    color=DiccionarioVariables[Metrica]['Color'],
                    **DiccionarioVariables[Metrica]['Propiedades'])
        else:
            ListadoMetricasAuxiliares[
                'l' + str(MetricasAuxiliares.index(Metrica))] = PLT.line(
                    EjeX,
                    DiccionarioVariables[Metrica]['Variable'].split('[', 1)[0]
                    + DiccionarioVariables['DESNIVEL POSITIVO']['Sufijo'],
                    source=DiccionarioVariables[Metrica]['CDS'],
                    color=DiccionarioVariables[Metrica]['Color'],
                    **DiccionarioVariables[Metrica]['Propiedades'])

    # Atributos
    PLT.title.text = 'DESNIVEL POSITIVO ACUMULADO'
    PLT.sizing_mode = 'fixed'
    PLT.yaxis.axis_label = 'Desnivel positivo acumulado [m]'
    PLT.yaxis.formatter = NumeralTickFormatter(format='0')
    PLT.grid.visible = False
    PLT.yaxis.minor_tick_line_color = None
    PLT.yaxis.major_label_overrides = FormateoEjes(
        DatosBokeh.data['DesnivelPositivo[m]'], 100, 1)

    # Asignacion de opciones de visualizacion del eje X
    if EjeX == 'Distancia[m]':
        PLT.xaxis.axis_label = 'Distancia'
        PLT.xaxis.formatter = NumeralTickFormatter(format='0')
        if DatosBokeh.data['Distancia[m]'].max() >= 4000:
            PLT.xaxis.ticker = SingleIntervalTicker(interval=1000)
            PLT.xaxis.major_label_overrides = FormateoEjes(
                DatosBokeh.data['Distancia[m]'], 1000, 1000, 0, 0)
    elif EjeX == 'TiempoActividad':
        PLT.xaxis.axis_label = 'Tiempo actividad'
        PLT.xaxis.formatter = DatetimeTickFormatter(hourmin='%H:%M:%S',
                                                    minutes='%M:%S',
                                                    seconds='%Ss')
        PLT.xaxis.ticker = DatetimeTicker()
    elif EjeX == 'TiempoTotal':
        PLT.xaxis.axis_label = 'Tiempo total'
        PLT.xaxis.formatter = DatetimeTickFormatter(hourmin='%H:%M:%S',
                                                    minutes='%M:%S',
                                                    seconds='%Ss')
        PLT.xaxis.ticker = DatetimeTicker()

    #Botones
    Botones = CheckboxGroup(labels=MetricasAuxiliares,
                            active=[],
                            width=100,
                            height=380)
    ListadoMetricasAuxiliares['checkbox'] = Botones
    CodigoJSFrecuenciaCardiaca = CustomJS(code=CodigoJS,
                                          args=ListadoMetricasAuxiliares)
    Botones.js_on_click(CodigoJSFrecuenciaCardiaca)

    #Layout
    GridBotones = layout(
        [Spacer(width=100, height=25),
         Column(Botones, width=100, height=375)],
        sizing_mode='fixed',
        width=100,
        height=400)
    GridGrafica = gridplot([PLT, GridBotones],
                           ncols=2,
                           sizing_mode='stretch_width',
                           toolbar_location=None,
                           plot_width=1100,
                           plot_height=400)

    return GridGrafica
Exemplo n.º 5
0
def html_postages(coord=None, idx=None, veto=None, info=None, layer_list=None, BoxSize=40):


    plots = {}
    sources = []
    layers = []

    RA, DEC = coord[0], coord[1]
    scale_unit='pixscale'
    scale=0.262
    boxsize = BoxSize #2*m*radius*3600
    radius = BoxSize/(2 * 3600)
    size = int(round(boxsize/scale))
    figsize = int(128)
    #print('BoxSize', boxsize)
    #print('Size', size)

    idx_list = idx #random.sample(list(idx), rows*cols)

    if info is None:
        info = {'RA':RA, 'DEC':DEC}

    if veto is None:
        veto = {'all':np.ones_like(RA, dtype=bool)}

    if layer_list is None:

        layer_list = ['dr9f-south', 'dr9f-south-model', 'dr9f-south-resid', 'dr9g-south', 'dr9g-south-model', 'dr9g-south-resid',
                 'dr9f-north', 'dr9f-north-model', 'dr9f-north-resid', 'dr9g-north', 'dr9g-north-model', 'dr9g-north-resid']


    for idx in idx_list:

        RAidx = RA[idx]
        DECidx = DEC[idx]

        ramin, ramax = RAidx-radius, RAidx+radius
        decmin, decmax = DECidx-radius, DECidx+radius
        dra = (ramax - ramin)/40
        ddec = (decmax - decmin)/40
        mask = (RA > ramin + dra) & (RA < ramax - dra) & (DEC > decmin + ddec) & (DEC < decmax - ddec)

        TOOLTIPS = []

        for key in info.keys():
            TOOLTIPS.append((key, '@'+key))

        p = figure(plot_width=2*figsize, plot_height=2*figsize, tooltips=TOOLTIPS, tools="tap, save, zoom_in, zoom_out, crosshair")
        p.axis.visible = False
        p.toolbar.logo = None
        p.toolbar_location = None
        #p.min_border = 0

        layers2 = []
        for layer in layer_list:

            source='https://www.legacysurvey.org/viewer-dev/jpeg-cutout/?ra=%.12f&dec=%.12f&%s=%g&layer=%s&size=%g' % (RAidx, DECidx, scale_unit, scale, layer, size)
            url='https://www.legacysurvey.org/viewer-dev?ra=%.12f&dec=%.12f&layer=%s&zoom=15' %(RAidx, DECidx, layer)
            imfig_source = ColumnDataSource(data=dict(url=[source], txt=[source]))
            image1 = ImageURL(url="url", x=0, y=1, w=size, h=size, anchor='bottom_left')
            img_source = p.add_glyph(imfig_source, image1)

            layers2.append(img_source)

        taptool = p.select(type=TapTool)
        taptool.callback = OpenURL(url=url)

        colors = ['green', 'red', 'blue', 'cyan', 'yellow']
        circle_i = []
        for color, key, val in zip(colors, veto.keys(), veto.values()):

            ravpix, decvpix = coordtopix(center=[RAidx, DECidx], coord=[RA[(mask) & (val)], DEC[(mask) & (val)]], size=size, scale=scale)

            data = {}
            data['x'] = ravpix
            data['y'] = decvpix
            for info_key, info_val in zip(info.keys(), info.values()):
                if isinstance(info_val[0], (bytes, bytearray)):
                    data[info_key] = np.array(info_val)[(mask) & (val)].astype('U13')
                else:
                    data[info_key] = np.array(info_val)[(mask) & (val)]

            sourceCirc = ColumnDataSource(data=data)

            circle = p.circle('x', 'y', source=sourceCirc, size=15, fill_color=None, line_color=color, line_width=3)
            circle_i.append(circle)

        lineh = Span(location=size/2, dimension='height', line_color='white', line_dash='solid', line_width=1)
        linew = Span(location=size/2, dimension='width', line_color='white', line_dash='solid', line_width=1)

        p.add_layout(lineh)
        p.add_layout(linew)
        p.background_fill_color = "black"
        #p.outline_line_width = 15
        #p.outline_line_alpha = 0.7

        p.xgrid.grid_line_color = None
        p.ygrid.grid_line_color = None

        plots[str(idx)] = p

        sources.append(circle_i)
        layers.append(layers2)


    checkbox = CheckboxGroup(labels=list(veto.keys()), active=list(np.arange(len(veto))))
    iterable = [elem for part in [[('_'.join(['line',str(figid),str(lineid)]),line) for lineid,line in enumerate(elem)] for figid,elem in enumerate(sources)] for elem in part]
    checkbox_code = ''.join([elem[0]+'.visible=checkbox.active.includes('+elem[0].split('_')[-1]+');' for elem in iterable])
    callback = CustomJS(args={key:value for key,value in iterable+[('checkbox',checkbox)]}, code=checkbox_code)

    # print('===== plots ======')
    # print(checkbox_code)
    # print('====')
    # print({key:value for key,value in iterable+[('checkbox',checkbox)]})

    checkbox.js_on_click(callback)

    #script, div = components(plots)
    #print(div)

    radio = RadioGroup(labels=layer_list, active=len(layer_list)-1)
    iterable2 = [elem for part in [[('_'.join(['line',str(figid),str(lineid)]),line) for lineid,line in enumerate(elem)] for figid,elem in enumerate(layers)] for elem in part]
    #
    N = len(layer_list)
    text = []
    for elem in iterable2[::N]:
        for n in range(N):
            text.append('%s%s.visible=false;' %(elem[0][:-1], str(n)))
        for n in range(N):
            if n == 0: text.append('if (cb_obj.active == 0) {%s%s.visible = true;}' %(elem[0][:-1], str(0)))
            if n != 0: text.append('else if (cb_obj.active == %s) {%s%s.visible = true;}' %(str(n), elem[0][:-1], str(n)))

    radiogroup_code = ''.join(text)

    callback2 = CustomJS(args={key:value for key,value in iterable2+[('radio',radio)]}, code=radiogroup_code)
    radio.js_on_change('active', callback2)


    # for key,val in zip(plots.keys(), plots.values()):
    #     print(key, '\t', val)

    #script, div = components(plots)
    #controls = WidgetBox(radio, checkbox)
    #plots['controls'] = components(radio)
    #script_2, div_2 = components(controls)

    #print('===== plots ======')
    plots['checkbox'] = checkbox
    plots['radio'] = radio

    return components(plots)
Exemplo n.º 6
0
def dash_line(x: str,
              y: str,
              data: pd.DataFrame,
              figsize: tuple = (1000, 400),
              title: str = None,
              x_axis_label: str = None,
              y_axis_label: str = None):
    """Create dashboard line plot

    Args:
        x (str): Column in x axis
        y (str): Column in y axis
        data (pd.DataFrame): Data frame contaning the above. It also must contain
                            columns for the max, min and mean of y axis
        figsize (tuple, optional): Width and height of figure. Defaults to (1000, 400).
        title (str, optional): Figure title. Defaults to None.
        x_axis_label (str, optional): X-axis label. Defaults to None.
        y_axis_label (str, optional): Y-axis label. Defaults to None.

    Returns:
        bokeh object: Plotted figure

    References:
        [1] https://www.reddit.com/r/learnpython/comments/8ythxo/how_to_use_checkbox_in_bokeh_with_pandas/

    Example: TODO: 
        >>> show(dash_line())
    """
    # 1. Define variables

    y_max = f"{y}_max"
    y_min = f"{y}_min"
    y_mean = f"{y}_mean"

    title = title or f"{y} vs {x}"

    tools = "xwheel_pan, ywheel_pan, pan,wheel_zoom,xwheel_zoom,ywheel_zoom,box_zoom,reset,save"

    # 2. Instantiate plot object

    if np.issubdtype(data[x].dtype, np.datetime64):
        line = figure(x_axis_type="datetime",
                      plot_width=figsize[0],
                      plot_height=figsize[1],
                      title=title,
                      toolbar_location="above",
                      tools=tools)

    else:
        line = figure(plot_width=figsize[0],
                      plot_height=figsize[1],
                      title=title,
                      toolbar_location="above",
                      tools=tools)

    ## 2.1. Add axes labels

    line.xaxis.axis_label = x or x_axis_label
    line.yaxis.axis_label = y or y_axis_label

    # 3. Add circles
    line.circle(x=x, y=y, source=data)

    # 4. Add hover tooltip
    ## 4.1. Format the tooltip
    tooltips = [(y, f"@{y}"), (x, f"@{x}")]
    hover = HoverTool(tooltips=tooltips)

    ## 4.2. Add the HoverTool to the figure
    line.add_tools(HoverTool(tooltips=tooltips))

    # 5. Format figure
    ## 5.1. Remove grey frame
    line.outline_line_color = None

    ## 5.2. Remove axis line
    line.xaxis.axis_line_width = 0
    line.yaxis.axis_line_width = 0

    ## 5.3. Remove grid
    line.xgrid.grid_line_color = None
    line.ygrid.grid_line_color = None

    ## 5.4. Remove tick markers
    # line.xaxis.major_tick_line_color = None  # turn off x-axis major ticks
    line.xaxis.minor_tick_line_color = None  # turn off x-axis minor ticks

    # line.yaxis.major_tick_line_color = None  # turn off y-axis major ticks
    line.yaxis.minor_tick_line_color = None  # turn off y-axis minor ticks

    ## 5.5. Add text
    # mytext = Label(x=data[x].max(), y=data[y].iloc[-1], text=y)
    # line.add_layout(mytext)

    # 6. Create rendering objects for callback
    line_renderer = line.line(x=x, y=y, line_width=2, source=data)
    line_max = line.line(x=x,
                         y=y_max,
                         line_width=1,
                         source=data,
                         line_dash="dashed",
                         line_alpha=0.25,
                         line_color="black")
    line_mean = line.line(x=x,
                          y=y_mean,
                          line_width=1,
                          source=data,
                          line_dash="dotted",
                          line_alpha=0.25,
                          line_color="black")
    line_min = line.line(x=x,
                         y=y_min,
                         line_width=1,
                         source=data,
                         line_dash="dashed",
                         line_alpha=0.25,
                         line_color="black")

    # 7. Create checkbox callback. See [1]
    checkboxes = CheckboxGroup(labels=["max", "mean", "min"], active=[0, 1, 2])
    callback = CustomJS(
        code="""line_max.visible = false; // same xline passed in from args
                                line_mean.visible = false;
                                line_min.visible = false;
                                // cb_obj injected in by the callback
                                if (cb_obj.active.includes(0)){line_max.visible = true;}
                                if (cb_obj.active.includes(1)){line_mean.visible = true;}
                                if (cb_obj.active.includes(2)){line_min.visible = true;}
                                """,
        args={
            'line_max': line_max,
            'line_mean': line_mean,
            'line_min': line_min
        })
    checkboxes.js_on_click(callback)

    return row(line, checkboxes)
Exemplo n.º 7
0
toggle_active = Toggle(label="Toggle button (initially active)", button_type="success", active=True)
toggle_active.js_on_click(CustomJS(code="console.log('toggle_active: ' + this.active, this.toString())"))

menu = [("Item 1", "item_1_value"), ("Item 2", "item_2_value"), None, ("Item 3", "item_3_value")]

dropdown = Dropdown(label="Dropdown button", button_type="warning", menu=menu)
dropdown.js_on_click(CustomJS(code="console.log('dropdown: ' + this.value, this.toString())"))

dropdown_disabled = Dropdown(label="Dropdown button (disabled)", button_type="warning", disabled=True, menu=menu)
dropdown_disabled.js_on_click(CustomJS(code="console.log('dropdown_disabled: ' + this.value, this.toString())"))

#dropdown_split = Dropdown(label="Split button", button_type="danger", menu=menu, default_value="default")
#dropdown_split.js_on_click(CustomJS(code="console.log('dropdown_split: ' + this.value, this.toString())"))

checkbox_group = CheckboxGroup(labels=["Option 1", "Option 2", "Option 3"], active=[0, 1])
checkbox_group.js_on_click(CustomJS(code="console.log('checkbox_group: ' + this.active, this.toString())"))

radio_group = RadioGroup(labels=["Option 1", "Option 2", "Option 3"], active=0)
radio_group.js_on_click(CustomJS(code="console.log('radio_group: ' + this.active, this.toString())"))

checkbox_button_group = CheckboxButtonGroup(labels=["Option 1", "Option 2", "Option 3"], active=[0, 1])
checkbox_button_group.js_on_click(CustomJS(code="console.log('checkbox_button_group: ' + this.active, this.toString())"))

radio_button_group = RadioButtonGroup(labels=["Option 1", "Option 2", "Option 3"], active=0)
radio_button_group.js_on_click(CustomJS(code="console.log('radio_button_group: ' + this.active, this.toString())"))

widget_box = WidgetBox(children=[
    button, button_disabled,
    toggle_inactive, toggle_active,
    dropdown, dropdown_disabled, #dropdown_split,
    checkbox_group, radio_group,
                            if (cb_obj.active.includes(12)){jline.visible = true;} 
                                // 1 index box is bline
                            if (cb_obj.active.includes(13)){kline.visible = true;} 
                             if (cb_obj.active.includes(14)){kkline.visible = true;} 
                                // 1 index box is bline
                            """,
                    args={
                        'aline': aline,
                        'bline': bline,
                        'cline': cline,
                        'ccline': ccline,
                        'dline': dline,
                        'ddline': ddline,
                        'eline': eline,
                        'fline': fline,
                        'gline': gline,
                        'ggline': ggline,
                        'hline': hline,
                        'iline': iline,
                        'jline': jline,
                        'kline': kline,
                        'kkline': kkline
                    })
checkboxes.js_on_click(callback)
layout = row(p1, checkboxes)
# output_file('BV2_DUT_sensors_134_sections.html')
# show(column(p1, p2, checkboxes))
curdoc().add_root(layout)
curdoc().title = "BOKEH_TEMPLATE"

show(layout)
Exemplo n.º 9
0
class ViewerVIWidgets(object):
    """ 
    Encapsulates Bokeh widgets, and related callbacks, used for VI
    """
    
    def __init__(self, title, viewer_cds):
        self.vi_quality_labels = [ x["label"] for x in vi_flags if x["type"]=="quality" ]
        self.vi_issue_labels = [ x["label"] for x in vi_flags if x["type"]=="issue" ]
        self.vi_issue_slabels = [ x["shortlabel"] for x in vi_flags if x["type"]=="issue" ]
        self.js_files = get_resources('js')
        self.title = title
        self.vi_countdown_toggle = None

        #- List of fields to be recorded in output csv file, contains for each field: 
        # [ field name (in VI file header), associated variable in viewer_cds.cds_metadata ]
        self.output_file_fields = []
        for file_field in vi_file_fields:
            if file_field[1] in viewer_cds.cds_metadata.data.keys() :
                self.output_file_fields.append([file_field[0], file_field[1]])

    def add_filename(self, username='******'):
        #- VI file name
        default_vi_filename = "desi-vi_"+self.title
        default_vi_filename += ("_"+username)
        default_vi_filename += ".csv"
        self.vi_filename_input = TextInput(value=default_vi_filename, title="VI file name:")


    def add_vi_issues(self, viewer_cds, widgets):
        #- Optional VI flags (issues)
        self.vi_issue_input = CheckboxGroup(labels=self.vi_issue_labels, active=[])
        vi_issue_code = self.js_files["CSVtoArray.js"] + self.js_files["save_vi.js"]
        vi_issue_code += """
            var issues = []
            for (var i=0; i<vi_issue_labels.length; i++) {
                if (vi_issue_input.active.indexOf(i) >= 0) issues.push(vi_issue_slabels[i])
            }
            if (issues.length > 0) {
                cds_metadata.data['VI_issue_flag'][ifiberslider.value] = ( issues.join('') )
            } else {
                cds_metadata.data['VI_issue_flag'][ifiberslider.value] = " "
            }
            autosave_vi_localStorage(output_file_fields, cds_metadata.data, title)
            cds_metadata.change.emit()
            """
        self.vi_issue_callback = CustomJS(
            args=dict(cds_metadata = viewer_cds.cds_metadata,
                      ifiberslider = widgets.ifiberslider,
                      vi_issue_input = self.vi_issue_input,
                      vi_issue_labels = self.vi_issue_labels,
                      vi_issue_slabels = self.vi_issue_slabels,
                      title = self.title, output_file_fields = self.output_file_fields),
                      code = vi_issue_code )
        self.vi_issue_input.js_on_click(self.vi_issue_callback)


    def add_vi_z(self, viewer_cds, widgets):
    ## TODO: z_tovi behaviour if with_vi_widget=False ..?
        #- Optional VI information on redshift
        self.vi_z_input = TextInput(value='', title="VI redshift:")
        vi_z_code = self.js_files["CSVtoArray.js"] + self.js_files["save_vi.js"]
        vi_z_code += """
            cds_metadata.data['VI_z'][ifiberslider.value]=vi_z_input.value
            autosave_vi_localStorage(output_file_fields, cds_metadata.data, title)
            cds_metadata.change.emit()
            """
        self.vi_z_callback = CustomJS(
            args=dict(cds_metadata = viewer_cds.cds_metadata,
                      ifiberslider = widgets.ifiberslider,
                      vi_z_input = self.vi_z_input,
                      title = self.title, output_file_fields=self.output_file_fields),
                      code = vi_z_code )
        self.vi_z_input.js_on_change('value', self.vi_z_callback)

        # Copy z value from redshift slider to VI
        self.z_tovi_button = Button(label='Copy z to VI')
        self.z_tovi_callback = CustomJS(
            args=dict(z_input=widgets.z_input, vi_z_input=self.vi_z_input),
            code="""
                vi_z_input.value = z_input.value
            """)
        self.z_tovi_button.js_on_event('button_click', self.z_tovi_callback)

    def add_vi_spectype(self, viewer_cds, widgets):
        #- Optional VI information on spectral type
        self.vi_category_select = Select(value=' ', title="VI spectype:", options=([' '] + vi_spectypes))
        # The default value set to ' ' as setting value='' does not seem to work well with Select.
        vi_category_code = self.js_files["CSVtoArray.js"] + self.js_files["save_vi.js"]
        vi_category_code += """
            if (vi_category_select.value == ' ') {
                cds_metadata.data['VI_spectype'][ifiberslider.value]=''
            } else {
                cds_metadata.data['VI_spectype'][ifiberslider.value]=vi_category_select.value
            }
            autosave_vi_localStorage(output_file_fields, cds_metadata.data, title)
            cds_metadata.change.emit()
            """
        self.vi_category_callback = CustomJS(
            args=dict(cds_metadata=viewer_cds.cds_metadata, 
                      ifiberslider = widgets.ifiberslider,
                      vi_category_select=self.vi_category_select,
                      title=self.title, output_file_fields=self.output_file_fields),
            code=vi_category_code )
        self.vi_category_select.js_on_change('value', self.vi_category_callback)


    def add_vi_comment(self, viewer_cds, widgets):
        #- Optional VI comment
        self.vi_comment_input = TextInput(value='', title="VI comment (see guidelines):")
        vi_comment_code = self.js_files["CSVtoArray.js"] + self.js_files["save_vi.js"]
        vi_comment_code += """
            var stored_comment = (vi_comment_input.value).replace(/./g, function(char){
                if ( char==',' ) {
                    return ';'
                } else if ( char.charCodeAt(0)<=127 ) {
                    return char
                } else {
                    var char_list = ['Å','α','β','γ','δ','λ']
                    var char_replace = ['Angstrom','alpha','beta','gamma','delta','lambda']
                    for (var i=0; i<char_list.length; i++) {
                        if ( char==char_list[i] ) return char_replace[i]
                    }
                    return '?'
                }
            })
            cds_metadata.data['VI_comment'][ifiberslider.value] = stored_comment
            autosave_vi_localStorage(output_file_fields, cds_metadata.data, title)
            cds_metadata.change.emit()
            """
        self.vi_comment_callback = CustomJS(
            args=dict(cds_metadata = viewer_cds.cds_metadata,
                      ifiberslider = widgets.ifiberslider, 
                      vi_comment_input = self.vi_comment_input,
                      title=self.title, output_file_fields=self.output_file_fields),
            code=vi_comment_code )
        self.vi_comment_input.js_on_change('value',self.vi_comment_callback)

        #- List of "standard" VI comment
        self.vi_std_comment_select = Select(value=" ", title="Standard comment:", options=([' '] + vi_std_comments))
        vi_std_comment_code = """
            if (vi_std_comment_select.value != ' ') {
                if (vi_comment_input.value != '') {
                    vi_comment_input.value = vi_comment_input.value + " " + vi_std_comment_select.value
                } else {
                    vi_comment_input.value = vi_std_comment_select.value
                }
            }
            """
        self.vi_std_comment_callback = CustomJS(
            args = dict(vi_std_comment_select = self.vi_std_comment_select,
                        vi_comment_input = self.vi_comment_input),
                        code = vi_std_comment_code )
        self.vi_std_comment_select.js_on_change('value', self.vi_std_comment_callback)


    def add_vi_quality(self, viewer_cds, widgets):
        #- Main VI quality widget
        self.vi_quality_input = RadioButtonGroup(labels=self.vi_quality_labels)
        vi_quality_code = self.js_files["CSVtoArray.js"] + self.js_files["save_vi.js"]
        vi_quality_code += """
            if ( vi_quality_input.active >= 0 ) {
                cds_metadata.data['VI_quality_flag'][ifiberslider.value] = vi_quality_labels[vi_quality_input.active]
            } else {
                cds_metadata.data['VI_quality_flag'][ifiberslider.value] = "-1"
            }
            autosave_vi_localStorage(output_file_fields, cds_metadata.data, title)
            cds_metadata.change.emit()
        """
        self.vi_quality_callback = CustomJS(
            args = dict(cds_metadata = viewer_cds.cds_metadata,
                        vi_quality_input = self.vi_quality_input,
                        vi_quality_labels = self.vi_quality_labels,
                        ifiberslider = widgets.ifiberslider,
                        title=self.title, output_file_fields = self.output_file_fields),
            code=vi_quality_code )
        self.vi_quality_input.js_on_click(self.vi_quality_callback)

    def add_vi_scanner(self, viewer_cds):
        #- VI scanner name
        self.vi_name_input = TextInput(value=(viewer_cds.cds_metadata.data['VI_scanner'][0]).strip(), title="Your name (3-letter acronym):")
        vi_name_code = self.js_files["CSVtoArray.js"] + self.js_files["save_vi.js"]
        vi_name_code += """
            for (var i=0; i<(cds_metadata.data['VI_scanner']).length; i++) {
                cds_metadata.data['VI_scanner'][i]=vi_name_input.value
            }
            var newname = vi_filename_input.value
            var name_chunks = newname.split("_")
            newname = ( name_chunks.slice(0,name_chunks.length-1).join("_") ) + ("_"+vi_name_input.value+".csv")
            vi_filename_input.value = newname
            autosave_vi_localStorage(output_file_fields, cds_metadata.data, title)
            """
        self.vi_name_callback = CustomJS(
            args = dict(cds_metadata = viewer_cds.cds_metadata,
                        vi_name_input = self.vi_name_input,
                        vi_filename_input = self.vi_filename_input, title=self.title,
                        output_file_fields = self.output_file_fields),
            code=vi_name_code )
        self.vi_name_input.js_on_change('value', self.vi_name_callback)

    def add_guidelines(self):
        #- Guidelines for VI flags
        vi_guideline_txt = "<B> VI guidelines </B>"
        vi_guideline_txt += "<BR /> <B> Classification flags: </B>"
        for flag in vi_flags :
            if flag['type'] == 'quality' : vi_guideline_txt += ("<BR />&emsp;&emsp;[&emsp;"+flag['label']+"&emsp;] "+flag['description'])
        vi_guideline_txt += "<BR /> <B> Optional indications: </B>"
        for flag in vi_flags :
            if flag['type'] == 'issue' :
                vi_guideline_txt += ( "<BR />&emsp;&emsp;[&emsp;" + flag['label'] +
                                     "&emsp;(" + flag['shortlabel'] + ")&emsp;] " + flag['description'] )
        vi_guideline_txt += "<BR /> <B> Comments: </B> <BR /> 100 characters max, avoid commas (automatically replaced by semi-columns), ASCII only."
        self.vi_guideline_div = Div(text=vi_guideline_txt)

    def add_vi_storage(self, viewer_cds, widgets):
        #- Save VI info to CSV file
        self.save_vi_button = Button(label="Download VI", button_type="success")
        save_vi_code = self.js_files["FileSaver.js"] + self.js_files["CSVtoArray.js"] + self.js_files["save_vi.js"]
        save_vi_code += """
            download_vi_file(output_file_fields, cds_metadata.data, vi_filename_input.value)
            """
        self.save_vi_callback = CustomJS(
            args = dict(cds_metadata = viewer_cds.cds_metadata,
                        output_file_fields = self.output_file_fields,
                        vi_filename_input = self.vi_filename_input),
                        code=save_vi_code )
        self.save_vi_button.js_on_event('button_click', self.save_vi_callback)

        #- Recover auto-saved VI data in browser
        self.recover_vi_button = Button(label="Recover auto-saved VI", button_type="default")
        recover_vi_code = self.js_files["CSVtoArray.js"] + self.js_files["recover_autosave_vi.js"]
        self.recover_vi_callback = CustomJS(
            args = dict(title=self.title, output_file_fields=self.output_file_fields,
                        cds_metadata = viewer_cds.cds_metadata,
                        ifiber = widgets.ifiberslider.value, vi_comment_input = self.vi_comment_input,
                        vi_name_input=self.vi_name_input, vi_quality_input=self.vi_quality_input,
                        vi_issue_input=self.vi_issue_input,
                        vi_issue_slabels=self.vi_issue_slabels, vi_quality_labels=self.vi_quality_labels),
                        code = recover_vi_code )
        self.recover_vi_button.js_on_event('button_click', self.recover_vi_callback)

        #- Clear all auto-saved VI
        self.clear_vi_button = Button(label="Clear all auto-saved VI", button_type="default")
        self.clear_vi_callback = CustomJS( args = dict(), code = """
            localStorage.clear()
            """ )
        self.clear_vi_button.js_on_event('button_click', self.clear_vi_callback)

    def add_vi_table(self, viewer_cds):
        #- Show VI in a table
        vi_table_columns = [
            TableColumn(field="VI_quality_flag", title="Flag", width=40),
            TableColumn(field="VI_issue_flag", title="Opt.", width=50),
            TableColumn(field="VI_z", title="VI z", width=50),
            TableColumn(field="VI_spectype", title="VI spectype", width=150),
            TableColumn(field="VI_comment", title="VI comment", width=200)
        ]
        self.vi_table = DataTable(source=viewer_cds.cds_metadata, columns=vi_table_columns, width=500)
        self.vi_table.height = 10 * self.vi_table.row_height


    def add_countdown(self, vi_countdown):
        #- VI countdown
        assert vi_countdown > 0
        self.vi_countdown_callback = CustomJS(args=dict(vi_countdown=vi_countdown), code="""
            if ( (cb_obj.label).includes('Start') ) { // Callback doesn't do anything after countdown started
                var countDownDate = new Date().getTime() + (1000 * 60 * vi_countdown);
                var countDownLoop = setInterval(function(){
                    var now = new Date().getTime();
                    var distance = countDownDate - now;
                    if (distance<0) {
                        cb_obj.label = "Time's up !";
                        clearInterval(countDownLoop);
                    } else {
                        var days = Math.floor(distance / (1000 * 60 * 60 * 24));
                        var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
                        var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
                        var seconds = Math.floor((distance % (1000 * 60)) / 1000);
                        //var stuff = days + "d " + hours + "h " + minutes + "m " + seconds + "s ";
                        var stuff = minutes + "m " + seconds + "s ";
                        cb_obj.label = "Countdown: " + stuff;
                    }
                }, 1000);
            }
        """)
        self.vi_countdown_toggle = Toggle(label='Start countdown ('+str(vi_countdown)+' min)', active=False, button_type="success")
        self.vi_countdown_toggle.js_on_change('active', self.vi_countdown_callback)
Exemplo n.º 10
0
def ajax_getplot(x, y, y_bottom, ref_value):  #fi,ff,y_bottom,ref_value,x,y):
    # En la ventana del plot
    graf = figure(tools="save",
                  x_axis_label="Frequency [Hz]",
                  y_axis_label='Power [dBm]',
                  width=700,
                  height=400,
                  sizing_mode='stretch_width',
                  x_range=(x[0], x[-1]),
                  y_range=(float(y_bottom), float(ref_value)))
    graf.toolbar.logo = None
    graf.toolbar.active_drag = None
    graf.toolbar.active_scroll = None

    graf.yaxis.major_label_text_font_style = 'bold'
    graf.xaxis.major_label_text_font_style = 'bold'
    graf.xaxis.axis_label_text_font_style = 'bold'
    graf.yaxis.axis_label_text_font_style = 'bold'
    graf.xaxis[0].formatter.use_scientific = True

    graf.xaxis[0].ticker.desired_num_ticks = 15
    graf.yaxis[0].ticker.desired_num_ticks = 10
    graf.ygrid.grid_line_alpha = 0.4
    graf.ygrid.grid_line_dash = [6, 4]
    graf.xgrid.grid_line_alpha = 0.4
    graf.xgrid.grid_line_dash = [6, 4]
    # graf.ygrid.minor_grid_line_alpha = 0.1
    # graf.ygrid.minor_grid_line_color = 'navy'
    # graf.xgrid.minor_grid_line_alpha = 0.1

    graf.background_fill_color = "black"
    graf.border_fill_color = "black"
    graf.border_fill_alpha = 0
    graf.xaxis.axis_line_color = "white"
    graf.yaxis.axis_line_color = "white"

    props = dict(line_width=4, line_alpha=0.7)

    # source for (marker_abs, markers [CANT_MARKERS])
    source_markers = ColumnDataSource(data={})

    # source for table of graf's markers
    source_table = ColumnDataSource()
    # strings for table of graf's markers
    source_table_share = ColumnDataSource(
    )  # only for share strings of table's rows between graf_adapter.js, checkbox_callback.js

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

    # button_height   = 30
    # button_width    = 70
    #SLIDER_WIDTH    = 500 # px
    CHECKBOX_WIDTH = 100

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

    if x != 0 and y != 0:
        max_abs_y = max(y)
        max_abs_x = argmax(y)
        #x_npa=asarray(x)
        y_npa = asarray(y)
        x_axis = linspace(x[0], x[-1], len(x))
    else:
        y_bottom = -100
        ref_value = -60
        y_npa = asarray([0, 0])
        x_axis = [0, 0]
        max_abs_y = 0
        max_abs_x = 0

#################################################################################################################################################################
# Sliders de marcadores

# solicitar frecuencias al analizador
    sliders = []
    if x[0] != x[-1]:
        step = (x[-1] - x[0]) / len(x)

        if step <= 0:
            step = 1

        init = (max_abs_x * step) + x[0]

        for i in range(0, CANT_MARKERS):
            sliders.append(
                Slider(start=x[0],
                       end=x[-1],
                       value=init,
                       step=step,
                       title="MARKER " + str(i + 1)))

    else:
        for i in range(0, CANT_MARKERS):
            sliders.append(
                Slider(start=0,
                       end=1,
                       value=0,
                       step=1,
                       title="MARKER " + str(i + 1)))

#################################################################################################################################################################
# Tablas de configuracion (las de solo lectura)

    source_set_an = ColumnDataSource()
    source_set_gen = ColumnDataSource()
    source_set_powm = ColumnDataSource()

    #################################################################################################################################################################
    # preparo el marcador movil

    # ve posibilidad de agregar PointDrawTool de hovertools
    # http://docs.bokeh.org/en/1.0.0/docs/user_guide/tools.html#click-tap-tools

    graf.add_tools(
        HoverTool(
            tooltips=[
                ('frec', '@x{0,0} Hz'),
                ('amp', '@y dBm'),  # use @{ } for field names with spaces
            ],
            point_policy='follow_mouse',
            mode='vline'))

    with open("static/js/graf_adapter.js", "r") as f:
        code = f.read()

    adapter = CustomJS(args=dict(graf=graf,
                                 sliders=sliders,
                                 source_markers=source_markers,
                                 source_table=source_table,
                                 source_table_share=source_table_share,
                                 source_set_an=source_set_an,
                                 source_set_gen=source_set_gen,
                                 source_set_powm=source_set_powm),
                       code=code)

    source = AjaxDataSource(data_url=request.url_root + 'data/',
                            polling_interval=1000,
                            mode='replace',
                            adapter=adapter)

    source.data = dict(x=[],
                       y=[],
                       y_bottom=[],
                       ref_value=[],
                       start_freq=[],
                       stop_freq=[])  #, power = [] )
    # span = [], center_freq = [], demod_time = [], ref_level = [], # ANALIZADOR
    # lf_freq = [], lf_level = [], rf_freq = [], rf_level = [], fm_mod_freq = [], am_mod_freq = [],am_mod_index= [],fm_mod_index= [],pm_mod_index= [], power = []) # GENERADOR

    graf.line('x', 'y', source=source, line_color="cyan")

    ###############################################################################

    # maximos relativos
    max_rel_x = argrelextrema(y_npa, greater)  #dato pasado a numpy array

    ###############################################################################

    # datos para la tabla de datos
    info = []
    value = []

    # tabla de datos
    source_table.data = dict(x_data=info, y_data=value)
    source_table_share.data = dict(x_data=info, y_data=value)
    #source_table = source
    columns = [
        TableColumn(field="x_data", title="Information"),
        TableColumn(field="y_data", title="Value")
    ]

    data_table = DataTable(source=source_table,
                           columns=columns,
                           height=200,
                           width=400)

    ###############################################################################
    set_div = Div(text="<b>Current Settings</b>")

    # tabla de valores seteados actualmente del analizador
    source_set_an.data = dict(
        configuration=[
            "X scale", "Y scale", "Start freq", "Stop freq", "Span",
            "Center freq", "Ref level", "Demod time", "Demod type",
            "Input att", "Resolution BW", "Scale div", "Avg state", "Avg times"
        ],
        value=[
            "LIN", "LOG", "0.0", "1.0", "1.0", "1.0", "0.0", "0.0", "FM", "10",
            "100000", "10.0", "WRITe", "1"
        ],
    )

    columns_set_an = [
        TableColumn(field="configuration", title="Analizer"),
        TableColumn(field="value", title="value"),
    ]
    info_table_an = DataTable(source=source_set_an,
                              columns=columns_set_an,
                              width=220,
                              height=180)

    # tabla de valuees seteados actualmente en el generador
    source_set_gen.data = dict(
        configuration=[
            "LF state", "LF freq", "LF level", "LF waveform", "RF state",
            "RF freq", "RF level", "AM state", "AM source", "AM mod freq",
            "AM mod index", "AM waveform", "Modulation type",
            "Modulation state", "FM mod freq", "FM mod index", "FM waveform",
            "PM mod freq", "PM mod index", "PM waveform"
        ],
        value=[
            "OFF", "0.0", "0.0", "SINE", "0.0", "0.0", "0.0", "OFF", "INT",
            "0.0", "0.0", "SINE", "FM", "OFF", "0.0", "0.0", "SINE", "0.0",
            "0.0", "0.0"
        ],
    )

    columns_set_gen = [
        TableColumn(field="configuration", title="Generator"),
        TableColumn(field="value", title="value"),
    ]
    info_table_gen = DataTable(source=source_set_gen,
                               columns=columns_set_gen,
                               width=220,
                               height=180)

    # tabla de valuees seteados actualmente en el generador
    source_set_powm.data = dict(
        configuration=["Duty cycle", "Average"],
        value=["50", "1"],
    )

    columns_set_powm = [
        TableColumn(field="configuration", title="Power meter"),
        TableColumn(field="value", title="value"),
    ]
    info_table_powm = DataTable(source=source_set_powm,
                                columns=columns_set_powm,
                                width=200,
                                height=180)

    #source_table = source

    ###############################################################################
    ## cosas a graficar

    # source5 = ColumnDataSource(data=dict(x5=[x_axis[max_abs_x]], y5=[max_abs_y]))
    # source4 = ColumnDataSource(data=dict(x4=[x_axis[max_abs_x]], y4=[max_abs_y]))
    # source3 = ColumnDataSource(data=dict(x3=[x_axis[max_abs_x]], y3=[max_abs_y]))
    # source2 = ColumnDataSource(data=dict(x2=[x_axis[max_abs_x]], y2=[max_abs_y]))

    # source5 = ColumnDataSource(data=dict(x5=[], y5=[]))
    # source4 = ColumnDataSource(data=dict(x4=[], y4=[]))
    # source3 = ColumnDataSource(data=dict(x3=[], y3=[]))
    # source2 = ColumnDataSource(data=dict(x2=[], y2=[]))

    # marcadores moviles que arrancan en el absolute maximum
    # l5=graf.circle('x5', 'y5', source=source5, color="lawngreen", line_width=8, line_alpha=0.7 )
    # l4=graf.circle('x4', 'y4', source=source4, color="lime", line_width=8, line_alpha=0.7)
    # l3=graf.circle('x3', 'y3', source=source3, color="yellow", line_width=8, line_alpha=0.7)
    # l2=graf.circle('x2', 'y2', source=source2, color="blue", line_width=8, line_alpha=0.7)

    # custom markers
    #markers_rel_dict = {}
    markers = []
    colors = ["yellow", "red", "pink", "lime"]
    for i in range(0, CANT_MARKERS):
        x_label = 'x_mark_' + str(i + 1)
        y_label = 'y_mark_' + str(i + 1)
        source_markers.data[x_label] = [x_axis[max_abs_x]]
        source_markers.data[y_label] = [max_abs_y]
        markers.append(
            graf.circle(x_label,
                        y_label,
                        source=source_markers,
                        color=colors[i],
                        line_width=8,
                        line_alpha=0.7))

    #l1=graf.circle(x_axis[max_rel_x[0]] , y_npa[max_rel_x[0]], color="yellowgreen", **props)

    # max abs marker
    source_markers.data['x_abs'] = [x_axis[max_abs_x]]
    source_markers.data['y_abs'] = [max_abs_y]
    marker_abs = graf.circle(x='x_abs',
                             y='y_abs',
                             source=source_markers,
                             color="red",
                             line_width=8,
                             line_alpha=0.7)

    #marker_abs=graf.circle(x_axis[max_abs_x],max_abs_y, color="green", **props)

    ###############################################################################
    # presentacion del maximo
    #maximo=str('%.2f' % max_abs_y)+"V @ "+str('%.2f' % x_axis[max_abs_x]+" rad")

    # presentacion de maximos relativos
    max_rel = ["a" for i in range(len(max_rel_x[0]))]

    for i in range(len((max_rel_x[0]))):
        max_rel[i] = (str('%.2f' % y_npa[max_rel_x[0][i]]) + "V @ " +
                      str('%.2f' % x_axis[max_rel_x[0][i]] + " rad"))

    ###############################################################################
    # Sliders de marcadores

    #callback unico para todos los sliders
    with open("static/js/callback_sm.js", "r") as f:
        callback_sm_code = f.read()

    callback_sm = CustomJS(args=dict(source_table=source_table,
                                     source=source,
                                     source_markers=source_markers,
                                     sliders=sliders,
                                     markers=markers,
                                     graf=graf,
                                     props=props),
                           code=callback_sm_code)

    for i in range(0, CANT_MARKERS):
        sliders[i].js_on_change('value', callback_sm)

    ###############################################################################

    # Acciones relativas a los checkbox
    checkbox_labels = ["Max. Abs"]
    # checkbox_labels = ["Max. Abs", "Max. Rel"]
    checkbox_preset = CheckboxGroup(labels=checkbox_labels,
                                    active=[],
                                    width=CHECKBOX_WIDTH)

    checkbox_mark = CheckboxGroup(
        labels=["Mark 1", "Mark 2", "Mark 3", "Mark 4"],
        active=[],
        width=CHECKBOX_WIDTH)

    #checkbox.active=[] <- indica los índices de los elementos "activados" (para activar el 1: [1], para activar el 0 y el 3: [0 3])
    #checkbox.active=[]
    #checkbox.active[0]=False
    marker_abs.visible = False
    #checkbox.active[1]=False
    for i in range(0, CANT_MARKERS):
        markers[i].visible = False
        pass

    #checkbox_mark.active=[]
    #checkbox_mark.active[0]=False
    # marker[i].visible=False
    #checkbox_mark.active[1]=False
    # marker[i].visible=False
    #checkbox_mark.active[2]=False
    # marker[i].visible=False
    #checkbox_mark.active[3]=False
    # marker[i].visible=False
    ##---------------------------------------------------------------------------##
    with open("static/js/checkbox_callback.js", "r") as f:
        checkbox_code = f.read()

    cjs = CustomJS(args=dict(marker_abs=marker_abs,
                             markers=markers,
                             checkbox_preset=checkbox_preset,
                             checkbox_mark=checkbox_mark,
                             source_table=source_table,
                             source=source,
                             source_markers=source_markers,
                             source_table_share=source_table_share,
                             sliders=sliders),
                   code=checkbox_code)
    checkbox_preset.js_on_click(cjs)

    checkbox_mark.js_on_click(cjs)

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

    sliders_col = column(sliders)

    # Ploteos
    layout_graf = gridplot([[graf]],
                           sizing_mode='scale_width',
                           toolbar_location="right")
    layout_widgets = widgetbox(row(checkbox_preset, checkbox_mark, sliders_col,
                                   data_table),
                               sizing_mode='scale_width')
    layout_seteos = widgetbox(row(info_table_an, info_table_gen,
                                  info_table_powm),
                              sizing_mode='scale_width')
    analyzer_layout = layout(
        [layout_graf, layout_widgets, set_div, layout_seteos],
        sizing_mode='scale_width')

    return components(analyzer_layout)
Exemplo n.º 11
0
class ViewerWidgets(object):
    """ 
    Encapsulates Bokeh widgets, and related callbacks, that are part of prospect's GUI.
        Except for VI widgets
    """
    
    def __init__(self, plots, nspec):
        self.js_files = get_resources('js')
        self.navigation_button_width = 30
        self.z_button_width = 30
        self.plot_widget_width = (plots.plot_width+(plots.plot_height//2))//2 - 40 # used for widgets scaling
    
        #-----
        #- Ifiberslider and smoothing widgets
        # Ifiberslider's value controls which spectrum is displayed
        # These two widgets call update_plot(), later defined
        slider_end = nspec-1 if nspec > 1 else 0.5 # Slider cannot have start=end
        self.ifiberslider = Slider(start=0, end=slider_end, value=0, step=1, title='Spectrum (of '+str(nspec)+')')
        self.smootherslider = Slider(start=0, end=26, value=0, step=1.0, title='Gaussian Sigma Smooth')
        self.coaddcam_buttons = None
        self.model_select = None


    def add_navigation(self, nspec):
        #-----
        #- Navigation buttons
        self.prev_button = Button(label="<", width=self.navigation_button_width)
        self.next_button = Button(label=">", width=self.navigation_button_width)
        self.prev_callback = CustomJS(
            args=dict(ifiberslider=self.ifiberslider),
            code="""
            if(ifiberslider.value>0 && ifiberslider.end>=1) {
                ifiberslider.value--
            }
            """)
        self.next_callback = CustomJS(
            args=dict(ifiberslider=self.ifiberslider, nspec=nspec),
            code="""
            if(ifiberslider.value<nspec-1 && ifiberslider.end>=1) {
                ifiberslider.value++
            }
            """)
        self.prev_button.js_on_event('button_click', self.prev_callback)
        self.next_button.js_on_event('button_click', self.next_callback)

    def add_resetrange(self, viewer_cds, plots):
        #-----
        #- Axis reset button (superseeds the default bokeh "reset"
        self.reset_plotrange_button = Button(label="Reset X-Y range", button_type="default")
        reset_plotrange_code = self.js_files["adapt_plotrange.js"] + self.js_files["reset_plotrange.js"]
        self.reset_plotrange_callback = CustomJS(args = dict(fig=plots.fig, xmin=plots.xmin, xmax=plots.xmax, spectra=viewer_cds.cds_spectra),
                                            code = reset_plotrange_code)
        self.reset_plotrange_button.js_on_event('button_click', self.reset_plotrange_callback)


    def add_redshift_widgets(self, z, viewer_cds, plots):
        ## TODO handle "z" (same issue as viewerplots TBD)

        #-----
        #- Redshift / wavelength scale widgets
        z1 = np.floor(z*100)/100
        dz = z-z1
        self.zslider = Slider(start=-0.1, end=5.0, value=z1, step=0.01, title='Redshift rough tuning')
        self.dzslider = Slider(start=0.0, end=0.0099, value=dz, step=0.0001, title='Redshift fine-tuning')
        self.dzslider.format = "0[.]0000"
        self.z_input = TextInput(value="{:.4f}".format(z), title="Redshift value:")

        #- Observer vs. Rest frame wavelengths
        self.waveframe_buttons = RadioButtonGroup(
            labels=["Obs", "Rest"], active=0)

        self.zslider_callback  = CustomJS(
            args=dict(zslider=self.zslider, dzslider=self.dzslider, z_input=self.z_input),
            code="""
            // Protect against 1) recursive call with z_input callback;
            //   2) out-of-range zslider values (should never happen in principle)
            var z1 = Math.floor(parseFloat(z_input.value)*100) / 100
            if ( (Math.abs(zslider.value-z1) >= 0.01) &&
                 (zslider.value >= -0.1) && (zslider.value <= 5.0) ){
                 var new_z = zslider.value + dzslider.value
                 z_input.value = new_z.toFixed(4)
                }
            """)

        self.dzslider_callback  = CustomJS(
            args=dict(zslider=self.zslider, dzslider=self.dzslider, z_input=self.z_input),
            code="""
            var z = parseFloat(z_input.value)
            var z1 = Math.floor(z) / 100
            var z2 = z-z1
            if ( (Math.abs(dzslider.value-z2) >= 0.0001) &&
                 (dzslider.value >= 0.0) && (dzslider.value <= 0.0099) ){
                 var new_z = zslider.value + dzslider.value
                 z_input.value = new_z.toFixed(4)
                }
            """)

        self.zslider.js_on_change('value', self.zslider_callback)
        self.dzslider.js_on_change('value', self.dzslider_callback)

        self.z_minus_button = Button(label="<", width=self.z_button_width)
        self.z_plus_button = Button(label=">", width=self.z_button_width)
        self.z_minus_callback = CustomJS(
            args=dict(z_input=self.z_input),
            code="""
            var z = parseFloat(z_input.value)
            if(z >= -0.09) {
                z -= 0.01
                z_input.value = z.toFixed(4)
            }
            """)
        self.z_plus_callback = CustomJS(
            args=dict(z_input=self.z_input),
            code="""
            var z = parseFloat(z_input.value)
            if(z <= 4.99) {
                z += 0.01
                z_input.value = z.toFixed(4)
            }
            """)
        self.z_minus_button.js_on_event('button_click', self.z_minus_callback)
        self.z_plus_button.js_on_event('button_click', self.z_plus_callback)

        self.zreset_button = Button(label='Reset to z_pipe')
        self.zreset_callback = CustomJS(
            args=dict(z_input=self.z_input, metadata=viewer_cds.cds_metadata, ifiberslider=self.ifiberslider),
            code="""
                var ifiber = ifiberslider.value
                var z = metadata.data['Z'][ifiber]
                z_input.value = z.toFixed(4)
            """)
        self.zreset_button.js_on_event('button_click', self.zreset_callback)

        self.z_input_callback = CustomJS(
            args=dict(spectra = viewer_cds.cds_spectra,
                coaddcam_spec = viewer_cds.cds_coaddcam_spec,
                model = viewer_cds.cds_model,
                othermodel = viewer_cds.cds_othermodel,
                metadata = viewer_cds.cds_metadata,
                ifiberslider = self.ifiberslider,
                zslider = self.zslider,
                dzslider = self.dzslider,
                z_input = self.z_input,
                waveframe_buttons = self.waveframe_buttons,
                line_data = viewer_cds.cds_spectral_lines,
                lines = plots.speclines,
                line_labels = plots.specline_labels,
                zlines = plots.zoom_speclines,
                zline_labels = plots.zoom_specline_labels,
                overlap_waves = plots.overlap_waves,
                overlap_bands = plots.overlap_bands,
                fig = plots.fig
                ),
            code="""
                var z = parseFloat(z_input.value)
                if ( z >=-0.1 && z <= 5.0 ) {
                    // update zsliders only if needed (avoid recursive call)
                    z_input.value = parseFloat(z_input.value).toFixed(4)
                    var z1 = Math.floor(z*100) / 100
                    var z2 = z-z1
                    if ( Math.abs(z1-zslider.value) >= 0.01) zslider.value = parseFloat(parseFloat(z1).toFixed(2))
                    if ( Math.abs(z2-dzslider.value) >= 0.0001) dzslider.value = parseFloat(parseFloat(z2).toFixed(4))
                } else {
                    if (z_input.value < -0.1) z_input.value = (-0.1).toFixed(4)
                    if (z_input.value > 5) z_input.value = (5.0).toFixed(4)
                }

                var line_restwave = line_data.data['restwave']
                var ifiber = ifiberslider.value
                var waveshift_lines = (waveframe_buttons.active == 0) ? 1+z : 1 ;
                var waveshift_spec = (waveframe_buttons.active == 0) ? 1 : 1/(1+z) ;

                for(var i=0; i<line_restwave.length; i++) {
                    lines[i].location = line_restwave[i] * waveshift_lines
                    line_labels[i].x = line_restwave[i] * waveshift_lines
                    zlines[i].location = line_restwave[i] * waveshift_lines
                    zline_labels[i].x = line_restwave[i] * waveshift_lines
                }
                if (overlap_bands.length>0) {
                    for (var i=0; i<overlap_bands.length; i++) {
                        overlap_bands[i].left = overlap_waves[i][0] * waveshift_spec
                        overlap_bands[i].right = overlap_waves[i][1] * waveshift_spec
                    }
                }

                function shift_plotwave(cds_spec, waveshift) {
                    var data = cds_spec.data
                    var origwave = data['origwave']
                    var plotwave = data['plotwave']
                    if ( plotwave[0] != origwave[0] * waveshift ) { // Avoid redo calculation if not needed
                        for (var j=0; j<plotwave.length; j++) {
                            plotwave[j] = origwave[j] * waveshift ;
                        }
                        cds_spec.change.emit()
                    }
                }

                for(var i=0; i<spectra.length; i++) {
                    shift_plotwave(spectra[i], waveshift_spec)
                }
                if (coaddcam_spec) shift_plotwave(coaddcam_spec, waveshift_spec)

                // Update model wavelength array
                // NEW : don't shift model if othermodel is there
                if (othermodel) {
                    var zref = othermodel.data['zref'][0]
                    var waveshift_model = (waveframe_buttons.active == 0) ? (1+z)/(1+zref) : 1/(1+zref) ;
                    shift_plotwave(othermodel, waveshift_model)
                } else if (model) {
                    var zfit = 0.0
                    if(metadata.data['Z'] !== undefined) {
                        zfit = metadata.data['Z'][ifiber]
                    }
                    var waveshift_model = (waveframe_buttons.active == 0) ? (1+z)/(1+zfit) : 1/(1+zfit) ;
                    shift_plotwave(model, waveshift_model)
                }
            """)
        self.z_input.js_on_change('value', self.z_input_callback)
        self.waveframe_buttons.js_on_click(self.z_input_callback)

        self.plotrange_callback = CustomJS(
            args = dict(
                z_input=self.z_input,
                waveframe_buttons=self.waveframe_buttons,
                fig=plots.fig,
            ),
            code="""
            var z =  parseFloat(z_input.value)
            // Observer Frame
            if(waveframe_buttons.active == 0) {
                fig.x_range.start = fig.x_range.start * (1+z)
                fig.x_range.end = fig.x_range.end * (1+z)
            } else {
                fig.x_range.start = fig.x_range.start / (1+z)
                fig.x_range.end = fig.x_range.end / (1+z)
            }
            """
        )
        self.waveframe_buttons.js_on_click(self.plotrange_callback) # TODO: for record: is this related to waveframe bug? : 2 callbakcs for same click...


    def add_oii_widgets(self, plots):
        #------
        #- Zoom on the OII doublet TODO mv js code to other file
        # TODO: is there another trick than using a cds to pass the "oii_saveinfo" ?
        # TODO: optimize smoothing for autozoom (current value: 0)
        cds_oii_saveinfo = ColumnDataSource(
            {'xmin':[plots.fig.x_range.start], 'xmax':[plots.fig.x_range.end], 'nsmooth':[self.smootherslider.value]})
        self.oii_zoom_button = Button(label="OII-zoom", button_type="default")
        self.oii_zoom_callback = CustomJS(
            args = dict(z_input=self.z_input, fig=plots.fig, smootherslider=self.smootherslider,
                       cds_oii_saveinfo=cds_oii_saveinfo),
            code = """
            // Save previous setting (for the "Undo" button)
            cds_oii_saveinfo.data['xmin'] = [fig.x_range.start]
            cds_oii_saveinfo.data['xmax'] = [fig.x_range.end]
            cds_oii_saveinfo.data['nsmooth'] = [smootherslider.value]
            // Center on the middle of the redshifted OII doublet (vaccum)
            var z = parseFloat(z_input.value)
            fig.x_range.start = 3728.48 * (1+z) - 100
            fig.x_range.end = 3728.48 * (1+z) + 100
            // No smoothing (this implies a call to update_plot)
            smootherslider.value = 0
            """)
        self.oii_zoom_button.js_on_event('button_click', self.oii_zoom_callback)

        self.oii_undo_button = Button(label="Undo OII-zoom", button_type="default")
        self.oii_undo_callback = CustomJS(
            args = dict(fig=plots.fig, smootherslider=self.smootherslider, cds_oii_saveinfo=cds_oii_saveinfo),
            code = """
            fig.x_range.start = cds_oii_saveinfo.data['xmin'][0]
            fig.x_range.end = cds_oii_saveinfo.data['xmax'][0]
            smootherslider.value = cds_oii_saveinfo.data['nsmooth'][0]
            """)
        self.oii_undo_button.js_on_event('button_click', self.oii_undo_callback)


    def add_coaddcam(self, plots):
        #-----
        #- Highlight individual-arm or camera-coadded spectra
        coaddcam_labels = ["Camera-coadded", "Single-arm"]
        self.coaddcam_buttons = RadioButtonGroup(labels=coaddcam_labels, active=0)
        self.coaddcam_callback = CustomJS(
            args = dict(coaddcam_buttons = self.coaddcam_buttons,
                        list_lines=[plots.data_lines, plots.noise_lines,
                                    plots.zoom_data_lines, plots.zoom_noise_lines],
                        alpha_discrete = plots.alpha_discrete,
                        overlap_bands = plots.overlap_bands,
                        alpha_overlapband = plots.alpha_overlapband),
            code="""
            var n_lines = list_lines[0].length
            for (var i=0; i<n_lines; i++) {
                var new_alpha = 1
                if (coaddcam_buttons.active == 0 && i<n_lines-1) new_alpha = alpha_discrete
                if (coaddcam_buttons.active == 1 && i==n_lines-1) new_alpha = alpha_discrete
                for (var j=0; j<list_lines.length; j++) {
                    list_lines[j][i].glyph.line_alpha = new_alpha
                }
            }
            var new_alpha = 0
            if (coaddcam_buttons.active == 0) new_alpha = alpha_overlapband
            for (var j=0; j<overlap_bands.length; j++) {
                    overlap_bands[j].fill_alpha = new_alpha
            }
            """
        )
        self.coaddcam_buttons.js_on_click(self.coaddcam_callback)
    
    
    def add_metadata_tables(self, viewer_cds, show_zcat=True, template_dicts=None,
                           top_metadata=['TARGETID', 'EXPID']):
        """ Display object-related informations
                top_metadata: metadata to be highlighted in table_a
            
            Note: "short" CDS, with a single row, are used to fill these bokeh tables.
            When changing object, js code modifies these short CDS so that tables are updated.  
        """

        #- Sorted list of potential metadata:
        metadata_to_check = ['TARGETID', 'HPXPIXEL', 'TILEID', 'COADD_NUMEXP', 'COADD_EXPTIME', 
                             'NIGHT', 'EXPID', 'FIBER', 'CAMERA', 'MORPHTYPE']
        metadata_to_check += [ ('mag_'+x) for x in viewer_cds.phot_bands ]
        table_keys = []
        for key in metadata_to_check:
            if key in viewer_cds.cds_metadata.data.keys():
                table_keys.append(key)
            if 'NUM_'+key in viewer_cds.cds_metadata.data.keys():
                for prefix in ['FIRST','LAST','NUM']:
                    table_keys.append(prefix+'_'+key)
                    if key in top_metadata:
                        top_metadata.append(prefix+'_'+key)
        
        #- Table a: "top metadata"
        table_a_keys = [ x for x in table_keys if x in top_metadata ]
        self.shortcds_table_a, self.table_a = _metadata_table(table_a_keys, viewer_cds, table_width=600, 
                                                              shortcds_name='shortcds_table_a', selectable=True)
        #- Table b: Targeting information
        self.shortcds_table_b, self.table_b = _metadata_table(['Targeting masks'], viewer_cds, table_width=self.plot_widget_width,
                                                              shortcds_name='shortcds_table_b', selectable=True)
        #- Table(s) c/d : Other information (imaging, etc.)
        remaining_keys = [ x for x in table_keys if x not in top_metadata ]
        if len(remaining_keys) > 7:
            table_c_keys = remaining_keys[0:len(remaining_keys)//2]
            table_d_keys = remaining_keys[len(remaining_keys)//2:]
        else:
            table_c_keys = remaining_keys
            table_d_keys = None
        self.shortcds_table_c, self.table_c = _metadata_table(table_c_keys, viewer_cds, table_width=self.plot_widget_width,
                                                             shortcds_name='shortcds_table_c', selectable=False)
        if table_d_keys is None:
            self.shortcds_table_d, self.table_d = None, None
        else:
            self.shortcds_table_d, self.table_d = _metadata_table(table_d_keys, viewer_cds, table_width=self.plot_widget_width,
                                                                 shortcds_name='shortcds_table_d', selectable=False)

        #- Table z: redshift fitting information
        if show_zcat is not None :
            if template_dicts is not None : # Add other best fits
                fit_results = template_dicts[1]
                # Case of DeltaChi2 : compute it from Chi2s
                #    The "DeltaChi2" in rr fits is between best fits for a given (spectype,subtype)
                #    Convention: DeltaChi2 = -1 for the last fit.
                chi2s = fit_results['CHI2'][0]
                full_deltachi2s = np.zeros(len(chi2s))-1
                full_deltachi2s[:-1] = chi2s[1:]-chi2s[:-1]
                cdsdata = dict(Nfit = np.arange(1,len(chi2s)+1),
                                SPECTYPE = fit_results['SPECTYPE'][0],  # [0:num_best_fits] (if we want to restrict... TODO?)
                                SUBTYPE = fit_results['SUBTYPE'][0],
                                Z = [ "{:.4f}".format(x) for x in fit_results['Z'][0] ],
                                ZERR = [ "{:.4f}".format(x) for x in fit_results['ZERR'][0] ],
                                ZWARN = fit_results['ZWARN'][0],
                                CHI2 = [ "{:.1f}".format(x) for x in fit_results['CHI2'][0] ],
                                DELTACHI2 = [ "{:.1f}".format(x) for x in full_deltachi2s ])
                self.shortcds_table_z = ColumnDataSource(cdsdata, name='shortcds_table_z')
                columns_table_z = [ TableColumn(field=x, title=t, width=w) for x,t,w in [ ('Nfit','Nfit',5), ('SPECTYPE','SPECTYPE',70), ('SUBTYPE','SUBTYPE',60), ('Z','Z',50) , ('ZERR','ZERR',50), ('ZWARN','ZWARN',50), ('DELTACHI2','Δχ2(N+1/N)',70)] ]
                self.table_z = DataTable(source=self.shortcds_table_z, columns=columns_table_z,
                                         selectable=False, index_position=None, width=self.plot_widget_width)
                self.table_z.height = 3 * self.table_z.row_height
            else :
                self.shortcds_table_z, self.table_z = _metadata_table(viewer_cds.zcat_keys, viewer_cds,
                                    table_width=self.plot_widget_width, shortcds_name='shortcds_table_z', selectable=False)
        else :
            self.table_z = Div(text="Not available ")
            self.shortcds_table_z = None


    def add_specline_toggles(self, viewer_cds, plots):
        #-----
        #- Toggle lines
        self.speclines_button_group = CheckboxButtonGroup(
                labels=["Emission lines", "Absorption lines"], active=[])
        self.majorline_checkbox = CheckboxGroup(
                labels=['Show only major lines'], active=[])

        self.speclines_callback = CustomJS(
            args = dict(line_data = viewer_cds.cds_spectral_lines,
                        lines = plots.speclines,
                        line_labels = plots.specline_labels,
                        zlines = plots.zoom_speclines,
                        zline_labels = plots.zoom_specline_labels,
                        lines_button_group = self.speclines_button_group,
                        majorline_checkbox = self.majorline_checkbox),
            code="""
            var show_emission = false
            var show_absorption = false
            if (lines_button_group.active.indexOf(0) >= 0) {  // index 0=Emission in active list
                show_emission = true
            }
            if (lines_button_group.active.indexOf(1) >= 0) {  // index 1=Absorption in active list
                show_absorption = true
            }

            for(var i=0; i<lines.length; i++) {
                if ( !(line_data.data['major'][i]) && (majorline_checkbox.active.indexOf(0)>=0) ) {
                    lines[i].visible = false
                    line_labels[i].visible = false
                    zlines[i].visible = false
                    zline_labels[i].visible = false
                } else if (line_data.data['emission'][i]) {
                    lines[i].visible = show_emission
                    line_labels[i].visible = show_emission
                    zlines[i].visible = show_emission
                    zline_labels[i].visible = show_emission
                } else {
                    lines[i].visible = show_absorption
                    line_labels[i].visible = show_absorption
                    zlines[i].visible = show_absorption
                    zline_labels[i].visible = show_absorption
                }
            }
            """
        )
        self.speclines_button_group.js_on_click(self.speclines_callback)
        self.majorline_checkbox.js_on_click(self.speclines_callback)


    def add_model_select(self, viewer_cds, template_dicts, num_approx_fits, with_full_2ndfit=True):
        #------
        #- Select secondary model to display
        model_options = ['Best fit', '2nd best fit']
        for i in range(1,1+num_approx_fits) :
            ith = 'th'
            if i==1 : ith='st'
            if i==2 : ith='nd'
            if i==3 : ith='rd'
            model_options.append(str(i)+ith+' fit (approx)')
        if with_full_2ndfit is False :
            model_options.remove('2nd best fit')
        for std_template in ['QSO', 'GALAXY', 'STAR'] :
            model_options.append('STD '+std_template)
        self.model_select = Select(value=model_options[0], title="Other model (dashed curve):", options=model_options)
        model_select_code = self.js_files["interp_grid.js"] + self.js_files["smooth_data.js"] + self.js_files["select_model.js"]
        self.model_select_callback = CustomJS(
            args = dict(ifiberslider = self.ifiberslider,
                        model_select = self.model_select,
                        fit_templates=template_dicts[0],
                        cds_othermodel = viewer_cds.cds_othermodel,
                        cds_model_2ndfit = viewer_cds.cds_model_2ndfit,
                        cds_model = viewer_cds.cds_model,
                        fit_results=template_dicts[1],
                        std_templates=template_dicts[2],
                        median_spectra = viewer_cds.cds_median_spectra,
                        smootherslider = self.smootherslider,
                        z_input = self.z_input,
                        cds_metadata = viewer_cds.cds_metadata),
                        code = model_select_code)
        self.model_select.js_on_change('value', self.model_select_callback)


    def add_update_plot_callback(self, viewer_cds, plots, vi_widgets, template_dicts):
        #-----
        #- Main js code to update plots
        update_plot_code = (self.js_files["adapt_plotrange.js"] + self.js_files["interp_grid.js"] +
                            self.js_files["smooth_data.js"] + self.js_files["coadd_brz_cameras.js"] +
                            self.js_files["update_plot.js"])
        # TMP handling of template_dicts
        the_fit_results = None if template_dicts is None else template_dicts[1] # dirty
        self.update_plot_callback = CustomJS(
            args = dict(
                spectra = viewer_cds.cds_spectra,
                coaddcam_spec = viewer_cds.cds_coaddcam_spec,
                model = viewer_cds.cds_model,
                othermodel = viewer_cds.cds_othermodel,
                model_2ndfit = viewer_cds.cds_model_2ndfit,
                metadata = viewer_cds.cds_metadata,
                fit_results = the_fit_results,
                shortcds_table_z = self.shortcds_table_z,
                shortcds_table_a = self.shortcds_table_a,
                shortcds_table_b = self.shortcds_table_b,
                shortcds_table_c = self.shortcds_table_c,
                shortcds_table_d = self.shortcds_table_d,
                ifiberslider = self.ifiberslider,
                smootherslider = self.smootherslider,
                z_input = self.z_input,
                fig = plots.fig,
                imfig_source = plots.imfig_source,
                imfig_urls = plots.imfig_urls,
                model_select = self.model_select,
                vi_comment_input = vi_widgets.vi_comment_input,
                vi_std_comment_select = vi_widgets.vi_std_comment_select,
                vi_name_input = vi_widgets.vi_name_input,
                vi_quality_input = vi_widgets.vi_quality_input,
                vi_quality_labels = vi_widgets.vi_quality_labels,
                vi_issue_input = vi_widgets.vi_issue_input,
                vi_z_input = vi_widgets.vi_z_input,
                vi_category_select = vi_widgets.vi_category_select,
                vi_issue_slabels = vi_widgets.vi_issue_slabels
                ),
            code = update_plot_code
        )
        self.smootherslider.js_on_change('value', self.update_plot_callback)
        self.ifiberslider.js_on_change('value', self.update_plot_callback)
Exemplo n.º 12
0
def Zancada(DatosBokeh, EjeX, MetricasAuxiliares):
    """
        GRAFICO DISCRETO | LONGITUD DE ZANCADA
    """

    # Creacion del diccionario de metricas auxiliares
    DiccionarioVariables = ParametrosVariables(DatosBokeh)

    # Generacion del codigo JavaScript que habilita la visualizacion de metricas auxiliares
    CodigoJS = GeneracionCodigoJS(MetricasAuxiliares)

    # Asignacion de tamaño del punto en graficas discretas
    SizeCircle = FunctionSizeCircle(DatosBokeh)

    # Creacion de un grafica
    PLT = figure(width=1000,
                 height=400,
                 x_range=(DatosBokeh.data[EjeX].min(),
                          DatosBokeh.data[EjeX].max()),
                 y_range=(LimiteEjeY(DatosBokeh, 'LONGITUD ZANCADA',
                                     'Inferior'),
                          LimiteEjeY(DatosBokeh, 'LONGITUD ZANCADA',
                                     'Superior')),
                 tools='',
                 toolbar_location=None)

    # Inclusion de datos
    PLT.circle(EjeX,
               'LongitudZancada[m]',
               source=DatosBokeh,
               size=SizeCircle,
               line_color=transform(
                   'LongitudZancada[m]',
                   LinearColorMapper(palette=PaletaColoresLinea,
                                     low=0.8,
                                     high=2)),
               color=transform(
                   'LongitudZancada[m]',
                   LinearColorMapper(palette=PaletaColores, low=0.8, high=2)),
               fill_alpha=1)
    PLT_Linea = PLT.line(EjeX,
                         'LongitudZancada[m]',
                         source=DatosBokeh,
                         color='white',
                         line_width=0,
                         line_alpha=0)
    PLT.add_tools(
        HoverTool(tooltips=[('', '@{LongitudZancada[m]}{0,0.00} m')],
                  renderers=[PLT_Linea],
                  mode='vline'))

    # Inclusion de lineas auxiliares
    ListadoMetricasAuxiliares = {}
    for Metrica in MetricasAuxiliares:
        if DiccionarioVariables[Metrica]['Tipo'] == 'circle':
            ListadoMetricasAuxiliares[
                'l' + str(MetricasAuxiliares.index(Metrica))] = PLT.circle(
                    EjeX,
                    DiccionarioVariables[Metrica]['Variable'].split('[', 1)[0]
                    + DiccionarioVariables['LONGITUD ZANCADA']['Sufijo'],
                    source=DiccionarioVariables[Metrica]['CDS'],
                    size=SizeCircle,
                    line_color=DiccionarioVariables[Metrica]['Color'],
                    color=DiccionarioVariables[Metrica]['Color'],
                    **DiccionarioVariables[Metrica]['Propiedades'])
        elif DiccionarioVariables[Metrica]['Tipo'] == 'step':
            ListadoMetricasAuxiliares[
                'l' + str(MetricasAuxiliares.index(Metrica))] = PLT.step(
                    EjeX,
                    DiccionarioVariables[Metrica]['Variable'].split('[', 1)[0]
                    + DiccionarioVariables['LONGITUD ZANCADA']['Sufijo'],
                    source=DiccionarioVariables[Metrica]['CDS'],
                    color=DiccionarioVariables[Metrica]['Color'],
                    **DiccionarioVariables[Metrica]['Propiedades'])
        else:
            ListadoMetricasAuxiliares[
                'l' + str(MetricasAuxiliares.index(Metrica))] = PLT.line(
                    EjeX,
                    DiccionarioVariables[Metrica]['Variable'].split('[', 1)[0]
                    + DiccionarioVariables['LONGITUD ZANCADA']['Sufijo'],
                    source=DiccionarioVariables[Metrica]['CDS'],
                    color=DiccionarioVariables[Metrica]['Color'],
                    **DiccionarioVariables[Metrica]['Propiedades'])

    # Atributos
    PLT.title.text = 'LONGITUD DE ZANCADA'
    PLT.sizing_mode = 'fixed'
    PLT.yaxis.axis_label = 'Longitud de zancada [m]'
    PLT.yaxis.formatter = NumeralTickFormatter(format='0.0')
    PLT.grid.visible = False
    PLT.yaxis.minor_tick_line_color = None

    # Asignacion de opciones de visualizacion del eje X
    if EjeX == 'Distancia[m]':
        PLT.xaxis.axis_label = 'Distancia'
        PLT.xaxis.formatter = NumeralTickFormatter(format='0')
        if DatosBokeh.data['Distancia[m]'].max() >= 4000:
            PLT.xaxis.ticker = SingleIntervalTicker(interval=1000)
            PLT.xaxis.major_label_overrides = FormateoEjes(
                DatosBokeh.data['Distancia[m]'], 1000, 1000, 0, 0)
    elif EjeX == 'TiempoActividad':
        PLT.xaxis.axis_label = 'Tiempo actividad'
        PLT.xaxis.formatter = DatetimeTickFormatter(hourmin='%H:%M:%S',
                                                    minutes='%M:%S',
                                                    seconds='%Ss')
        PLT.xaxis.ticker = DatetimeTicker()
    elif EjeX == 'TiempoTotal':
        PLT.xaxis.axis_label = 'Tiempo total'
        PLT.xaxis.formatter = DatetimeTickFormatter(hourmin='%H:%M:%S',
                                                    minutes='%M:%S',
                                                    seconds='%Ss')
        PLT.xaxis.ticker = DatetimeTicker()

    #Botones
    Botones = CheckboxGroup(labels=MetricasAuxiliares,
                            active=[],
                            width=100,
                            height=380)
    ListadoMetricasAuxiliares['checkbox'] = Botones
    CodigoJSFrecuenciaCardiaca = CustomJS(code=CodigoJS,
                                          args=ListadoMetricasAuxiliares)
    Botones.js_on_click(CodigoJSFrecuenciaCardiaca)

    #Layout
    GridBotones = layout(
        [Spacer(width=100, height=25),
         Column(Botones, width=100, height=375)],
        sizing_mode='fixed',
        width=100,
        height=400)
    GridGrafica = gridplot([PLT, GridBotones],
                           ncols=2,
                           sizing_mode='stretch_width',
                           toolbar_location=None,
                           plot_width=1100,
                           plot_height=400)

    return GridGrafica
Exemplo n.º 13
0
def make_interactive_plot(qr: np.array, pvals, disp_data_full: list,
                          disp_inter_full: list, labels: dict) -> None:
    """ Create the interactive Bokeh plot as a standalone html web page

    :param qr: x-values for the points
    :type qr: np.array
    :param pvals: slider values
    :type pvals: list
    :param disp_data_full: list of arrays containing q vectors and eigenvalues for points
    :type disp_data_full: list
    :param disp_inter_full: list of arrays containing interpolated x and eigen values
    :type disp_inter_full: list
    :param labels: labels for the x-axis indicating special points
    :type labels: dict
    :return: None

    .. todo:: add output file name option
    """

    # Plotting
    from bokeh.plotting import figure, output_file
    from bokeh.io import show, output_notebook, push_notebook
    from bokeh.models import ColumnDataSource, Panel, CustomJS, Circle, Line, Div, HoverTool
    from bokeh.models.widgets import CheckboxGroup, Slider, RangeSlider
    from bokeh.layouts import column, row
    from bokeh.application import Application

    nfiles = len(disp_data_full)
    neigvals = disp_inter_full[0].shape[1] - 1  # first column is x-values

    # Output file name (web page)
    output_file("disp_app.html")

    # Create the figure
    p = figure(title="Dispersion curves for FCC",
               y_range=(0, 2.25),
               x_range=(0, qr[-1] + 0.001),
               x_axis_label="q",
               y_axis_label="ω (THz)",
               plot_width=800)

    # Glyphs for points and lines (intepolation)
    raw_glyphs = []
    inter_glyphs = []

    # Make dictionaries for Bokeh ColumnDataSource
    draw = {"xraw": qr}
    dint = {"xint": disp_inter_full[0][:, 0]}
    for ip in range(nfiles):
        for ie in range(neigvals):
            ei = "e" + str(ip) + "_" + str(ie)
            draw[ei] = disp_data_full[ip][:, ie + 3]
            dint[ei] = disp_inter_full[ip][:, ie + 1]

    srcraw = ColumnDataSource(draw)
    srcint = ColumnDataSource(dint)

    # Build glyphs for each pressure point
    for ip in range(nfiles):
        lalpha = 0
        for ie in range(neigvals):
            ei = "e" + str(ip) + "_" + str(ie)
            if ip == 0: lalpha = 1
            raw_glyphs.append(
                Circle(x="xraw", y=ei, line_alpha=lalpha, fill_alpha=lalpha))
            inter_glyphs.append(Line(x="xint", y=ei, line_alpha=lalpha))
            p.add_glyph(srcraw, raw_glyphs[-1])
            p.add_glyph(srcint, inter_glyphs[-1])

    # Styling
    p.xaxis.ticker = list(labels.keys())  # SPqr
    p.xaxis.major_label_overrides = labels

    # Widgets
    EIGEN_LBLS = ["Eigen " + str(i + 1) for i in range(neigvals)]
    eigen_chkbx_grp = CheckboxGroup(labels=EIGEN_LBLS,
                                    active=[i for i in range(neigvals)])
    slider = Slider(start=1,
                    end=nfiles,
                    value=1,
                    step=1,
                    title="Pressure series")
    #pvals = [''.join(re.findall(regex, f)) for f in onlylogfiles ]
    div = Div(text="Pressure = " + pvals[0] + " bar", name="pval")

    # Callbacks for widgets
    ## Slider Callback
    slider.js_on_change(
        "value",
        CustomJS(args=dict(glp=raw_glyphs,
                           glq=inter_glyphs,
                           neig=neigvals,
                           lbl=div,
                           vals=pvals,
                           chkbx=eigen_chkbx_grp),
                 code="""
        var i;
        var eigs = chkbx.active
        for (i=0; i<glp.length; i=i+1){
            if (i>=(this.value-1)*neig && i < this.value*neig){
                if( eigs.includes(i%neig) ){
                    glp[i]["fill_alpha"] = 1;
                    glp[i]["line_alpha"] = 1;
                    glq[i]["line_alpha"] = 1;
                } else {
                    glp[i]["fill_alpha"] = 0;
                    glp[i]["line_alpha"] = 0;
                    glq[i]["line_alpha"] = 0;
                }
                console.log(i,'YES')
            }else{
                glp[i]["fill_alpha"] = 0;
                glp[i]["line_alpha"] = 0;
                glq[i]["line_alpha"] = 0;
                console.log(i,'NO')
            }
        }
        lbl["text"] = "Pressure = " + vals[this.value-1] + " bar"
    """))

    ## Checkbox callback
    eigen_chkbx_grp.js_on_click(
        CustomJS(args=dict(glp=raw_glyphs,
                           glq=inter_glyphs,
                           neig=neigvals,
                           sldr=slider),
                 code="""
        var actv = this.active
        var i
        console.log("sldr ",sldr.value)
        for (i=(sldr.value-1)*neig; i<sldr.value*neig; i=i+1){
            console.log('i, i%neig res = ', i, i%neig, actv.includes(i%neig))
            if (actv.includes(i%neig)){
                glp[i]["fill_alpha"]=1;
                glp[i]["line_alpha"]=1;
                glq[i]["line_alpha"]=1;
            } else {
                glp[i]["fill_alpha"]=0;
                glp[i]["line_alpha"]=0;
                glq[i]["line_alpha"]=0;
            }
        }
    """))

    ## Add hover widget
    hover = HoverTool(tooltips=[("ω (THz)", "$y")])
    p.add_tools(hover)

    ## Make the layout
    layout = column(eigen_chkbx_grp, p, row(slider, div))

    ## Make the webpage
    show(layout)
def plot_linechart_areas_short_term_migration():
    wb = openpyxl.load_workbook(
        'data/Short term migration.xlsx')  # Import datasets
    ws = wb.get_sheet_by_name('Data')
    x = []
    areas = []
    y1,y2,y3,y4,y5,y6,y7,y8,y9,y10,y11,y12,y13,y14,y15,y16,y17,y18,y19,y20,y21,y22,y23,y24,y25,y26,y27,y28,y29,y30,y31,y32,y33,y34 = [],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]
    #Rearrange data
    for column in range(2, 12):
        areas.append(ws.cell(row=row, column=1).value)
        x.append(ws.cell(row=5, column=column).value)
        y1.append(ws.cell(row=6, column=column).value)
        y2.append(ws.cell(row=7, column=column).value)
        y3.append(ws.cell(row=8, column=column).value)
        y4.append(ws.cell(row=9, column=column).value)
        y5.append(ws.cell(row=10, column=column).value)
        y6.append(ws.cell(row=11, column=column).value)
        y7.append(ws.cell(row=12, column=column).value)
        y8.append(ws.cell(row=13, column=column).value)
        y9.append(ws.cell(row=14, column=column).value)
        y10.append(ws.cell(row=15, column=column).value)
        y11.append(ws.cell(row=16, column=column).value)
        y12.append(ws.cell(row=17, column=column).value)
        y13.append(ws.cell(row=18, column=column).value)
        y14.append(ws.cell(row=19, column=column).value)
        y15.append(ws.cell(row=20, column=column).value)
        y16.append(ws.cell(row=21, column=column).value)
        y17.append(ws.cell(row=22, column=column).value)
        y18.append(ws.cell(row=23, column=column).value)
        y19.append(ws.cell(row=24, column=column).value)
        y20.append(ws.cell(row=25, column=column).value)
        y21.append(ws.cell(row=26, column=column).value)
        y22.append(ws.cell(row=27, column=column).value)
        y23.append(ws.cell(row=28, column=column).value)
        y24.append(ws.cell(row=29, column=column).value)
        y25.append(ws.cell(row=30, column=column).value)
        y26.append(ws.cell(row=31, column=column).value)
        y27.append(ws.cell(row=32, column=column).value)
        y28.append(ws.cell(row=33, column=column).value)
        y29.append(ws.cell(row=34, column=column).value)
        y30.append(ws.cell(row=35, column=column).value)
        y31.append(ws.cell(row=36, column=column).value)
        y32.append(ws.cell(row=37, column=column).value)
        y33.append(ws.cell(row=38, column=column).value)
        y34.append(ws.cell(row=39, column=column).value)

    p_areas = figure(
        plot_width=1000,
        plot_height=500,
        x_axis_label="dates",
        y_axis_label="Migration population",
        y_range=(0, 7000),
        tools="hover,pan,box_zoom,save,reset,undo,zoom_in,zoom_out,wheel_zoom",
        title="Areas of London short-term migration")  #Create a new figure
    p2 = p_areas.line(x=x,
                      y=y2,
                      line_width=1,
                      color="#000003",
                      legend="City of London")  #draw a line chart
    p3 = p_areas.line(x=x,
                      y=y3,
                      line_width=1,
                      color="#140D35",
                      legend="Barking and Dagenham")  #draw a line chart
    p4 = p_areas.line(x=x,
                      y=y4,
                      line_width=1,
                      color="#3B0F6F",
                      legend="Barnet")  #draw a line chart
    p5 = p_areas.line(x=x,
                      y=y5,
                      line_width=1,
                      color="#63197F",
                      legend="Bexley")  #draw a line chart
    p6 = p_areas.line(x=x, y=y6, line_width=1, color="#8C2980",
                      legend="Brent")  #draw a line chart
    p7 = p_areas.line(x=x,
                      y=y7,
                      line_width=1,
                      color="#B53679",
                      legend="Bromley")  #draw a line chart
    p8 = p_areas.line(x=x,
                      y=y8,
                      line_width=1,
                      color="#DD4968",
                      legend="Camden")  #draw a line chart
    p9 = p_areas.line(x=x,
                      y=y9,
                      line_width=1,
                      color="#F66E5B",
                      legend="Croydon")  #draw a line chart
    p10 = p_areas.line(x=x,
                       y=y10,
                       line_width=1,
                       color="#FD9F6C",
                       legend="Ealing")  #draw a line chart
    p11 = p_areas.line(x=x,
                       y=y11,
                       line_width=1,
                       color="#FDCD90",
                       legend="Enfield")  #draw a line chart
    p12 = p_areas.line(x=x,
                       y=y12,
                       line_width=1,
                       color="#FBFCBF",
                       legend="Greenwich")  #draw a line chart
    p13 = p_areas.line(x=x,
                       y=y13,
                       line_width=1,
                       color="#a6cee3",
                       legend="Hackney")  #draw a line chart
    p14 = p_areas.line(x=x,
                       y=y14,
                       line_width=1,
                       color="#1f78b4",
                       legend="Hammersmith and Fulham")  #draw a line chart
    p15 = p_areas.line(x=x,
                       y=y15,
                       line_width=1,
                       color="#b2df8a",
                       legend="Haringey")  #draw a line chart
    p16 = p_areas.line(x=x,
                       y=y16,
                       line_width=1,
                       color="#33a02c",
                       legend="Harrow")  #draw a line chart
    p17 = p_areas.line(x=x,
                       y=y17,
                       line_width=1,
                       color="#fb9a99",
                       legend="Havering")  #draw a line chart
    p18 = p_areas.line(x=x,
                       y=y18,
                       line_width=1,
                       color="#e31a1c",
                       legend="Hillingdon")  #draw a line chart
    p19 = p_areas.line(x=x,
                       y=y19,
                       line_width=1,
                       color="#fdbf6f",
                       legend="Hounslow")  #draw a line chart
    p20 = p_areas.line(x=x,
                       y=y20,
                       line_width=1,
                       color="#ff7f00",
                       legend="Islington")  #draw a line chart
    p21 = p_areas.line(x=x,
                       y=y21,
                       line_width=1,
                       color="#cab2d6",
                       legend="Kensington and Chelsea")  #draw a line chart
    p22 = p_areas.line(x=x,
                       y=y22,
                       line_width=1,
                       color="#6a3d9a",
                       legend="Kingston upon Thames")  #draw a line chart
    p23 = p_areas.line(x=x,
                       y=y23,
                       line_width=1,
                       color="#ffff99",
                       legend="Lambeth")  #draw a line chart
    p24 = p_areas.line(x=x,
                       y=y24,
                       line_width=1,
                       color="#b15928",
                       legend="Lewisham")  #draw a line chart
    p25 = p_areas.line(x=x,
                       y=y25,
                       line_width=1,
                       color="#e41a1c",
                       legend="Merton")  #draw a line chart
    p26 = p_areas.line(x=x,
                       y=y26,
                       line_width=1,
                       color="#377eb8",
                       legend="Newham")  #draw a line chart
    p27 = p_areas.line(x=x,
                       y=y27,
                       line_width=1,
                       color="#4daf4a",
                       legend="Redbridge")  #draw a line chart
    p28 = p_areas.line(x=x,
                       y=y28,
                       line_width=1,
                       color="#984ea3",
                       legend="Richmond upon Thames")  #draw a line chart
    p29 = p_areas.line(x=x,
                       y=y29,
                       line_width=1,
                       color="#ff7f00",
                       legend="Southwark")  #draw a line chart
    p30 = p_areas.line(x=x,
                       y=y30,
                       line_width=1,
                       color="#ffff33",
                       legend="Sutton")  #draw a line chart
    p31 = p_areas.line(x=x,
                       y=y31,
                       line_width=1,
                       color="#a65628",
                       legend="Tower Hamlets")  #draw a line chart
    p32 = p_areas.line(x=x,
                       y=y32,
                       line_width=1,
                       color="#f781bf",
                       legend="Waltham Forest")  #draw a line chart
    p33 = p_areas.line(x=x,
                       y=y33,
                       line_width=1,
                       color="#410967",
                       legend="Wandsworth")  #draw a line chart
    p34 = p_areas.line(x=x,
                       y=y34,
                       line_width=1,
                       color="#6A176E",
                       legend="Westminster")  #draw a line chart

    #Set legend location adn legemd orientation
    p_areas.legend.location = "top_left"
    p_areas.legend.orientation = "horizontal"
    #Set callback function after click checkboxes
    display_event = CustomJS(code="""
                            p2.visible = false; 
                            p3.visible = false; 
                            p4.visible = false;
                            p5.visible = false;
                            p6.visible = false;
                            p7.visible = false;
                            p8.visible = false;
                            p9.visible = false;
                            p10.visible = false;
                            p11.visible = false;
                            p12.visible = false;
                            p13.visible = false;
                            p14.visible = false;
                            p15.visible = false;
                            p16.visible = false;
                            p17.visible = false;
                            p18.visible = false;
                            p19.visible = false;
                            p20.visible = false;
                            p21.visible = false;
                            p22.visible = false;
                            p23.visible = false;
                            p24.visible = false;
                            p25.visible = false;
                            p26.visible = false;
                            p27.visible = false;
                            p28.visible = false;
                            p29.visible = false;
                            p30.visible = false;
                            p31.visible = false;
                            p32.visible = false;
                            p33.visible = false;
                            p34.visible = false;

                            if(cb_obj.active.includes(0)){
                                p2.visible = true;
                            }
                            if (cb_obj.active.includes(1)){
                                p3.visible = true;
                            } 
                            if (cb_obj.active.includes(2)){
                                p4.visible = true;
                            } 
                            if (cb_obj.active.includes(3)){
                                p5.visible = true;
                            }
                            if (cb_obj.active.includes(4)){
                                p6.visible = true;
                            } 
                             if (cb_obj.active.includes(5)){
                                p7.visible = true;
                            } 
                            if (cb_obj.active.includes(6)){
                                p8.visible = true;
                            } 
                            if (cb_obj.active.includes(7)){
                                p9.visible = true;
                            } 
                            if (cb_obj.active.includes(8)){
                                p10.visible = true;   
                            } 
                            if (cb_obj.active.includes(9)){
                                p11.visible = true;
                            } 
                            if (cb_obj.active.includes(10)){
                                p12.visible = true;   
                            }
                            if (cb_obj.active.includes(11)){
                                p13.visible = true;   
                            }
                            if (cb_obj.active.includes(12)){
                                p14.visible = true;   
                            }
                            if (cb_obj.active.includes(13)){
                                p15.visible = true;   
                            }
                            if (cb_obj.active.includes(14)){
                                p16.visible = true;   
                            }
                            if (cb_obj.active.includes(15)){
                                p17.visible = true;   
                            }
                            if (cb_obj.active.includes(16)){
                                p18.visible = true;   
                            }
                            if (cb_obj.active.includes(17)){
                                p19.visible = true;   
                            }
                            if (cb_obj.active.includes(18)){
                                p20.visible = true;   
                            }  
                            if (cb_obj.active.includes(19)){
                                p21.visible = true;   
                            }
                            if (cb_obj.active.includes(20)){
                                p22.visible = true;   
                            }
                            if (cb_obj.active.includes(21)){
                                p23.visible = true;   
                            }
                            if (cb_obj.active.includes(22)){
                                p24.visible = true;   
                            }
                            if (cb_obj.active.includes(23)){
                                p25.visible = true;   
                            }
                            if (cb_obj.active.includes(24)){
                                p26.visible = true;   
                            }
                            if (cb_obj.active.includes(25)){
                                p27.visible = true;   
                            }
                            if (cb_obj.active.includes(26)){
                                p28.visible = true;   
                            }
                            if (cb_obj.active.includes(27)){
                                p29.visible = true;   
                            }
                            if (cb_obj.active.includes(28)){
                                p30.visible = true;   
                            }
                            if (cb_obj.active.includes(29)){
                                p31.visible = true;   
                            }
                            if (cb_obj.active.includes(30)){
                                p32.visible = true;   
                            }
                            if (cb_obj.active.includes(31)){
                                p33.visible = true;   
                            }
                            if (cb_obj.active.includes(32)){
                                p34.visible = true;   
                            }
                            """,
                             args={
                                 'p2': p2,
                                 'p3': p3,
                                 'p4': p4,
                                 'p5': p5,
                                 'p6': p6,
                                 'p7': p7,
                                 'p8': p8,
                                 'p9': p9,
                                 'p10': p10,
                                 'p11': p11,
                                 'p12': p12,
                                 'p13': p13,
                                 'p14': p14,
                                 'p15': p15,
                                 'p16': p16,
                                 'p17': p17,
                                 'p18': p18,
                                 'p19': p19,
                                 'p20': p20,
                                 'p21': p21,
                                 'p22': p22,
                                 'p23': p23,
                                 'p24': p24,
                                 'p25': p25,
                                 'p26': p26,
                                 'p27': p27,
                                 'p28': p28,
                                 'p29': p29,
                                 'p30': p30,
                                 'p31': p31,
                                 'p32': p32,
                                 'p33': p33,
                                 'p34': p34
                             })
    #Set widgets checkboxes
    selection_box = CheckboxGroup(labels=[
        "City of London", "Barking and Dagenham", "Barnet", "Bexley", "Brent",
        "Bromley", "Camden", "Croydon", "Ealing", "Enfield", "Greenwich",
        "Hackney", "Hammersmith and Fulham", "Haringey", "Harrow", "Havering",
        "Hillingdon", "Hounslow", "Islington", "Kensington and Chelsea",
        "Kingston upon Thames", "Lambeth", "Lewisham", "Merton", "Newham",
        "Redbridge", "Richmond upon Thames", "Southwark", "Sutton",
        "Tower Hamlets", "Waltham Forest", "Wandsworth", "Westminster"
    ],
                                  active=[
                                      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
                                      13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
                                      23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
                                      33
                                  ])

    selection_box.js_on_click(display_event)
    row_1 = [p_areas,
             selection_box]  #Make selection boxes located besides line chart
    return row_1