def createButtons(self, figNames):
     buttons = CheckboxButtonGroup(labels=[name for name in figNames],
                                   active=[0, 1, 2])
     buttons.on_click(self.buttonClick)
     for count, name in enumerate(figNames):
         self.buttonToFig[count] = self.figs[name]
     return buttons
Beispiel #2
0
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=
        "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.on_click(
    lambda value: print('radio_button_group: %s' % value))
radio_button_group.js_on_click(
    CustomJS(
        code=
        "console.log('radio_button_group: ' + this.active, this.toString())"))
                    ] * tmp_df.shape[0])
        sources_year_vs_usd[state].data = data


def filter_categories(indexes):
    if len(indexes):
        selected_categories = [categories[ind] for ind in indexes]
    else:
        selected_categories = categories
    update_source(selected_categories)


update_source(categories)

select = CheckboxButtonGroup(labels=categories)
select.on_click(filter_categories)

hover_year_with_usd = HoverTool(tooltips=[
    ("name", "@name"),
])

p_year_with_usd = figure(plot_height=200,
                         tools=[hover_year_with_usd, "box_select", "reset"])

for state, color in zip(states, colors):
    p_year_with_usd.circle(x='x',
                           y='y',
                           line_color='white',
                           fill_color=color,
                           alpha=0.7,
                           size=15,
split = Dropdown(label="Split button",
                 type="danger",
                 menu=menu,
                 default_value="baz")
split.on_click(split_handler)

checkbox_group = CheckboxGroup(labels=["Option 1", "Option 2", "Option 3"],
                               active=[0, 1])
checkbox_group.on_click(checkbox_group_handler)

radio_group = RadioGroup(labels=["Option 1", "Option 2", "Option 3"], active=0)
radio_group.on_click(radio_group_handler)

checkbox_button_group = CheckboxButtonGroup(
    labels=["Option 1", "Option 2", "Option 3"], active=[0, 1])
checkbox_button_group.on_click(checkbox_button_group_handler)

radio_button_group = RadioButtonGroup(
    labels=["Option 1", "Option 2", "Option 3"], active=0)
radio_button_group.on_click(radio_button_group_handler)

vbox = VBox(children=[
    button, toggle, dropdown, split, checkbox_group, radio_group,
    checkbox_button_group, radio_button_group
])

document = Document()
document.add_root(vbox)
session = push_session(document)
session.show()
Beispiel #5
0
menu = [("Item 1", "item_1"), ("Item 2", "item_2"), None, ("Item 3", "item_3")]
dropdown = Dropdown(label="Dropdown button", type="warning", menu=menu)
dropdown.on_click(dropdown_handler)

menu = [("Item 1", "foo"), ("Item 2", "bar"), None, ("Item 3", "baz")]
split = Dropdown(label="Split button", type="danger", menu=menu, default_action="baz")
split.on_click(split_handler)

checkbox_group = CheckboxGroup(labels=["Option 1", "Option 2", "Option 3"], active=[0, 1])
checkbox_group.on_click(checkbox_group_handler)

radio_group = RadioGroup(labels=["Option 1", "Option 2", "Option 3"], active=0)
radio_group.on_click(radio_group_handler)

checkbox_button_group = CheckboxButtonGroup(labels=["Option 1", "Option 2", "Option 3"], active=[0, 1])
checkbox_button_group.on_click(checkbox_button_group_handler)

radio_button_group = RadioButtonGroup(labels=["Option 1", "Option 2", "Option 3"], active=0)
radio_button_group.on_click(radio_button_group_handler)

vbox = VBox(children=[button, toggle, dropdown, split, checkbox_group, radio_group, checkbox_button_group, radio_button_group])

document.add(vbox)
session.store_document(document)

if __name__ == "__main__":
    link = session.object_link(document.context)
    print("Please visit %s to see the plots" % link)
    view(link)
    print("\npress ctrl-C to exit")
    session.poll_document(document)
Beispiel #6
0
    def do_layout(self):
        """
        generates the overall layout by creating all the widgets, buttons etc and arranges
        them in rows and columns
        :return: None
        """
        self.source = self.generate_source()
        tab_plot = self.generate_plot(self.source)
        multi_select = MultiSelect(title="Option (Multiselect Ctrl+Click):",
                                   value=self.active_country_list,
                                   options=countries,
                                   height=500)
        multi_select.on_change('value', self.update_data)
        tab_plot.on_change('active', self.update_tab)
        radio_button_group_per_capita = RadioButtonGroup(
            labels=["Total Cases", "Cases per Million"],
            active=0 if not self.active_per_capita else 1)
        radio_button_group_per_capita.on_click(self.update_capita)
        radio_button_group_scale = RadioButtonGroup(
            labels=[Scale.log.name.title(),
                    Scale.linear.name.title()],
            active=self.active_y_axis_type.value)
        radio_button_group_scale.on_click(self.update_scale_button)
        radio_button_group_df = RadioButtonGroup(labels=[
            Prefix.confirmed.name.title(),
            Prefix.deaths.name.title(),
            Prefix.recovered.name.title(),
        ],
                                                 active=int(
                                                     self.active_case_type))
        radio_button_group_df.on_click(self.update_data_frame)
        refresh_button = Button(label="Refresh Data",
                                button_type="default",
                                width=150)
        refresh_button.on_click(load_data_frames)
        export_button = Button(label="Export Url",
                               button_type="default",
                               width=150)
        export_button.on_click(self.export_url)
        slider = Slider(start=1,
                        end=30,
                        value=self.active_window_size,
                        step=1,
                        title="Window Size for rolling average")
        slider.on_change('value', self.update_window_size)
        radio_button_average = RadioButtonGroup(
            labels=[Average.mean.name.title(),
                    Average.median.name.title()],
            active=self.active_average)
        radio_button_average.on_click(self.update_average_button)
        plot_variables = [
            self.active_plot_raw, self.active_plot_average,
            self.active_plot_trend
        ]
        plots_button_group = CheckboxButtonGroup(
            labels=["Raw", "Averaged", "Trend"],
            active=[i for i, x in enumerate(plot_variables) if x])
        plots_button_group.on_click(self.update_shown_plots)

        world_map = self.create_world_map()
        link_div = Div(
            name="URL",
            text=
            fr'Link <a target="_blank" href="{self.url}">Link to this Plot</a>.',
            width=300,
            height=10,
            align='center')
        footer = Div(
            text=
            """Covid-19 Dashboard created by Andreas Weichslgartner in April 2020 with python, bokeh, pandas, 
            numpy, pyproj, and colorcet. Source Code can be found at 
            <a href="https://github.com/weichslgartner/covid_dashboard/">Github</a>.""",
            width=1600,
            height=10,
            align='center')
        self.generate_table_cumulative()
        columns = [
            TableColumn(field="name", title="Country"),
            TableColumn(field="number_rolling",
                        title="daily avg",
                        formatter=NumberFormatter(format="0.")),
            TableColumn(field="number_daily",
                        title="daily raw",
                        formatter=NumberFormatter(format="0."))
        ]
        top_top_14_new_header = Div(text="Highest confirmed (daily)",
                                    align='center')
        top_top_14_new = DataTable(source=self.top_new_source,
                                   name="Highest confirmed(daily)",
                                   columns=columns,
                                   width=300,
                                   height=380)
        self.generate_table_new()
        columns = [
            TableColumn(field="name", title="Country"),
            TableColumn(field="number",
                        title="confirmed(cumulative)",
                        formatter=NumberFormatter(format="0."))
        ]

        top_top_14_cum_header = Div(text="Highest confirmed (cumulative)",
                                    align='center')
        top_top_14_cum = DataTable(source=self.top_total_source,
                                   name="Highest confirmed(cumulative)",
                                   columns=columns,
                                   width=300,
                                   height=380)
        self.layout = layout([
            row(
                column(tab_plot, world_map),
                column(top_top_14_new_header, top_top_14_new,
                       top_top_14_cum_header, top_top_14_cum),
                column(link_div, row(refresh_button, export_button),
                       radio_button_group_df, radio_button_group_per_capita,
                       plots_button_group, radio_button_group_scale, slider,
                       radio_button_average, multi_select),
            ),
            row(footer)
        ])

        curdoc().add_root(self.layout)
        curdoc().title = "Bokeh Covid-19 Dashboard"
Beispiel #7
0
p.triangle('x',
           'y',
           source=chap_1930_geosource,
           color="orange",
           size=4,
           legend="1930s Chaparral")

# p.circle('x','y', source = shrub_1990_geosource,
# color = 'black', size=4,legend="1990s shrubland")

p.square('x',
         'y',
         source=landfire_geosource,
         color='brown',
         size=4,
         legend="2010s Chaparral")

p.multi_line('xs', 'ys', source=ca_geosource, color="black")

# Add the CheckBox group
Check_Box = CheckboxButtonGroup(labels=checkbox_labels, active=[])
Check_Box.on_click(checkbox_handler)

# Position the color bars
p.add_layout(alt_color_bar, 'right')
p.add_layout(dMAT_color_bar, 'right')

layout = column(Check_Box, p)
curdoc().add_root(layout)
Beispiel #8
0
def modify_second_descriptive(doc):
    # Captura de los argumentos pasados desde flask
    args = doc.session_context.request.arguments
    try:
        periodo = int(args.get('periodo')[0])
        tipo_var = args.get('tipo_var')[0].decode('ascii')
        periodo_custom_start = args.get('periodo_custom_start')[0].decode(
            'ascii')
        periodo_custom_end = args.get('periodo_custom_end')[0].decode('ascii')
        current_date = dt.strptime(
            args.get('current_date')[0].decode('ascii'), '%d/%m/%Y')
    except:
        periodo = 0
        tipo_var = ''
        periodo_custom_start = ''
        periodo_custom_end = ''
        current_date = ''
    if tipo_var == 'abs':
        tipo_var = 'ABSOLUTAS'
    elif tipo_var == 'rend':
        tipo_var = 'RENDIMIENTOS'
    print(
        f'periodo: {periodo}, tipo_var: {tipo_var}, periodo_custom_start: {periodo_custom_start}, periodo_custom_end: {periodo_custom_end}, current_date: {current_date}'
    )

    # Creación/Carga en RAM del diccionario con las variables a modelizar
    total_model_dict = load_or_create_model_vars(
        model_vars_file='resources/total_model_dict.pkl',
        mask_file='resources/model_variables_mask.xlsx',
        sheets=[
            'ID_INFLUENTE', 'ID_BIOS', 'ID_FANGOS', 'ID_HORNO', 'ID_EFLUENTE',
            'ID_ELECTRICIDAD', 'YOKO', 'ANALITICA', 'METEO'
        ],
        cols=['OUT', 'IN', 'MANIPULABLES', 'PROCESOS_IN'],
        force_create=False)

    # Inicialización del diccionario ordenado para almacenar los modelos creados
    models = OrderedDict([])
    try:
        created_models = load_obj(name='resources/created_models.pkl')
    except:
        created_models = ['Calidad_Agua']

    ruta_periodo = f'{SERVER_HOST}/archivos/EDAR4.0_EDAR_Cartuja_ID_PERIOD_{periodo}.csv'
    # Crear nuevo archivo custom si periodo=3
    if periodo == 3:
        create_custom_period(periodo_custom_start, periodo_custom_end)
        ruta_periodo = F'{SERVER_HOST}/archivos/EDAR4.0_EDAR_Cartuja_ID_PERIOD_CUSTOM.csv'
        current_date = dt.strptime(periodo_custom_end, '%d/%m/%Y')

    # Llamada al webservice de RapidMiner
    json_perfil_document = call_webservice(
        url=
        'http://rapidminer.vicomtech.org/api/rest/process/EDAR_Cartuja_Perfil_Out_JSON_v5?',
        username='******',
        password='******',
        parameters={
            'Ruta_periodo': ruta_periodo,
            'Ruta_tipo_variable':
            f'{SERVER_HOST}/archivos/EDAR4.0_EDAR_Cartuja_VARIABLES_{tipo_var}.csv',
            'Normalizacion': 1
        },
        out_json=True)

    # Extracción de los datos web
    df_perfil = [json_normalize(data) for data in json_perfil_document]

    # Asignación de los datos web a su variable correspondiente
    prediction_df = df_perfil[3]
    outlier_df = df_perfil[4]

    # Creación de los gráficos y widgets permanentes en la interfaz
    prediction_plot = create_prediction_plot(prediction_df, current_date)
    outlier_plot = create_outlier_plot(outlier_df, prediction_df, tipo_var)
    simulation_title = create_div_title(
        'Creación, Simulación y Optimización de modelos')
    model_title, add_model_button, model_select_menu = create_model_menu(
        model_variables=list(total_model_dict.keys()))
    create_model_spinner = Spinner(size=16)
    recreate_button = Button(label='Recrear',
                             button_type='success',
                             height=35,
                             max_width=200,
                             min_width=200)
    model_select_wb = widgetbox([
        row([model_title, create_model_spinner.spinner],
            sizing_mode='stretch_width',
            max_width=400),
        row([model_select_menu, recreate_button],
            sizing_mode='stretch_width',
            max_width=400), add_model_button
    ],
                                max_width=400,
                                sizing_mode='stretch_width')
    created_models_title = create_div_title('Modelos creados')
    created_models_checkbox = CheckboxButtonGroup(labels=list(models.keys()),
                                                  height=35)
    created_models_checkbox.active = [0]
    delete_model_button = Button(label='Eliminar',
                                 button_type='danger',
                                 height=35,
                                 max_width=200)
    created_models_wb = widgetbox(
        [created_models_title, created_models_checkbox],
        max_width=900,
        sizing_mode='stretch_width')

    # Callback para crear nuevamente el listado de variables de la mascara
    def recreate_callback():
        print('Recreando lista de variables para modelizar')
        nonlocal total_model_dict
        total_model_dict = load_or_create_model_vars(
            model_vars_file='resources/total_model_dict.pkl',
            mask_file='resources/model_variables_mask.xlsx',
            sheets=[
                'ID_INFLUENTE', 'ID_BIOS', 'ID_FANGOS', 'ID_HORNO',
                'ID_EFLUENTE', 'ID_ELECTRICIDAD', 'YOKO', 'ANALITICA', 'METEO'
            ],
            cols=['OUT', 'IN', 'MANIPULABLES', 'PROCESOS_IN'],
            force_create=True)
        model_select_menu.options = list(total_model_dict.keys())
        model_select_menu.value = 'Calidad_Agua'

    recreate_button.on_click(recreate_callback)

    # Callbacks para los widgets de la interfaz
    def prediction_callback(model='Calidad_Agua'):
        create_model_spinner.show_spinner()
        if initialize == False:
            model_objective = model_select_menu.value
        else:
            model_objective = model
        model_discretise = 5

        # Verificar que el modelo no ha sido creado antes
        if model_objective not in models:
            # print(f'Objetivo: {model_objective}')
            # print(f'Discretizacion: {model_discretise}')
            # print(f'Ruta_periodo: /home/admin/Cartuja_Datos/EDAR4.0_EDAR_Cartuja_ID_PERIOD_{periodo}.csv')
            # print(f'IN_MODELO: {total_model_dict[model_objective]}')
            # Llamar al servicio web EDAR_Cartuja_Prediccion con los nuevos parámetros
            ruta_periodo = f'https://edar.vicomtech.org/archivos/EDAR4.0_EDAR_Cartuja_ID_PERIOD_{periodo}.csv'
            # Crear nuevo archivo custom si periodo=3
            if periodo == 3:
                create_custom_period(periodo_custom_start, periodo_custom_end)
                ruta_periodo = 'https://edar.vicomtech.org/archivos/EDAR4.0_EDAR_Cartuja_ID_PERIOD_CUSTOM.csv'
            json_prediction_document = call_webservice(
                url=
                'http://rapidminer.vicomtech.org/api/rest/process/EDAR_Cartuja_Prediccion_JSON_v5?',
                username='******',
                password='******',
                parameters={
                    'Objetivo': model_objective,
                    'Discretizacion': model_discretise,
                    'Numero_Atributos': 4,
                    'Ruta_periodo': ruta_periodo,
                    'IN_MODELO': str(total_model_dict[model_objective])
                },
                out_json=True)

            # Obtener datos
            df_prediction = [
                json_normalize(data) for data in json_prediction_document
            ]

            decision_tree_df = df_prediction[0]
            decision_tree_df = append_count(decision_tree_df)
            confusion_df_raw = df_prediction[1].reindex(
                columns=list(json_prediction_document[1][0].keys()))
            confusion_df = create_df_confusion(confusion_df_raw)
            weight_df = df_prediction[2]
            pred_df = df_prediction[3]
            ranges_df = df_prediction[4]
            ranges_df.set_index('Name', inplace=True)
            # ranges_df['Values']=ranges_df['Values'].replace(regex=r'\(.*\)',value='')
            slider_df = create_df_sliders(weight_df, pred_df)
            daily_pred_df = pred_df[[
                'Fecha', model_objective, f'prediction({model_objective})'
            ]]
            possible_targets = sorted(list(pred_df[model_objective].unique()))
            # print(f'Targets: {possible_targets}')
            var_influyentes = list(weight_df['Attribute'])
            decision_tree_data = create_decision_tree_data(
                decision_tree_df, model_objective)

            # Crear nuevos gráficos
            simul_or_optim_wb = SimulOptimWidget(
                target=model_objective,
                simul_df=slider_df,
                possible_targets=possible_targets,
                var_influyentes=var_influyentes,
                periodo=periodo,
                ranges=ranges_df,
                periodo_custom_start=periodo_custom_start,
                periodo_custom_end=periodo_custom_end)
            daily_pred_plot = create_daily_pred_plot(daily_pred_df,
                                                     model_objective)
            decision_tree_plot = create_decision_tree_plot()
            decision_tree_graph = create_decision_tree_graph_renderer(
                decision_tree_plot, decision_tree_data)
            decision_tree_plot = append_labels_to_decision_tree(
                decision_tree_plot, decision_tree_graph, decision_tree_data)
            confusion_matrix = create_confusion_matrix(confusion_df)
            weight_plot = create_attribute_weight_plot(weight_df,
                                                       model_objective)
            corrects_plot = create_corrects_plot(confusion_df, model_objective)
            model_title = create_div_title(f'Modelo - {model_objective}')
            confusion_title = create_div_title(
                f'Matriz de confusión - {model_objective}')
            decision_tree_title = create_div_title(
                f'Arbol de decisión - {model_objective}')
            ranges_description = create_ranges_description(
                possible_targets, model_objective)
            new_plots = layout(
                [[model_title], [simul_or_optim_wb.rb],
                 [
                     row([simul_or_optim_wb.wb, ranges_description],
                         min_width=1400,
                         sizing_mode='stretch_width')
                 ], [daily_pred_plot],
                 [
                     column([confusion_title, confusion_matrix],
                            sizing_mode='stretch_width'), weight_plot,
                     corrects_plot
                 ], [decision_tree_title], [decision_tree_plot]],
                name=model_objective,
                sizing_mode='stretch_width')

            # Almacenar en RAM y algunos gráficos y en ROM algunos modelos creados
            model_plots.children.append(new_plots)
            if model_objective not in created_models:
                created_models.append(model_objective)
            save_obj(created_models, 'resources/created_models.pkl')
            models.update({model_objective: new_plots})
            models.move_to_end(model_objective, last=False)
            created_models_checkbox.labels = list(models.keys())
            created_models_checkbox.active = list(range(len(models.keys())))
        create_model_spinner.hide_spinner()

    add_model_button.on_click(prediction_callback)

    # Callback para eliminar algunos modelos seleccionados
    def remove_model_handler(new):
        selected_labels = [
            created_models_checkbox.labels[elements]
            for elements in created_models_checkbox.active
        ]
        try:
            for element in selected_labels:
                models.pop(element)
                model_plots.children.remove(doc.get_model_by_name(element))
                created_models.remove(element)
            save_obj(created_models, 'resources/created_models.pkl')
        except:
            for element in selected_labels:
                print(f"El modelo {element} no existe")
        created_models_checkbox.labels = list(models.keys())
        created_models_checkbox.active = list(range(len(models.keys())))

    delete_model_button.on_click(remove_model_handler)

    # Callback para mostrar u ocultar los gráficos de los modelos creados
    def show_hide_plots(new):
        selected_labels = [
            created_models_checkbox.labels[elements] for elements in new
        ]
        children = []
        for element in selected_labels:
            children.append(models[element])
        model_plots.children = children

    created_models_checkbox.on_click(show_hide_plots)

    # Creación del layout inicial de la interfaz
    model_plots = column([])
    initialize = True
    for model in created_models:
        prediction_callback(model=model)
    initialize = False
    # Creación del layout estático de la interfaz
    l = layout([[prediction_plot], [outlier_plot], [simulation_title],
                [
                    model_select_wb,
                    column(created_models_wb,
                           delete_model_button,
                           sizing_mode='stretch_width')
                ], [model_plots]],
               sizing_mode='stretch_both')

    doc.add_root(l)
class BenchmarkApp(HBox):
    """An example of a browser-based, interactive plot with slider controls."""

    extra_generated_classes = [["BenchmarkApp", "BenchmarkApp", "HBox"]]

    inputs = Instance(VBoxForm)

    # widgets
    benchmarks = Instance(Select)
    x_axis_options = Instance(Select)
    y_axis_options = Instance(Select)
    # TODO: Convert this to a MultiSelect once it is fixed
    # https://github.com/bokeh/bokeh/issues/2495
    device_names = Instance(CheckboxGroup)
    platform_names = Instance(CheckboxButtonGroup)
    # data displays, not enabled by default
    data_display0 = Instance(DataTable)
    data_display1 = Instance(DataTable)

    # plot and interaction
    plot = Instance(Plot)
    hover = Instance(HoverTool)
    # data
    source0 = Instance(ColumnDataSource)
    source1 = Instance(ColumnDataSource)
    source2 = Instance(ColumnDataSource)
    source3 = Instance(ColumnDataSource)
    source4 = Instance(ColumnDataSource)
    source5 = Instance(ColumnDataSource)
    source6 = Instance(ColumnDataSource)
    source7 = Instance(ColumnDataSource)
    source8 = Instance(ColumnDataSource)
    source9 = Instance(ColumnDataSource)

    def make_source(self):
        # set up the data source
        self.source0 = ColumnDataSource(data=dict())
        self.source1 = ColumnDataSource(data=dict())
        self.source2 = ColumnDataSource(data=dict())
        self.source3 = ColumnDataSource(data=dict())
        self.source4 = ColumnDataSource(data=dict())
        self.source5 = ColumnDataSource(data=dict())
        self.source6 = ColumnDataSource(data=dict())
        self.source7 = ColumnDataSource(data=dict())
        self.source8 = ColumnDataSource(data=dict())
        self.source9 = ColumnDataSource(data=dict())

    def make_inputs(self):
        columns = [
            TableColumn(field='x', title='x'),
            TableColumn(field='y', title='y'),
            TableColumn(field='device', title='device'),
            TableColumn(field='platform', title='platform')
        ]

#        obj.data_display0 = DataTable(source=obj.source2, columns=columns)
#        obj.data_display1 = DataTable(source=obj.source3, columns=columns)

        # setup user input
        self.x_axis_options = Select(title="X:", value='size', options=axis_options)
        self.y_axis_options = Select(title="Y:", value='throughput [1/sec]', options=axis_options)
        self.benchmarks = Select(title="Benchmark:", value=benchmark_names[0],
            options=benchmark_names)
        self.device_names = CheckboxGroup(labels=device_names, active=[0])
        self.platform_names = CheckboxButtonGroup(labels=platform_names, active=[0])

    @classmethod
    def create(cls):
        """One-time creation of app's objects.

        This function is called once, and is responsible for
        creating all objects (plots, datasources, etc)
        """
        obj = cls()

        obj.make_source()
        obj.make_inputs()
        obj.make_plot()
        obj.update_data()
        obj.set_children()

        return obj

    def plot_data(self, source, linecolor, symbolfill):
        self.plot.line(   'x', 'y', source=source, line_color=linecolor,
            line_width=3, line_alpha=0.6)
        self.plot.scatter('x', 'y', source=source, fill_color=symbolfill, size=8)

    def make_plot(self):

        # configure the toolset
        toolset = ['wheel_zoom,save,box_zoom,resize,reset']
        self.hover = BenchmarkApp.make_hovertool()
        toolset.append(self.hover)

        title = self.benchmarks.value + " " + \
            "(" + self.y_axis_options.value + " vs." + self.x_axis_options.value + ")"

        self.plot = figure(title_text_font_size="12pt",
            plot_height=400,
            plot_width=400,
            tools=toolset,
            title=title,
        )
        # remove the logo
        self.plot.logo = None

        # Generate a figure container
        # Plot the line by the x,y values in the source property
        self.plot_data(self.source0, "#F0A3FF", "white")
        self.plot_data(self.source1, "#0075DC", "white")
        self.plot_data(self.source2, "#993F00", "white")
        self.plot_data(self.source3, "#4C005C", "white")
        self.plot_data(self.source4, "#191919", "white")
        self.plot_data(self.source5, "#005C31", "white")
        self.plot_data(self.source6, "#2BCE48", "white")
        self.plot_data(self.source7, "#FFCC99", "white")
        self.plot_data(self.source8, "#808080", "white")
        self.plot_data(self.source9, "#94FFB5", "white")

        # set the x/y axis labels
#        plot.xaxis.axis_label = self.x_axis_options.value
#        plot.yaxis.axis_label = self.y_axis_options.value



    def set_children(self):
        self.inputs = VBoxForm(
            children=[self.benchmarks, self.device_names, self.platform_names,
                self.x_axis_options, self.y_axis_options,
#                self.data_display0, self.data_display1
            ]
        )

        self.children.append(self.inputs)
        self.children.append(self.plot)


    @classmethod
    def make_hovertool(self):
        hover = HoverTool(
            tooltips = [
                ("Device", "@device"),
                ("Backend", "@platform"),
                ("(x,y)", "(@x,@y)")
            ]
        )
        return hover

    def setup_events(self):
        """Attaches the on_change event to the value property of the widget.

        The callback is set to the input_change method of this app.
        """
        super(BenchmarkApp, self).setup_events()
        if not self.benchmarks:
            return

        # Event registration for everything except checkboxes
        self.benchmarks.on_change('value', self, 'benchmark_changed')
        self.x_axis_options.on_change('value', self, 'input_change')
        self.y_axis_options.on_change('value', self, 'input_change')

        # Event registration for checkboxes
        self.device_names.on_click(self.checkbox_handler)
        self.platform_names.on_click(self.checkbox_handler)

    def checkbox_handler(self, active):

        self.update_data()

    def benchmark_changed(self, obj, attrname, old, new):

        self.update_data()
        self.make_plot()
        curdoc().add(self)

    def input_change(self, obj, attrname, old, new):
        """Executes whenever the input form changes.

        It is responsible for updating the plot, or anything else you want.

        Args:
            obj : the object that changed
            attrname : the attr that changed
            old : old value of attr
            new : new value of attr
        """
        self.update_data()
        self.make_plot()
        curdoc().add(self)


    def getXY(self, celero_result, axis_filter):
        """Returns the X or Y value as specified by axis_filter"""

        # TODO: Remove the baseline measurement from the timing results
        if axis_filter == 'size':
            return celero_result['data_sizes']
        elif axis_filter == 'log2(size)':
            return np.log2(celero_result['data_sizes'])
        elif axis_filter == 'log10(size)':
            return np.log10(celero_result['data_sizes'])
        elif axis_filter == 'time [ms]':
            return celero_result['times'] * 1E-3
        elif axis_filter == 'throughput [1/sec]':
            return 1.0 / (celero_result['times'] * 1E-6)
        elif axis_filter == 'throughput [log2(1/sec)]':
            return np.log2(1.0 / (celero_result['times'] * 1E-6))
        elif axis_filter == 'throughput [log10(1/sec)]':
            return np.log10(1.0 / (celero_result['times'] * 1E-6))


    @classmethod
    def make_field_ids(self, id_number):
        """Creates a unique set of named fields for the y, device, and platform"""
        i = str(id_number)
        y_id = 'y' + i
        device_id = 'device' + i
        platform_id = 'platform' + i

        return [y_id, device_id, platform_id]


    def update_data(self):
        """Called each time that any watched property changes.

        This updates the sin wave data with the most recent values of the
        sliders. This is stored as two numpy arrays in a dict into the app's
        data source property.
        """

        # extract the user's input
        benchmark = self.benchmarks.value
        devices = list(device_names[i] for i in self.device_names.active)
        platforms = list(platform_names[i] for i in self.platform_names.active)
        x_axis_label = self.x_axis_options.value
        y_axis_label = self.y_axis_options.value


        # extract only the results which match this group
        filtered_results = filter(lambda x: x['benchmark_name'] == benchmark, celero_results)
        # remove the baseline measurements from the plots
        filtered_results = filter(lambda x: x['benchmark_name'] != "Baseline", filtered_results)

        # select the desired devices
        filtered_results = filter(lambda x: x['extra_data']['AF_DEVICE'] in devices, filtered_results)
        filtered_results = filter(lambda x: x['extra_data']['AF_PLATFORM'] in platforms, filtered_results)

        # extract the data
        sources = dict()
        result_number = 0
        for result in filtered_results:
            # ensure we don't plot too many results
            if result_number > MAX_PLOTS:
                break

            y_id, device_id, platform_id = self.make_field_ids(result_number)

            # Extract the results from the benchmark
            platform = result['extra_data']['AF_PLATFORM']
            device = result['extra_data']['AF_DEVICE']

            x = self.getXY(result, x_axis_label)
            y = self.getXY(result, y_axis_label)

            # store the benchmark results in the self.source object
            # NOTE: we replicate the device and platform data here so that
            # it works correctly with the mouseover/hover
            sources['x'] = x
            sources[y_id] = y
            sources[device_id] = [device] * len(x)
            sources[platform_id] = [platform] * len(x)

            # increment the counter
            result_number += 1

        # assign the data
        self.assign_source(sources, self.source0, 0)
        self.assign_source(sources, self.source1, 1)
        self.assign_source(sources, self.source2, 2)
        self.assign_source(sources, self.source3, 3)
        self.assign_source(sources, self.source4, 4)
        self.assign_source(sources, self.source5, 5)
        self.assign_source(sources, self.source6, 6)
        self.assign_source(sources, self.source7, 7)
        self.assign_source(sources, self.source8, 8)
        self.assign_source(sources, self.source9, 9)

    def assign_source(self, src, dest, index):
        """Assigns the data from src to the dictionary in dest if the
        corresponding data exists in src."""
        y_id, device_id, platform_id = self.make_field_ids(index)

        dest.data = dict()
        if y_id in src:
            dest.data['x'] = src['x']
            dest.data['y'] = src[y_id]
            dest.data['device'] = src[device_id]
            dest.data['platform'] = src[platform_id]
            dest._dirty = True
Beispiel #10
0
sort_widgets = [modelsort, datasetsort, filtersort]

def handler(new):
    layout.children[0] = create_figure()

def showall_handler():
    for w in visibility_widgets:
        w.active = list(range(len(w.labels)))
    layout.children[0] = create_figure()

def hideall_handler():
    for w in visibility_widgets:
        w.active = []
    layout.children[0] = create_figure()

modelboxes.on_click(handler)
datasetboxes.on_click(handler)
filterboxes.on_click(handler)
showall.on_click(showall_handler)
hideall.on_click(hideall_handler)
modelsort.on_click(handler)
datasetsort.on_click(handler)
filtersort.on_click(handler)

legendtext = ('\n'*8 + 'Solid: SVM Score\nOutline: RF Score\n\n' +
              'Green: UK\nPink: US\nOrange: Mixed\n' +
              'Purple: Reverse Split\nBlue: Split\n\n' +
              'Circle: Complete\nDiamond: Filtered')
controls = widgetbox([PreText(text='Choose Visible Items')] +
                     visibility_widgets + [showall, hideall] +
                     [PreText(text='Choose What to Sort Kmers by')] +
Beispiel #11
0
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="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.on_click(lambda value: print('radio_button_group: %s' % value))
radio_button_group.js_on_click(CustomJS(code="console.log('radio_button_group: ' + this.active, this.toString())"))

widgetBox = WidgetBox(children=[
    button, button_disabled,
    toggle_inactive, toggle_active,
    dropdown, dropdown_disabled, #dropdown_split,
    checkbox_group, radio_group,
    checkbox_button_group, radio_button_group,
])

document = curdoc()
Beispiel #12
0

def select_data():
    data_val = data_select.value
    with h5py.File('demo_data.hdf5', 'r') as f:
        return get_data(f, data_val)

def show_hide(active):
    if 0 in active:
        alpha = 1
    elif 0 not in active:
        alpha = 0
    renderer.glyph.line_alpha = alpha


def update_data(attrname, old, new):
    # hardcoded length of 100
    x = list(range(1, 101))
    y = select_data()
    source.data = dict(x=x, y=y)


data_select.on_change('value', update_data)
checkbox_button_group.on_click(show_hide)

inputs = VBoxForm(data_select, checkbox_button_group, width=300)

update_data(None, None, None)

curdoc().add_root(HBox(inputs, p, width=1100))
def modify_second_descriptive(doc):
    models = OrderedDict([])

    # Llamada al webservice de RapidMiner
    json_perfil_document = call_webservice(
        'http://rapidminer.vicomtech.org/api/rest/process/EDAR_Cartuja_Perfil_Out_JSON?',
        'rapidminer',
        'rapidminer',
        out_json=True)

    # Extracción de los datos web
    df_perfil = [json_normalize(data) for data in json_perfil_document]

    # Asignación de los datos web a su variable correspondiente
    prediction_df = df_perfil[3]
    outlier_df = df_perfil[4]

    # Creación de los gráficos y widgets permanentes en la interfaz
    prediction_plot = create_prediction_plot(prediction_df)
    outlier_plot = create_outlier_plot(outlier_df)
    simulation_title = create_div_title('Simulación')
    model_title, add_model_button, model_select_menu = create_model_menu()
    model_select_wb = widgetbox(
        [model_title, model_select_menu, add_model_button],
        max_width=200,
        sizing_mode='stretch_width')
    created_models_title = create_div_title('Modelos creados')
    created_models_checkbox = CheckboxButtonGroup(labels=list(models.keys()),
                                                  height=35)
    created_models_checkbox.active = [0]
    delete_model_button = Button(label='Eliminar',
                                 button_type='danger',
                                 height=45,
                                 max_width=200)
    created_models_wb = widgetbox(
        [created_models_title, created_models_checkbox],
        max_width=900,
        sizing_mode='stretch_width')

    # Callbacks para los widgets de la interfaz
    def prediction_callback():
        # Llamar al servicio web EDAR_Cartuja_Prediccion con los nuevos parámetros
        model_objective = model_select_menu.value
        model_discretise = 5

        # Verificar que el modelo no ha sido creado antes
        if model_objective not in models:
            json_prediction_document = call_webservice(
                'http://rapidminer.vicomtech.org/api/rest/process/EDAR_Cartuja_Prediccion_JSON?',
                'rapidminer',
                'rapidminer', {
                    'Objetivo': model_objective,
                    'Discretizacion': model_discretise,
                    'Numero_Atributos': 4
                },
                out_json=True)

            # Obtener datos
            df_prediction = [
                json_normalize(data) for data in json_prediction_document
            ]

            decision_tree_df = df_prediction[0]
            confusion_df_raw = df_prediction[1].reindex(
                columns=list(json_prediction_document[1][0].keys()))
            confusion_df = create_df_confusion(confusion_df_raw)
            weight_df = df_prediction[2]
            daily_pred_df = df_prediction[3][[
                'timestamp', model_objective, f'prediction({model_objective})'
            ]]
            decision_tree_data = create_decision_tree_data(
                decision_tree_df, model_objective)

            # Crear nuevos gráficos
            daily_pred_plot = create_daily_pred_plot(daily_pred_df,
                                                     model_objective)
            decision_tree_plot = create_decision_tree_plot()
            decision_tree_graph = create_decision_tree_graph_renderer(
                decision_tree_plot, decision_tree_data)
            decision_tree_plot = append_labels_to_decision_tree(
                decision_tree_plot, decision_tree_graph, decision_tree_data)
            confusion_matrix = create_confusion_matrix(confusion_df)
            weight_plot = create_attribute_weight_plot(weight_df,
                                                       model_objective)
            corrects_plot = create_corrects_plot(confusion_df, model_objective)
            confusion_title = create_div_title(
                f'Matriz de confusión - {model_objective}')
            decision_tree_title = create_div_title(
                f'Arbol de decisión - {model_objective}')
            new_plots = layout(
                [[daily_pred_plot],
                 [
                     column([confusion_title, confusion_matrix],
                            sizing_mode='stretch_width'), weight_plot,
                     corrects_plot
                 ], [decision_tree_title], [decision_tree_plot]],
                name=model_objective,
                sizing_mode='stretch_width')
            model_plots.children.append(new_plots)
            models.update({model_objective: new_plots})
            models.move_to_end(model_objective, last=False)
            created_models_checkbox.labels = list(models.keys())
            created_models_checkbox.active = list(range(len(models.keys())))

    add_model_button.on_click(prediction_callback)

    def remove_options_handler(new):
        selected_labels = [
            created_models_checkbox.labels[elements]
            for elements in created_models_checkbox.active
        ]
        try:
            for element in selected_labels:
                models.pop(element)
                model_plots.children.remove(doc.get_model_by_name(element))
        except:
            for element in selected_labels:
                print(f"El modelo {element} no existe")
        created_models_checkbox.labels = list(models.keys())
        created_models_checkbox.active = list(range(len(models.keys())))

    delete_model_button.on_click(remove_options_handler)

    def show_hide_plots(new):
        selected_labels = [
            created_models_checkbox.labels[elements] for elements in new
        ]
        # model_plots.children = []
        children = []
        for element in selected_labels:
            children.append(models[element])
        model_plots.children = children

    created_models_checkbox.on_click(show_hide_plots)

    # Creación del layout dinámico de la interfaz
    model_plots = column([])
    prediction_callback()

    # Creación del layout estático de la interfaz
    l = layout([[prediction_plot], [outlier_plot], [simulation_title],
                [
                    model_select_wb,
                    column(created_models_wb,
                           delete_model_button,
                           sizing_mode='stretch_width')
                ], [model_plots]],
               sizing_mode='stretch_both')

    doc.add_root(l)
Beispiel #14
0
def monitors(doc):
    ## Streaming Update Function
    def update():
        global cfg
        global s1
        global s2
        global s3

        df = get_vars(cfg['mon_fname'])
        s1.stream(df.to_dict(orient='list'), rollover=len(df))

        df = get_res(cfg['tra_fname'], cfg['resid_len'])
        if cfg['resid_len'] is None:
            s2.stream(df.to_dict(orient='list'), rollover=len(df))
        else:
            s2.stream(df.to_dict(orient='list'), rollover=cfg['resid_len'])
        s3.stream(get_prog(cfg['tra_fname']), rollover=1)

    def update_images():
        global cfg
        global s4
        s4.stream(get_img_data(cfg), rollover=1)

    ## Backgroud Color Update Function
    def night_mode():
        if (pd.datetime.now().hour >= 19) or (pd.datetime.now().hour < 6):
            curdoc().theme = 'dark_minimal'
            #curdoc().template = 'dark.html'

        else:
            curdoc().theme = 'light_minimal'
            #curdoc().template = 'index.html'
            # THIS NEEDS TO BE A JINJA TYPE?
        ## Not sure why this doesn't work...
        #curdoc().template_variables.update(background='#BA55D3')

    global cfg

    ## Plotting Setup
    do_not_plot = [
        'iteration', 'time', 'iter_left', 'converged', 'relative_total_time',
        'relative_time_step'
    ]
    sizes = cfg['sizes'].tolist()
    colors = itertools.cycle(palette)
    colors_res = itertools.cycle(palette)
    hover = HoverTool()
    res_hover = HoverTool()
    if 'flow_time' in s1.data.keys():
        # Unsteady Flow (transient)
        x_opts = [('Flow Time', '@flow_time s'), ('Time Step', '@time_step')]
        x_var = 'flow_time'
    else:
        # Steady Flow
        x_opts = [('Iteration', '@iteration')]
        x_var = 'iteration'
    hover.tooltips = [('Variable', '$name'), ('Value', '$y'), *x_opts]
    res_hover.tooltips = [('Variable', '$name'), ('Value', '$y'),
                          ('Iteration', '@iteration')]

    ## Plot Residuals
    w, h = sizes.pop(0)
    res_plots = figure(tools="pan,wheel_zoom,box_zoom,undo,reset,save",
                       plot_width=w,
                       plot_height=h,
                       y_axis_type='log')
    res_plots.add_tools(res_hover)

    for var, color in zip(s2.data.keys(), colors_res):
        if var not in do_not_plot:
            res_plots.line('iteration',
                           var,
                           line_width=2,
                           source=s2,
                           color=color,
                           legend=var.replace('_', ' ').title(),
                           name=var.replace('_', ' ').title())

    res_plots.legend.location = "top_left"
    res_plots.legend.click_policy = "hide"

    ## Progress Bar
    prog_bar = figure(plot_width=300,
                      plot_height=25,
                      toolbar_location=None,
                      x_range=[0, 1])
    prog_bar.grid.visible = False
    prog_bar.axis.visible = False
    prog_bar.hbar_stack(['steps_complete', 'steps_left'],
                        y=1,
                        height=0.8,
                        color=("limegreen", "lightgrey"),
                        source=s3)
    prog_bar.text(0.5,
                  1,
                  text='text',
                  text_baseline="middle",
                  text_align="center",
                  text_color="white",
                  text_font_style="bold",
                  source=s3)

    ## Plot Monitor Variables
    variables = var_name_cleaner(cfg['variables'])
    if cfg['var_ylims']:
        ylims = cfg['var_ylims']
    else:
        ylims = len(variables) * [None]

    plots = [res_plots]
    for var, ylim, color in zip(variables, ylims, colors):
        w, h = sizes.pop(0)
        p = figure(tools="pan,wheel_zoom,box_zoom,undo,reset,save",
                   plot_width=w,
                   plot_height=h)
        # Link x ranges
        try:
            p.x_range = plots[1].x_range
        except:
            pass
        if ylim is not None:
            print(ylim)
            p.y_range = Range1d(*ylim)

        if isinstance(var, str):
            p.line(x_var,
                   var,
                   line_width=2,
                   source=s1,
                   color=color,
                   legend=var.replace('_', ' ').title(),
                   name=var.replace('_', ' ').title())
        elif isinstance(var, list) or isinstance(var, tuple):
            for y, color in zip(var, itertools.cycle(palette_2)):
                p.line(x_var,
                       y,
                       line_width=2,
                       source=s1,
                       color=color,
                       legend=y.replace('_', ' ').title(),
                       name=y.replace('_', ' ').title())

        p.add_tools(hover)
        p.legend.click_policy = "hide"
        p.legend.location = "top_left"
        plots.append(p)

    ## Legend Locations
    select = Select(value="top_left",
                    options=list(LegendLocation),
                    width=100,
                    height=25)
    [select.js_link('value', f.legend[0], 'location') for f in plots[1::]]

    ## Legend Visibility
    def legend_visibility(active):
        for n, plot in enumerate(plots):
            if n in active:
                plot.legend[0].visible = True
            else:
                plot.legend[0].visible = False

    legend_button_group = CheckboxButtonGroup(
        labels=['Legend ' + str(n) for n in range(0, len(plots))],
        active=[n for n in range(0, len(plots))],
        width=cfg['width'] - 400,
        height=25)
    legend_button_group.on_click(legend_visibility)

    ## Turn off all active tools (helps for mobile)
    #https://stackoverflow.com/questions/49282688/how-do-i-set-default-active-tools-for-a-bokeh-gridplot
    # THIS DOESNT @!#$#@ WORK
    for p in plots:
        p.toolbar.active_drag = None
        p.toolbar.active_scroll = None
        p.toolbar.active_tap = None

    ## Initialize Image Plots
    if cfg['img_folder']:
        try:
            img_basenames = cfg['images']
            tabs = [Panel(child=plots[0], title='Residuals')]
            for img in img_basenames:
                p = figure(plot_width=plots[0].width,
                           plot_height=plots[0].height,
                           x_range=(0, 1),
                           y_range=(0, 1))
                p.image_url(url=img, x='x', y='y', w='w', h='h', source=s4)
                tabs.append(Panel(child=p, title=img))
            plots[0] = Tabs(tabs=tabs)
        except:
            print('Cannot add images')

    ## Create Layout
    # This will split the flat arry where sizes sum to the width of the doc
    sizes = cfg['sizes']
    splits = 1 + np.where(np.cumsum(sizes[:, 0]) % cfg['width'] == 0)[0]
    layout = [
        x.tolist() for x in np.split(np.array(plots), splits) if len(x) > 0
    ]

    ## Build the Document
    #doc.template = 'dark.html'
    night_mode()
    doc.add_periodic_callback(update, cfg['polling_int'])
    if cfg['img_folder']:
        doc.add_periodic_callback(update_images, 1000 * 30)
    doc.add_periodic_callback(night_mode, 1000 * 60 * 10)
    doc.title = 'Fluent Monitors'

    #Panel(child=p, title=fname)
    #gps = gridplot([[prog_bar,select,legend_button_group],[layout]], toolbar_location=None)
    #doc.add_root(gps)

    doc.add_root(
        gridplot([[prog_bar, select, legend_button_group]],
                 toolbar_location=None))
    [doc.add_root(gridplot([row], toolbar_location='right')) for row in layout]
Beispiel #15
0
          'Associate Professor',  'Full Professor'],
                             axis=1).rename({"Other (please specify)":"Other"},axis=1)

    pt = dfTotal.cumsum(axis=1)
    p = figure(title="Count of Positions of Data Science Professionals",
              x_axis_label='Primary Role', y_axis_label='Total',
              x_range = FactorRange(factors=list(pt.index)),
              plot_height=600, plot_width=900,tools=[])
    for column,color in zip(pt.columns,all_palettes['PiYG'][len(pt.columns)]):
       p.vbar(x=pt.index,bottom=pt[column]-dfTotal[column],top=pt[column],width=.2,color=color, legend = column)
    p.ygrid.minor_grid_line_color = 'black'
    p.ygrid.minor_grid_line_alpha = 0.1



    p.legend.location = "top_left"

    p.toolbar.logo = None
    return p



