CoolFace
Apppublic

Projet2024/Projet_data_viz_CZSS

sourceHugging Faceotherupdated 2y agoView on Hugging Face
0likes
app.py481 linesDownload Raw Back to root
1import seaborn as sns2import pandas as pd3import numpy as np 4from shared import uc, scoring, encodage_sfdr, encodage_devise5import plotly.graph_objects as go6import plotly.express as px7import plotly.figure_factory as ff8from shiny import App, render, ui, reactive, req9from shinywidgets import output_widget, render_widget   10import shinyswatch11from faicons import icon_svg as icon12from datatable import dt, f, by, g, join, sort, update, ifelse, rowsum, rowmean,math, min, max, median13 14page_presentation = ui.page_fluid(15    ui.div(16        ui.h3("Bienvenue sur votre application d'analyse et de visualisation des données !"),17        ui.p(18            """19            Cette plateforme vous permet d'explorer, d'analyser et de visualiser en profondeur 20            les performances des unités de compte (UC) en fonction de divers critères. 21            Voici un aperçu des principales fonctionnalités disponibles :22            """23        ),24        ui.tags.ul(25            ui.tags.li("Analyse des données : Parcourez et filtrez les données des UC selon des critères spécifiques comme le SRI, les critères ESG, les frais, et bien plus."),26            ui.tags.li("Gestion des Marchés Cibles : Définissez et personnalisez des marchés cibles en fonction de vos besoins. Créez, modifiez ou supprimez des segments et visualisez les UC qui répondent aux critères définis."),27            ui.tags.li("Scoring et évaluation : Analysez les scores des UC en fonction de facteurs clés tels que les rendements, les frais et les prix. Paramétrez vos critères de scoring pour adapter les évaluations à vos besoins."),28            ui.tags.li("Visualisations interactives : Explorez les données grâce à des graphiques dynamiques :"),29            ui.tags.ul(30                ui.tags.li("Des nuages de points pour comparer les performances globales des UC."),31                ui.tags.li("Des histogrammes et des courbes de densité pour visualiser les distributions des scores."),32                ui.tags.li("Des graphiques en bulles pour explorer les corrélations entre critères."),33            ),34            ui.tags.li("Vue globale : Obtenez un aperçu des scores moyens et des corrélations entre les UC de différents groupes ou marchés cibles."),35            ui.tags.li("Pensez à visiter toutes les pages dans l'ordre ! "),36            ui.tags.li("Les données proviennent d'un scrapping simple de Boursorama")37        ),38        style="padding: 2rem; background-color: #f8f8f8; border-radius: 10px; border: 1px solid #ccc;"39    )40)41 42 43page_uc = ui.div(ui.page_navbar(44                ui.nav_panel('Info', page_presentation),45                ui.nav_panel("marché cible",46                             ui.page_sidebar(47                                 ui.sidebar(48                                    ui.div(ui.input_action_button("uc_pg_add", "Ajouter un marché cible")),49                                    ui.div(ui.input_action_button("uc_pg_del", "Supprimer un marché cible")),50                                    title=ui.div(icon('gear'), 'Gestion des marché cible', style = 'display : line'),51 52                                ),53                            ui.div(ui.div(ui.h6('Listing des marché cible'),style = 'padding-left : 10px;'),54                                   ui.output_data_frame("uc_grid_pg__"),55                                   style = 'width : 100%; height : 30vh; border: 1px solid; border-color : darkgrey; border-radius : 10px; margin-top: -15px;'),56                            ui.div(ui.div(ui.h6(ui.output_text('uc_pg_selected_name')),style = 'padding-left : 10px;'),57                                   ui.output_data_frame("uc_pg_selected"),58                                   style = 'width : 100%; min-height : 30vh; height : fit-content; border: 1px solid; border-color : darkgrey; border-radius : 10px; '),59                            )60                ),61                ui.nav_panel("Score",62                             ui.page_sidebar(63                                 ui.sidebar(64                                    ui.input_selectize("uc_score_pg", label=None, choices=[], multiple=False, options={'placeholder':'Choisissez un marché cible'}),65                                    ui.input_switch('uc_score_critere_switch_all', 'Sélectionner tous les critères', True),66                                    ui.tags.ul(67                                        ui.tags.li(68                                            ui.h6("Rendement PRIIPS"),69                                            ui.row(70                                                ui.column(6,71                                                        ui.input_checkbox_group("uc_score_critere_rdmt_priips_1an",72                                                                                "Rendement 1 an",73                                                                                {74                                                                                    "score_rendement_tension_1an": "Tension",  75                                                                                    "score_rendement_defavorable_1an": "Défavorable",  76                                                                                    "score_rendement_intermediaire_1an": "Intermédiaire",  77                                                                                    "score_rendement_favorable_1an": "Favorable"78                                                                                    }79                                                            )80                                                ),81                                                ui.column(6,82                                                        ui.input_checkbox_group("uc_score_critere_rdmt_priips_ddr",  83                                                                                    "Rendement à DDR",  84                                                                                    {  85                                                                                    "score_rendement_tension_ddr": "Tension",  86                                                                                    "score_rendement_defavorable_ddr": "Défavorable",  87                                                                                    "score_rendement_intermediaire_ddr": "Intermédiaire",  88                                                                                    "score_rendement_favorable_ddr": "Favorable"89                                                                                    }90                                                            )91                                                )92 93                                            )94                                                    95                                                ),96                                        ui.tags.li(97                                            ui.input_checkbox_group(  98                                            "uc_score_critere_frais",  99                                            "Frais",  100                                            {  101                                                "score_uc_frais_entree": "Frais d'entrée",  102                                                "score_uc_frais_gestion": "Frais de gestion",  103                                                "score_uc_frais_transaction": "Frais de transaction", 104                                                "score_uc_frais_sortie": "Frais de sortie" 105                                            },  106                                        )107                                        ),108                                        ui.tags.li(109                                            ui.input_checkbox_group(  110                                            "uc_score_critere_riy",  111                                            "Prix / Coût",  112                                            {  113                                                "score_riy_1an": "Incidence des coûts après 1 an",  114                                                "score_riy_ddr": "Incidence des coûts à la DDR",115                                            },  116                                        )117                                        ),118                                        119                                    ),120                                    title=ui.div(icon('gear'), 'Paramètres du scoring', style = 'display : line; margin-top : -35px'),121                                    width = '30%'122                                ),123                            ui.div(ui.div(ui.h6('Tableau des scores'),style = 'padding-left : 10px;'),124                                   ui.output_data_frame("uc_score_grid"),125                                   style = 'width : 100%; min-height : 30vh; height : fit-content; border: 1px solid; border-color : darkgrey; border-radius : 10px; margin-top: -15px;')126                            )127                             ),128                ui.nav_panel("Distribution",129                             ui.input_selectize("uc_visu_pg", label=None, choices=[], multiple=False, options={'placeholder':'Choisissez un marché cible'}),130 131                             ui.row(132                    ui.column(6,ui.div("distplot", ui.input_radio_buttons("uc_visu_boutton", "Type de représentation", choices = {'hist' : "Histogramme"}), 133                                       output_widget('uc_visu_histo'), style = 'width : 100%; height-min : 30vh; height : fit-content; border: 1px solid; border-color : darkgrey; border-radius : 10px; '),134                    135                              ),136                    ui.column(6,ui.div("boxplot", 137                                       ui.input_radio_buttons("uc_visu_boutton_box", "Type de représentation", 138                                                              choices = {'score_rdmt_priips_1an' : "Rendement 1 an ", 'score_rdmt_priips_ddr' : "Rendement DDR",139                                                                         "score_frais" : "Frais"}),140                                        output_widget('uc_visu_box'),141                                                      style = 'width : 100%; height-min : 30vh; height : fit-content; border: 1px solid; border-color : darkgrey; border-radius : 10px; '))142                    ,style = 'padding-left : 2rem; padding-right : 2rem')), 143                144                ui.nav_panel("Visualisation",145                             ui.input_selectize("uc_visu_2_pg", label=None, choices=[], multiple=False, options={'placeholder':'Choisissez un marché cible'}),146 147                148                    ui.column(6,ui.div("Scatter", [ui.input_selectize('uc_bubble_abcisse',label = 'Abscisse', multiple= False, choices = [], options={'placeholder' : "abcisse"},),149                                                      ui.input_selectize('uc_bubble_ordonnée',label = 'Ordonnée', multiple= False, choices = [], options={'placeholder' : "ordonnée"}),150                                                      ui.input_selectize('uc_bubble_taille', label = 'Ventilation', multiple= False, choices = [], options={'placeholder' : "taille"})], 151                                                      output_widget('uc_visu_bubble'),152                                                      style = 'width : 100%; height-min : 30vh; height : fit-content; border: 1px solid; border-color : darkgrey; border-radius : 10px; '))153                    ),154 155    ),156     style = 'padding-top : 0'157)158                                                                159app_ui = ui.page_fluid(160    # shinyswatch.theme_picker_ui(),161    ui.include_css("./www/css/header.css"),162    ui.tags.head(163        ui.tags.link(rel = "icon", type = "image/png", sizes = "32x32", href = "./img/logo-ISUP.png")),164    ui.page_navbar(ui.nav_spacer(), 165                   ui.nav_panel(ui.div("Unité de compte", style = 'width : 120px; text-align : center'), page_uc),166                #  ui.nav_panel('debug', page_debug),167                   title=ui.div(168                          ui.div("Data viz CZSS",style = 'height: 80px; line-height: 80px; text-align: center;'),169                          ui.output_image("image", height='80px', width = '80px'),170                          style = 'display : flex; width : 230px; flex-direction: row-reverse;'),171                   window_title='ISUP: Data viz',172                   theme = shinyswatch.theme.sandstone173                   174    ),175    style = 'body {padding-left : 100px; padding-right : 0px;}',176 177)178 179def server(input, output, session):180    uc_pg_name = reactive.value([])181    uc_pg_dict = {}182    183    @render.image  184    def image():185        img = {"src": "./www/img/logo-ISUP.png", "width": "80px"}  186        return img     187 188    @render.data_frame189    def uc_grid_data():190        return render.DataGrid(data = uc, filters=True, editable=True , height= '75vh')191    192    193    @render.data_frame194    def uc_pg_add_tmp():195        tmp = uc196        if input.uc_pg_duree():197            tmp = tmp[[f.objectif == i for i in input.uc_pg_duree()],:]198        if input.uc_pg_sri():199            tmp = tmp[(f.sri >= input.uc_pg_sri()[0]) & (f.sri <= input.uc_pg_sri()[1]),:]200        if input.uc_pg_esg():201            tmp = tmp[[f.sfdr== i for i in input.uc_pg_esg()],:]202                203        return render.DataGrid(data = tmp, filters=False, editable=False , height= '75vh;')204 205    @reactive.effect206    @reactive.event(input.uc_pg_add)207    def __():208        tab_pg_add = ui.page_sidebar(209            ui.sidebar(ui.input_text('uc_pg_nom', label=None, placeholder='Nom du marché cible'),210                ui.input_selectize('uc_pg_duree', label=None, options={'placeholder' : "Durée d'investissement"}, choices= list(['Court terme','Moyen terme','Long terme']), multiple=True),211                ui.row(212                    ui.column(2,ui.div("SRI", style = 'height: 79px; align-content : center')),213                    ui.column(10,ui.input_slider('uc_pg_sri',label=None, ticks=True,min=1, max=7, value=[1,7], step=1))),214                ui.input_selectize("uc_pg_esg", label=None, options={'placeholder' : 'Critères ESG'},choices=["article 6", "article 8", 'article 9','aucune' ], multiple=True),215                bg="#f6f6f6",216                title=None,217                width='30%'),218            'Prévisualisation du Peer-group',219            ui.output_data_frame('uc_pg_add_tmp'))220        221        # tmp = ui.modal( ui.div(ui.navset_tab222        #             (ui.nav_panel('marché cible', tab_pg_add),223        #              ui.nav_panel('Critères de comparaison',tab_pref )224        tmp = ui.modal( ui.div(tab_pg_add,225                     style = 'width : 80 vw;'),226                     footer=ui.input_action_button("valider", "Valider"),227                     title='Définissez un marché cible UC' ,228                     easy_close= True,229                     size = 'xl'230        )231       232        ui.modal_show(tmp)233 234 235    @reactive.effect236    @reactive.event(input.uc_score_critere_switch_all)237    def __():238        if input.uc_score_critere_switch_all() :239            ui.update_checkbox_group("uc_score_critere_rdmt_priips_1an",selected=['score_rendement_tension_1an','score_rendement_defavorable_1an','score_rendement_intermediaire_1an','score_rendement_favorable_1an'])240            ui.update_checkbox_group("uc_score_critere_rdmt_priips_ddr",selected=['score_rendement_tension_ddr','score_rendement_defavorable_ddr','score_rendement_intermediaire_ddr','score_rendement_favorable_ddr'])241            ui.update_checkbox_group("uc_score_critere_frais",selected=['score_uc_frais_entree','score_uc_frais_gestion','score_uc_frais_transaction','score_uc_frais_sortie'])242            ui.update_checkbox_group("uc_score_critere_riy",selected=['score_riy_1an','score_riy_ddr'])243        else :244            ui.update_checkbox_group("uc_score_critere_rdmt_priips_1an",selected=[])245            ui.update_checkbox_group("uc_score_critere_rdmt_priips_ddr",selected=[])246            ui.update_checkbox_group("uc_score_critere_frais",selected=[])247            ui.update_checkbox_group("uc_score_critere_riy",selected=[])248        249 250 251    @reactive.effect252    @reactive.event(input.valider)253    def uc_pg_table (): 254        new_pg = {255            "Nom" : input.uc_pg_nom(),256            "Durée": input.uc_pg_duree(),257            "Risque" : input.uc_pg_sri(),258            "ESG" : input.uc_pg_esg()259            }260 261        if input.uc_pg_nom() in uc_pg_name.get():262                tmp = ui.modal(ui.h6("Merci de choisir un autre nom."),263                               footer=None,264                                title='Nom de marché cible déjà utilisé' ,265                                easy_close= True,266                                size = 'l')267                ui.modal_show(tmp)268        else :269            score = uc270            if len(input.uc_pg_duree())>0 :271                score = score[[f.objectif == i for i in input.uc_pg_duree()],:]272            if len(input.uc_pg_sri())>0 :273                score = score[(f.sri >= input.uc_pg_sri()[0]) & (f.sri <= input.uc_pg_sri()[1]),:]274            if len(input.uc_pg_esg())>0 :275                score = score[[f.sfdr == i for i in input.uc_pg_esg()],:]276 277            score[:,  update(score_rendement_tension_1an = scoring(x = f.rdmt_tension_1an))]278            score[:,  update(score_rendement_tension_ddr = scoring(x = f.rdmt_tension_ddr))]279            score[:,  update(score_rendement_defavorable_1an = scoring(x = f.rdmt_defa_1an))]280            score[:,  update(score_rendement_defavorable_ddr = scoring(x = f.rdmt_defa_ddr))]281            score[:,  update(score_rendement_intermediaire_1an = scoring(x = f.rdmt_inter_1an))]282            score[:,  update(score_rendement_intermediaire_ddr = scoring(x = f.rdmt_inter_ddr))]283            score[:,  update(score_rendement_favorable_1an = scoring(x = f.rdmt_favo_1an))]284            score[:,  update(score_rendement_favorable_ddr = scoring(x = f.rdmt_favo_ddr))]285            score[:,  update(score_uc_frais_entree = scoring(x = f.uc_frais_entree, order = -1))]286            score[:,  update(score_uc_frais_gestion = scoring(x = f.uc_frais_gestion, order = -1))]287            score[:,  update(score_uc_frais_transaction = scoring(x = f.uc_frais_transaction, order = -1))]288            score[:,  update(score_uc_frais_sortie = scoring(x = f.uc_frais_sortie, order = -1))]289            score[:,  update(score_riy_1an = scoring(x = f.riy_1an, order = -1))]290            score[:,  update(score_riy_ddr = scoring(x = f.riy_ddr, order = -1))]291            score[:, update(score_rdmt_priips_1an = rowmean([f[item] for item in list(input.uc_score_critere_rdmt_priips_1an())]))]292            score[:, update(score_rdmt_priips_ddr = rowmean([f[item] for item in list(input.uc_score_critere_rdmt_priips_ddr())]))]293            score[:, update(score_frais = rowmean([f[item] for item in list(input.uc_score_critere_frais())]))] 294            score[:, update(score_riy = rowmean([f[item] for item in list(input.uc_score_critere_riy())]))]295            score[:, update(sc_VFM = rowmean(f.score_rdmt_priips_1an, f.score_rdmt_priips_ddr, f.score_frais, f.score_riy ))]296 297            nouvel_ordre = ['isin','compagnie_fonds','sc_VFM','score_rdmt_priips_1an','score_rdmt_priips_ddr','score_frais',298                            'score_riy','type_uc','objectif','sri','devise', 'rdmt_min_gar','confo_priips','innovant','complexite',299                            'coupon','risque_devise','rdmt_tension_1an','score_rendement_tension_1an','rdmt_defa_1an',300                            'score_rendement_defavorable_1an','rdmt_inter_1an','score_rendement_intermediaire_1an','rdmt_favo_1an',301                            'score_rendement_favorable_1an', 'rdmt_tension_ddr','score_rendement_tension_ddr','rdmt_defa_ddr',302                            'score_rendement_defavorable_ddr','rdmt_inter_ddr','score_rendement_intermediaire_ddr','rdmt_favo_ddr',303                            'score_rendement_favorable_ddr','uc_frais_entree','score_uc_frais_entree','uc_frais_gestion',304                            'score_uc_frais_gestion','uc_frais_transaction','score_uc_frais_transaction','uc_frais_sortie',305                            'score_uc_frais_sortie','riy_1an','score_riy_1an','riy_ddr','score_riy_ddr','sfdr']306            307 308            score = score[:, nouvel_ordre]309            uc_pg_name.set(uc_pg_name.get() + [input.uc_pg_nom()])310            uc_pg_dict[input.uc_pg_nom()] = {'definition' : new_pg,311                                            #  'critere' : new_critere,312                                             'score' : score}313          314        ui.modal_remove()315        316    @output317    @render.data_frame318    def uc_grid_pg__():319        pg_list = [uc_pg_dict[pg]['definition'] for pg in uc_pg_dict.keys()]320        ui.update_select("uc_score_pg", choices= uc_pg_name.get())321        ui.update_select("uc_visu_pg", choices= uc_pg_name.get())322 323        324        if pg_list :325            return render.DataGrid(data = pd.DataFrame(pg_list), selection_mode="rows")326        else :327            vide = {328            "Nom" : '',329            "Durée": '',330            "Risque" : '',331            "ESG" : '',332            }333            return render.DataGrid(data = pd.DataFrame(vide,index=[0]))334 335    @render.data_frame336    def uc_pg_selected():337        filters = uc_grid_pg__.data_view(selected=True)338        if np.shape(filters)[0] > 0 :    339            tmp = uc340            if len(filters.iloc[0,1])>0 :341                tmp = tmp[[f.objectif == i for i in filters.iloc[0,1]],:]342            if len(filters.iloc[0,2])>0 :343                tmp = tmp[(f.sri >= filters.iloc[0,2][0]) & (f.sri <= filters.iloc[0,2][1]),:]344            if len(filters.iloc[0,3])>0 :345                tmp = tmp[[f.sfdr == i for i in filters.iloc[0,3]],:]346 347            return render.DataGrid(data= tmp, filters=True)348            349    @render.text350    def uc_pg_selected_name():351        filters = uc_grid_pg__.data_view(selected=True)352        print(np.shape(filters))353        if np.shape(filters)[0] > 0 : 354            name = filters.iloc[0,0]   355            return f"Visualisation du marché cible : {name}"356        else :357            return "Aucun marché cible du Listing n'est selectionné"358 359    @reactive.effect360    @reactive.event(input.uc_pg_del)361    def supp_pg ():362        supp_pg= ui.modal(ui.page_fluid(363                        ui.input_selectize("pg_to_delete", "Sélectionnez un marché cible à supprimer:", [], multiple=True),364                        ),365                        footer=ui.input_action_button("supprimer",'Supprimer'),366                        title="Supression d'un marché cible",367                        easy_close= True368                )369        370        pg_names = uc_pg_name.get()371        ui.update_select("pg_to_delete", choices=pg_names)372        ui.modal_show(supp_pg)373 374    @reactive.effect375    @reactive.event(input.supprimer)376    def delete_pg():377        if len(uc_pg_name.get()) == 1 :378            tmp = []379        else :380            tmp = uc_pg_name.get()[uc_pg_name.get() != input.pg_to_delete()]381        uc_pg_name.set(tmp)382        print(input.pg_to_delete()[0])383        del uc_pg_dict[input.pg_to_delete()[0]]384        ui.modal_remove()385    386    @render.data_frame387    def uc_score_grid():388        if input.uc_score_pg() :389            tmp = uc_pg_dict[input.uc_score_pg()]['score']390            tmp[:, update(score_rdmt_priips_1an = rowmean([f[item] for item in list(input.uc_score_critere_rdmt_priips_1an())]))]391            tmp[:, update(score_rdmt_priips_ddr = rowmean([f[item] for item in list(input.uc_score_critere_rdmt_priips_ddr())]))]392            tmp[:, update(score_frais = rowmean([f[item] for item in list(input.uc_score_critere_frais())]))] 393            tmp[:, update(score_riy = rowmean([f[item] for item in list(input.uc_score_critere_riy())]))]394            tmp[:, update(sc_VFM = rowmean(f.score_rdmt_priips_1an, f.score_rdmt_priips_ddr, f.score_frais, f.score_riy ))]395            uc_pg_dict[input.uc_score_pg()]['score'] = tmp396 397            # col = list(tmp.to_pandas().select_dtypes(include = 'float64').columns)398            col = list(['objectif', 'sri', 'devise',399                        'sc_VFM', 'score_rdmt_priips_1an', 'score_rdmt_priips_ddr', 'score_frais', 'score_riy',400                        'rdmt_tension_1an','rdmt_defa_1an','rdmt_inter_1an','rdmt_favo_1an',401                        'rdmt_tension_ddr','rdmt_defa_ddr','rdmt_inter_ddr','rdmt_favo_ddr',402                        'uc_frais_entree', 'uc_frais_gestion', 'uc_frais_transaction', 'uc_frais_sortie', 403                        'riy_1an', 'riy_ddr', 404                        'sfdr'])405            406            ui.update_selectize('uc_bubble_abcisse', choices = col)407            ui.update_selectize('uc_bubble_ordonnée', choices = col )408            ui.update_selectize('uc_bubble_taille', choices = col )409 410            return render.DataGrid(data = tmp, filters = True, height='70vh')411        else :412            return 413        uc_score_grid414    415    @output416    @render_widget417    def uc_visu_histo () :418        if input.uc_visu_pg() :419            tmp = uc_pg_dict[input.uc_visu_pg()]['score']420            dt_plot = tmp.to_pandas()421           422            423            if input.uc_visu_boutton() == 'hist' : 424                dt_plot_hist = pd.melt(dt_plot, 425                              id_vars = ['isin'],426                              var_name = 'type' ,427                              value_vars = ['sc_VFM', 'score_rdmt_priips_1an', 'score_rdmt_priips_ddr', 'score_frais', 'score_riy'], 428                              value_name = 'score' )429                430                fig = px.histogram(dt_plot_hist, x = "score", color= 'type', marginal = 'rug',  range_x=[0,10], hover_data=['isin', 'type', 'score'],431                                barmode = 'group',432                                opacity = 0.6,433                                nbins = 20)434            435            if input.uc_visu_boutton() == 'densite' :436                dt_plot_densite = dt_plot[['isin','sc_VFM', 'score_rdmt_priips_1an', 'score_rdmt_priips_ddr', 'score_frais', 'score_riy']]437                #isin = dt_plot_densite['isin']438                hist_data = [np.array(dt_plot['sc_VFM'].dropna()), np.array(dt_plot['score_rdmt_priips_1an'].dropna()), 439                             np.array(dt_plot['score_rdmt_priips_ddr'].dropna()), np.array(dt_plot['score_frais'].dropna()), 440                             np.array(dt_plot['score_riy'].dropna())]441                labels = ['sc_VFM', 'score_rdmt_priips_1an', 'score_rdmt_priips_ddr', 'score_frais', 'score_riy']442                fig = ff.create_distplot(hist_data, 443                                         group_labels= labels,444                                         #rug_text = isin, 445                                         show_hist=False)446        447        return fig448    449    @output450    @render_widget451    def uc_visu_bubble () :452        if input.uc_visu_pg() :453            tmp = uc_pg_dict[input.uc_visu_pg()]['score']454            dt_plot = tmp.to_pandas()455 456            457            458 459            fig = px.scatter(dt_plot, x=input.uc_bubble_abcisse(), y=input.uc_bubble_ordonnée(),460	                        # size=461                            color= input.uc_bubble_taille(),462                            hover_name="isin", size_max=15)463        464        return fig465    466    @output467    @render_widget468    def uc_visu_box () :469        if input.uc_visu_pg() :470            tmp = uc_pg_dict[input.uc_visu_pg()]['score']471            dt_plot = tmp.to_pandas()472            473            trace_rdmt_1an = np.array(dt_plot['score_rdmt_priips_1an'])474            trace_rdmt_ddr = np.array(dt_plot['score_rdmt_priips_ddr'])475 476            fig = px.box(dt_plot, y=input.uc_visu_boutton_box(), points="all", hover_name= 'isin')477 478        479        return fig480 481app = App(app_ui, server)