pronoun = CheckboxButtonGroup(
        labels=["She/Her/Hers", "He/His/Him", "Other","NA"], active=[0,1,2])
pronoun.on_click(update)

controls = column([pronoun], width=200)
layout = row(controls, create_figure())

curdoc().add_root(layout)
def create_message_timeseries_panel(message_df, title, participants,
                                    colour_palette):
    """ Creates a plot of messages to a chat over time

        Parameters:
        ===========

        message_df - pandas Dataframe
            A dataframe containing data of every message from a chat

        title - string
            A string containing the name of the group chat

        participants - list
            a list of strings of each pariticipant in the messenger chat

        colour_palette - list
            a list of strings which have a participant

        Returns:
        ===========

        message_panel - bokeh Panel
            A layout of graphs for analysis of message data
    """
    def plot_summary_data(messages):

        # See if your chat is dying:
        def curve(x, a, b, c):
            return a * np.exp(-b * x) + c

        total_messages = messages.groupby('Date').mean()
        total_messages = total_messages.resample('W', convention='end').sum(
        ).reset_index()  # Convert to a weekly aggregation of messages

        x_data = total_messages.Date.array.asi8 / 1e18
        y_data = total_messages['Message'].values

        popt, _ = curve_fit(curve, x_data, y_data, maxfev=100000)

        x_data_step = x_data[1] - x_data[0]

        x_data = list(x_data)

        for _ in range(51):
            x_data.append(x_data[-1] + x_data_step)

        x_data = np.array(x_data)

        y_prediction = curve(x_data, *popt)

        total_messages['Prediction'] = y_prediction[:len(total_messages)]

        total_messages_cds = ColumnDataSource(data=total_messages)

        main_figure.line(x='Date',
                         y='Message',
                         source=total_messages_cds,
                         alpha=0.45,
                         muted_alpha=0.2,
                         legend_label='Weekly Total',
                         color='black')

        main_figure.circle(x='Date',
                           y='Message',
                           source=total_messages_cds,
                           alpha=0.45,
                           muted_alpha=0.2,
                           legend_label='Weekly Average',
                           color='black')

        main_figure.line(x='Date',
                         y='Prediction',
                         source=total_messages_cds,
                         alpha=0.45,
                         muted_alpha=0.2,
                         legend_label='Trend',
                         line_dash='dashed',
                         color='red')

    # Find x-axis limits:
    start_date = min(message_df.loc[:, 'Date'])
    end_date = max(message_df.loc[:, 'Date'])

    # Create widget objects:
    name_buttons = CheckboxButtonGroup(
        labels=participants, active=[i for i in range(len(participants))])
    date_slider = DateRangeSlider(end=end_date,
                                  start=start_date,
                                  value=(start_date, end_date),
                                  step=1)

    # Create figures to be included:
    main_figure = figure(plot_width=800,
                         plot_height=250,
                         x_axis_type="datetime",
                         toolbar_location=None)
    main_figure.toolbar.logo = None
    main_figure.x_range.start = start_date
    main_figure.x_range.end = end_date
    main_figure.toolbar.active_drag = None
    main_figure.toolbar.active_scroll = None

    messages_tooltip = HoverTool(tooltips=[('Name', '@Name'),
                                           ('Message Count', '@Message'),
                                           ('Date', '@Date{%A, %e %B %Y}')],
                                 formatters={'@Date': "datetime"})

    main_figure.add_tools(messages_tooltip)

    overview_figure = figure(plot_height=80,
                             plot_width=800,
                             x_axis_type='datetime',
                             toolbar_location=None,
                             x_range=(start_date, end_date))
    overview_figure.yaxis.major_label_text_color = None
    overview_figure.yaxis.major_tick_line_color = None
    overview_figure.yaxis.minor_tick_line_color = None
    overview_figure.grid.grid_line_color = None
    overview_figure.toolbar.active_drag = None
    overview_figure.toolbar.active_scroll = None

    box = BoxAnnotation(fill_alpha=0.5,
                        line_alpha=0.5,
                        level='underlay',
                        left=start_date,
                        right=end_date)

    messages = message_df.groupby(['Name', 'Date']).count().reset_index()
    messages = messages.loc[:, messages.columns != 'Reacts']

    source = ColumnDataSource(data=messages)

    # Plot a line for each person onto both figures:
    for index, name in enumerate(participants):
        view = CDSView(source=source,
                       filters=[GroupFilter(column_name='Name', group=name)])

        main_figure.line(x='Date',
                         y='Message',
                         source=source,
                         view=view,
                         alpha=0.45,
                         muted_color=colour_palette[index],
                         muted_alpha=0.2,
                         legend_label=name,
                         color=colour_palette[index])

        main_figure.circle(x='Date',
                           y='Message',
                           alpha=0.55,
                           source=source,
                           view=view,
                           muted_color=colour_palette[index],
                           muted_alpha=0.2,
                           legend_label=name,
                           color=colour_palette[index])

        overview_figure.line(x='Date',
                             y='Message',
                             source=source,
                             view=view,
                             color=colour_palette[index])

    if len(participants) > 2:
        plot_summary_data(messages)

    main_figure.xaxis.axis_label = 'Time'
    main_figure.yaxis.axis_label = 'Total Messages'
    main_figure.title.text = title
    main_figure.legend.location = "top_right"
    main_figure.legend.click_policy = "mute"
    main_figure.legend.orientation = 'horizontal'
    main_figure.legend.spacing = 7

    overview_figure.add_layout(box)

    # --------------------------------------------------------------------------+
    # Creating Real Python callbacks for interaction between plots and widgets |
    # --------------------------------------------------------------------------+

    def update_graph(active_labels):
        df = message_df
        selected_names = [name_buttons.labels[i] for i in name_buttons.active]
        df = df[df['Name'].isin(selected_names)]
        df = df.groupby(by=['Name', 'Date']).count().reset_index()
        source.data = dict(
            Date=df['Date'],
            Message=df['Message'],
            Name=df["Name"],
        )

    def update_range(attr, old, new):
        start = datetime.fromtimestamp(new[0] / 1e3)
        end = datetime.fromtimestamp(new[1] / 1e3)
        main_figure.x_range.start = start
        main_figure.x_range.end = end

        box.left = start
        box.right = end

    # Assign callbacks to appropriate widget interactions
    name_buttons.on_click(update_graph)
    date_slider.on_change('value', update_range)

    date_slider_layout = row(Spacer(width=46, height=50, sizing_mode="fixed"),
                             date_slider,
                             sizing_mode="scale_width")

    plots = column(main_figure,
                   date_slider_layout,
                   overview_figure,
                   sizing_mode="scale_width")

    # Create the layout of the Bokeh application
    message_timeseries = layout([[name_buttons], [plots]],
                                sizing_mode="scale_width")

    message_timeseries.margin = (10, 35, 60, 20)

    message_panel = Panel(child=message_timeseries, title='Message Data')

    return message_panel