diff --git a/dashboard/app.py b/dashboard/app.py index c62156b..8261fa2 100644 --- a/dashboard/app.py +++ b/dashboard/app.py @@ -11,13 +11,16 @@ from my_data.datasets import get_useful_data from my_data.computed_datasets import merge_tables, calc_degrees_pollution, calc_vdl, count_lichen, count_lichen_per_species, count_species_per_observation, count_lichen_per_lichen_id, group_lichen_by_observation_and_thallus from dashboard.charts import blank_figure, create_map, create_hist1_nb_species, create_hist2_vdl, create_hist3, create_pie_thallus, create_hist4, create_gauge_chart -from dashboard.constants import MAP_SETTINGS, BASE_COLOR_PALETTE, BODY_FONT_FAMILY, POSITIVE_GAUGE_COLOR_PALETTE, NEGATIVE_GAUGE_COLOR_PALETTE, TRANSLATIONS_EN_FR, GRID_STYLE, CARD_STYLE, MAP_STYLE, FLEX_COLUMNS_CONTAINER_STYLE +from dashboard.constants import MAP_COLOR_PALETTES, BASE_COLOR_PALETTE, BODY_FONT_FAMILY, POSITIVE_GAUGE_COLOR_PALETTE, NEGATIVE_GAUGE_COLOR_PALETTE, GRID_STYLE, CARD_STYLE, MAP_STYLE, FLEX_COLUMNS_CONTAINER_STYLE +from dashboard.utils.translations import get_translation _dash_renderer._set_react_version("18.2.0") +# Set the language (could be dynamically set based on user preference) +lang = 'fr' # Get the datasets -print("Fetching data...") +print(get_translation('fetching_data', lang)) lichen_df, merged_lichen_species_df, observation_df, table_df, tree_df = get_useful_data() @@ -50,7 +53,7 @@ # Initialize the options and selections date_range = [merged_observation_df["date_obs"].min(), datetime.now().date()] -map_column_selected = list(MAP_SETTINGS.keys())[0] +map_column_selected = list(MAP_COLOR_PALETTES.keys())[0] # Convert DataFrame to list of dictionaries @@ -105,9 +108,9 @@ def update_dashboard_map(date_range, map_column_selected, relayoutData): # Second callback to update the dashboard based on observation click @callback( - Output('gauge-chart1-artif', 'figure'), - Output('gauge-chart2-acide', 'figure'), - Output('gauge-chart3-azote', 'figure'), + Output('gauge-chart-toxitolerance', 'figure'), + Output('gauge-chart-eutrophication', 'figure'), + Output('gauge-chart-acidity', 'figure'), Output('hist3-species', 'figure'), Output('pie-thallus', 'figure'), Output('hist1-nb_species', 'figure', allow_duplicate=True), @@ -147,9 +150,9 @@ def update_dashboard_observation(clickData, date_range): observation_id_clicked = observation_clicked['observation_id'] nb_species_clicked = observation_clicked['nb_species'] vdl_clicked = observation_clicked['VDL'] - deg_artif_clicked = observation_clicked['deg_artif'] - deg_pollution_acid_clicked = observation_clicked['deg_pollution_acid'] - deg_pollution_azote_clicked = observation_clicked['deg_pollution_azote'] + deg_toxitolerance_clicked = observation_clicked['deg_toxitolerance'] + deg_acidity_clicked = observation_clicked['deg_acidity'] + deg_eutrophication_clicked = observation_clicked['deg_eutrophication'] filtered_nb_lichen_per_lichen_id_df = nb_lichen_per_lichen_id_df[ nb_lichen_per_lichen_id_df['observation_id'] == observation_id_clicked @@ -159,9 +162,9 @@ def update_dashboard_observation(clickData, date_range): grouped_lichen_by_observation_and_thallus_df['observation_id'] == observation_id_clicked ] - gauge_chart1_artif = create_gauge_chart(deg_artif_clicked, intervals=[0, 25, 50, 75, 100], color_scale=NEGATIVE_GAUGE_COLOR_PALETTE) - gauge_chart2_acide = create_gauge_chart(deg_pollution_acid_clicked, intervals=[0, 25, 50, 75, 100], color_scale=POSITIVE_GAUGE_COLOR_PALETTE) - gauge_chart3_azote = create_gauge_chart(deg_pollution_azote_clicked, intervals=[0, 25, 50, 75, 100], color_scale=NEGATIVE_GAUGE_COLOR_PALETTE) + gauge_chart_toxitolerance = create_gauge_chart(deg_toxitolerance_clicked, intervals=[0, 25, 50, 75, 100], color_scale=NEGATIVE_GAUGE_COLOR_PALETTE) + gauge_chart_acidity = create_gauge_chart(deg_acidity_clicked, intervals=[0, 25, 50, 75, 100], color_scale=POSITIVE_GAUGE_COLOR_PALETTE) + gauge_chart_eutrophication = create_gauge_chart(deg_eutrophication_clicked, intervals=[0, 25, 50, 75, 100], color_scale=NEGATIVE_GAUGE_COLOR_PALETTE) hist1_nb_species = create_hist1_nb_species(filtered_observation_df, nb_species_clicked) hist2_vdl = create_hist2_vdl(filtered_observation_df, vdl_clicked) @@ -169,7 +172,7 @@ def update_dashboard_observation(clickData, date_range): hist3_species = create_hist3(filtered_nb_lichen_per_lichen_id_df) pie_thallus = create_pie_thallus(filtered_grouped_lichen_by_observation_and_thallus_df) - return gauge_chart1_artif, gauge_chart2_acide, gauge_chart3_azote, hist3_species, pie_thallus, hist1_nb_species, hist2_vdl + return gauge_chart_toxitolerance, gauge_chart_eutrophication, gauge_chart_acidity, hist3_species, pie_thallus, hist1_nb_species, hist2_vdl ## Dashboard on species tab # Define callback to update the bar chart based on selected species @@ -180,7 +183,7 @@ def update_dashboard_observation(clickData, date_range): Output(component_id='species-image', component_property='src'), Output(component_id='acid-badge', component_property='children'), Output(component_id='eutro-badge', component_property='children'), - Output(component_id='poleo-badge', component_property='children'), + Output(component_id='toxitolerance-badge', component_property='children'), Output(component_id='species-thallus', component_property='children'), Output(component_id='species-rarity', component_property='children'), Input(component_id='species-dropdown', component_property='value'), @@ -214,20 +217,20 @@ def update_dashboard2(species_id_selected, relayoutData): species_img = species_selected['picture'] species_img_path = os.path.join(lichen_img_dir, species_img) - species_acid = species_selected['pH'] - species_eutro = species_selected['eutrophication'] - species_poleo = species_selected['poleotolerance'] + species_acidity = species_selected['pH'] + species_eutrophication = species_selected['eutrophication'] + species_toxitolerance = species_selected['poleotolerance'] species_thallus = species_selected['thallus'] species_rarity = species_selected['rarity'] # Translate with the dictionary - species_acid = TRANSLATIONS_EN_FR.get(species_acid, species_acid) - species_eutro = TRANSLATIONS_EN_FR.get(species_eutro, species_eutro) - species_poleo = TRANSLATIONS_EN_FR.get(species_poleo, species_poleo) - species_thallus = TRANSLATIONS_EN_FR.get(species_thallus, species_thallus) - - return fig_map, hist4_species, species_name, species_img_path, species_acid, species_eutro, species_poleo, species_thallus, species_rarity + species_acidity = get_translation(species_acidity, lang) + species_eutrophication = get_translation(species_eutrophication, lang) + species_toxitolerance = get_translation(species_toxitolerance, lang) + species_thallus = get_translation(species_thallus, lang) + species_rarity = get_translation(species_rarity, lang) + return fig_map, hist4_species, species_name, species_img_path, species_acidity, species_eutrophication, species_toxitolerance, species_thallus, species_rarity # Reusable component for title and tooltip @@ -243,6 +246,8 @@ def title_and_tooltip(title, tooltip_text): label=tooltip_text, withArrow=True, position="top", + maw="50%", # max width + style={"white-space": "normal", "word-wrap": "break-word"}, # Wrap text on multiple lines ), ], align="center", @@ -326,13 +331,16 @@ def histogram_card(title, tooltip_text, graph_id, height="330px"): ), dmc.Card( children=[ - dmc.Title("Carte des observations", order=4), + title_and_tooltip( + title=get_translation("map_title", lang), + tooltip_text=get_translation("map_tooltip", lang) + ), dmc.SegmentedControl( id="map-column-select", - value=list(MAP_SETTINGS.keys())[0], + value=list(MAP_COLOR_PALETTES.keys())[0], data=[ - {"label": MAP_SETTINGS[col]["title"], "value": col} - for col in ["nb_species_cat", "VDL_cat", "deg_pollution_acid_cat", "deg_pollution_azote_cat", "deg_artif_cat"] + {"label": get_translation(col, lang), "value": col} + for col in ["nb_species_cat", "VDL_cat", "deg_toxitolerance_cat", "deg_eutrophication_cat", "deg_acidity_cat"] ], transitionDuration=600, transitionTimingFunction="ease-in-out", @@ -362,9 +370,9 @@ def histogram_card(title, tooltip_text, graph_id, height="330px"): children=[ dmc.GridCol( gauge_card( - "% Espèces toxitolérantes", - "Pourcentage d'espèces toxitolérantes sur le site sélectionné", - "gauge-chart1-artif", + title=get_translation("toxitolerance_gauge_title", lang), + tooltip_text=get_translation("toxitolerance_gauge_tooltip", lang), + graph_id="gauge-chart-toxitolerance", ), span=4, style={"display": "flex", @@ -372,9 +380,9 @@ def histogram_card(title, tooltip_text, graph_id, height="330px"): ), dmc.GridCol( gauge_card( - "% Espèces eutrophes", - "Pourcentage d'espèces eutrophes sur le site sélectionné", - "gauge-chart3-azote", + title=get_translation("eutrophication_gauge_title", lang), + tooltip_text=get_translation("eutrophication_gauge_tooltip", lang), + graph_id="gauge-chart-eutrophication", ), span=4, style={"display": "flex", @@ -382,9 +390,9 @@ def histogram_card(title, tooltip_text, graph_id, height="330px"): ), dmc.GridCol( gauge_card( - "% Espèces acidophiles", - "Pourcentage d'espèces acidophiles sur le site sélectionné", - "gauge-chart2-acide", + title=get_translation("acidity_gauge_title", lang), + tooltip_text=get_translation("acidity_gauge_tooltip", lang), + graph_id="gauge-chart-acidity", ), span=4, style={"display": "flex", @@ -405,9 +413,9 @@ def histogram_card(title, tooltip_text, graph_id, height="330px"): span=6, children=[ histogram_card( - "Distribution du nombre d'espèces", - "Distribution du nombre d'espèces par site. Si vous cliquez sur un site sur la carte, son nombre d'espèce sera affiché en trait pointillé rouge.", - "hist1-nb_species", + title=get_translation("species_number_distribution_hist1_title", lang), + tooltip_text=get_translation("species_number_distribution_hist1_tooltip", lang), + graph_id="hist1-nb_species", ), ], ), @@ -415,9 +423,9 @@ def histogram_card(title, tooltip_text, graph_id, height="330px"): span=6, children=[ histogram_card( - "Distribution de VDL", - "Distribution des valeurs de Diversité Lichénique (VDL) sur l'ensemble des sites. Si vous cliquez sur un site sur la carte, sa VDL sera affichée en trait pointillé rouge.", - "hist2-vdl", + title=get_translation("vdl_distribution_hist2_title", lang), + tooltip_text=get_translation("vdl_distribution_hist2_tooltip", lang), + graph_id="hist2-vdl", ), ], ), @@ -425,9 +433,9 @@ def histogram_card(title, tooltip_text, graph_id, height="330px"): span=7, children=[ histogram_card( - "Espèces observées sur le site sélectionné", - "Distribution des espèces observées sur le site sélectionné", - "hist3-species", + title=get_translation("species_distribution_hist3_title", lang), + tooltip_text=get_translation("species_distribution_hist3_tooltip", lang), + graph_id="hist3-species", ), ], ), @@ -435,9 +443,9 @@ def histogram_card(title, tooltip_text, graph_id, height="330px"): span=5, children=[ histogram_card( - "Morphologie du site sélectionné", - "Distribution des thalles sur le site sélectionné", - "pie-thallus", + title=get_translation("thallus_pie_chart_title", lang), + tooltip_text=get_translation("thallus_pie_chart_tooltip", lang), + graph_id="pie-thallus", ), ], ), @@ -460,7 +468,11 @@ def histogram_card(title, tooltip_text, graph_id, height="330px"): children=[ dmc.CardSection( children=[ - dmc.Text(id="species-name", size="lg"), + dmc.Text( + id="species-name", + size="lg", + style={"fontStyle": "italic", "fontWeight": "bold"}, + ), ], withBorder=True, inheritPadding=True, @@ -468,19 +480,24 @@ def histogram_card(title, tooltip_text, graph_id, height="330px"): ), dmc.Text( children=[ - "Ce lichen ", + get_translation("species_description1", lang), + " ", dmc.Text( id="species-thallus", c="blue", style={"display": "inline"}, ), - " est ", + " ", + get_translation("species_description2", lang), + " ", dmc.Text( id="species-rarity", c="blue", style={"display": "inline"}, ), - " en milieu urbain.", + " ", + get_translation("species_description3", lang), + ".", ], mt="sm", c="dimmed", @@ -500,20 +517,20 @@ def histogram_card(title, tooltip_text, graph_id, height="330px"): [ dmc.Group( [ - "Acidité", - dmc.Badge(id="acid-badge", variant="light"), + get_translation("toxitolerance_badge", lang), + dmc.Badge(id="toxitolerance-badge", variant="light"), ] ), dmc.Group( [ - "Eutrophisation", + get_translation("eutrophication_badge", lang), dmc.Badge(id="eutro-badge", variant="light"), ] ), dmc.Group( [ - "Poléotolérance", - dmc.Badge(id="poleo-badge", variant="light"), + get_translation("acidity_badge", lang), + dmc.Badge(id="acid-badge", variant="light"), ] ), ], @@ -538,8 +555,8 @@ def histogram_card(title, tooltip_text, graph_id, height="330px"): children=[ dmc.Select( id="species-dropdown", - label="Espèce", - description="Sélectionnez une espèce pour afficher les informations", + label=get_translation("species_dropdown_label", lang), + description=get_translation("species_dropdown_description", lang), value=species_id_selected, data=species_options, clearable=False, @@ -558,8 +575,8 @@ def histogram_card(title, tooltip_text, graph_id, height="330px"): dmc.Card( children=[ title_and_tooltip( - title="Carte de présence de l'espèce sélectionnée", - tooltip_text="Carte de présence de l'espèce sélectionnée" + title=get_translation("species_presence_map_title", lang), + tooltip_text=get_translation("species_presence_map_tooltip", lang) ), dmc.Card( children=[ @@ -584,9 +601,9 @@ def histogram_card(title, tooltip_text, graph_id, height="330px"): style={"flex-basis": "40%", "flex-grow": "1"}, children=[ histogram_card( - "Espèces les plus observées", - "Distribution des espèces observées sur l'ensemble des sites", - "hist4-species", + title=get_translation("species_distribution_hist4_title", lang), + tooltip_text=get_translation("species_distribution_hist4_tooltip", lang), + graph_id="hist4-species", height="590px", ), ], @@ -644,7 +661,7 @@ def switch_theme(_, theme): dmc.styles.DATES, "https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600&display=swap" ], - title="Lichens GO" + title=get_translation("app_title", lang), ) @@ -666,14 +683,16 @@ def switch_theme(_, theme): DashIconify( icon="tabler:map-pin", height=25, - color=BASE_COLOR_PALETTE[0] + color=BASE_COLOR_PALETTE[0], ), dmc.Tooltip( - label="Cliquez sur un site pour découvrir ce que les lichens peuvent nous apprendre", + label=get_translation("observation_tab_tooltip", lang), position="right", withArrow=True, children=dmc.Title( - "Sites", order=3) + get_translation("observation_tab_title", lang), + order=3, + ), ), ], align="center", @@ -692,15 +711,17 @@ def switch_theme(_, theme): DashIconify( icon="ph:plant", height=25, - color=BASE_COLOR_PALETTE[0] + color=BASE_COLOR_PALETTE[0], ), dmc.Title( - "Espèces", order=3) + get_translation("species_tab_title", lang), + order=3, + ), ], align="bottom", ), ), - dmc.AccordionPanel(species_layout) + dmc.AccordionPanel(species_layout), ], value="species", ), diff --git a/dashboard/assets/locale/en.json b/dashboard/assets/locale/en.json new file mode 100644 index 0000000..31d14db --- /dev/null +++ b/dashboard/assets/locale/en.json @@ -0,0 +1,50 @@ +{ + "app_title": "Lichens Go Dashboard", + "observation_tab_title": "Sites", + "observation_tab_tooltip": "Click on a site to discover what lichens can teach us.", + "species_tab_title": "Species", + "map_title": "Observation Map", + "map_tooltip": "Click on a point to display observation details", + "species_number_distribution_hist1_title": "Species Count Distribution", + "species_number_distribution_hist1_tooltip": "The number of lichen species (or diversity) reflects environmental quality. Generally, more species indicate less pollution. Select a site on the map to see its position (red line) relative to other Lichens GO records (blue bars).", + "vdl_distribution_hist2_title": "Lichen Diversity Value Distribution", + "vdl_distribution_hist2_tooltip": "The LDV (lichen diversity value) measures the abundance of lichens at a site. This abundance corresponds to the number of squares in which a species is present. A high LDV suggests less pollution, but other environmental factors such as climate can also influence this index. It is therefore important to consider the ecology of the species present by looking at other indicators, such as the presence of toxitolerant species. Select a site to see its position (red line) compared to other Lichens GO records (blue bars).", + "species_distribution_hist3_title": "Observed Species", + "species_distribution_hist3_tooltip": "This chart shows the percentage of squares where each species was observed on the selected site.", + "thallus_pie_chart_title": "Thallus Type", + "thallus_pie_chart_tooltip": "This chart illustrates the number of fruticose, foliose, and crustose lichens observed at the selected site.", + "toxitolerance_gauge_title": "Toxitolerant Species (%)", + "toxitolerance_gauge_tooltip": "This indicator shows the proportion of toxitolerant species at the site. Toxitolerant species are generally tolerant to air pollution. They are mainly found in highly disturbed urban environments. Generally, the higher their proportion at a site, the more it is affected by human activities.", + "eutrophication_gauge_title": "Eutrophic Species (%)", + "eutrophication_gauge_tooltip": "This indicator shows the proportion of eutrophic species at the site. Eutrophic species are favored by pollution enriched with nitrogen nutrients, mainly related to urban traffic and rural agriculture. A high proportion of eutrophic species often indicates ecological imbalance, signaling that the site is heavily affected by this form of pollution.", + "acidity_gauge_title": "Acidophilic Species (%)", + "acidity_gauge_tooltip": "Acidophilic species are favored by acidic pollution. However, this type of pollution has practically disappeared from our cities. Therefore, currently, acidophilic species are rather indicators of an absence of eutrophic pollution.", + "species_presence_map_title": "Selected Species Presence Map", + "species_presence_map_tooltip": "This map illustrates the distribution of lichen species based on the records of Lichens GO participants.", + "species_distribution_hist4_title": "Most Observed Species", + "species_distribution_hist4_tooltip": "This chart shows the number of sites where each species was observed.", + "species_dropdown_label": "Species", + "species_dropdown_description": "Select a species to display its information", + "toxitolerance_badge": "Toxitolerance", + "acidity_badge": "Acidity", + "eutrophication_badge": "Eutrophication", + "species_description1": "This lichen", + "species_description2": "is", + "species_description3": "in urban environment", + "nb_species_cat": "Species Count", + "VDL_cat": "LDV", + "deg_toxitolerance_cat": "Toxitolerant Species (%)", + "deg_eutrophication_cat": "Eutrophic Species (%)", + "deg_acidity_cat": "Acidophilic Species (%)", + "unknown": "unknown", + "acidophilous": "acidophilic", + "neutrophilous": "neutrophilic", + "basophilous": "basophilic", + "oligotrophic": "oligotrophic", + "mesotrophic": "mesotrophic", + "eutrophic": "eutrophic", + "sensitive": "sensitive", + "intermediate": "intermediate", + "tolerant": "tolerant", + "resistant": "resistant" +} diff --git a/dashboard/assets/locale/fr.json b/dashboard/assets/locale/fr.json new file mode 100644 index 0000000..59e505b --- /dev/null +++ b/dashboard/assets/locale/fr.json @@ -0,0 +1,50 @@ +{ + "app_title": "Tableau de bord Lichens Go", + "observation_tab_title": "Sites", + "observation_tab_tooltip": "Cliquez sur un site pour découvrir ce que les lichens peuvent nous apprendre.", + "species_tab_title": "Espèces", + "map_title": "Carte des observations", + "map_tooltip": "Cliquer sur un point pour afficher les informations de l'observation", + "species_number_distribution_hist1_title": "Distribution du nombre d'espèces", + "species_number_distribution_hist1_tooltip": "Le nombre d'espèces (ou diversité) des lichens reflète la qualité de l'environnement. En règle générale, plus il y a d'espèces, moins le site est pollué. Sélectionnez un site sur la carte pour voir sa position (ligne rouge) par rapport aux autres relevés Lichens GO (barres bleues).", + "vdl_distribution_hist2_title": "Distribution de la valeur de diversité lichénique", + "vdl_distribution_hist2_tooltip": "La VDL (valeur de diversité lichénique) mesure l'abondance des lichens sur un site. Cette abondance correspond au nombre de carrés dans lesquels une espèce est présente. Une VDL élevée suggère moins de pollution, mais d'autres facteurs environnementaux comme le climat peuvent influencer cet indice. Il est donc important de considérer l'écologie des espèces présentes en s'intéressant à d'autres indicateurs, tels que la présence d'espèces toxitolérantes. Sélectionnez un site pour voir sa position (ligne rouge) par rapport aux relevés Lichens GO (barres bleues).", + "species_distribution_hist3_title": "Espèces observées", + "species_distribution_hist3_tooltip": "Ce graphique montre le pourcentage de cases où chaque espèce a été observée sur le site sélectionné.", + "thallus_pie_chart_title": "Type de thalle", + "thallus_pie_chart_tooltip": "Ce graphique illustre le nombre de lichens fruticuleux, foliacés et crustacés observés sur le site sélectionné.", + "toxitolerance_gauge_title": "Espèces toxitolérantes (%)", + "toxitolerance_gauge_tooltip": "Cet indicateur présente la proportion des espèces toxitolérantes sur le site. Les espèces toxitolérantes sont tolérantes à la pollution de l'air en général. Elles se trouvent principalement dans les environnements urbains fortement perturbés. En général, plus leur proportion sur un site est élevée, plus ce site est affecté par les activités humaines.", + "eutrophication_gauge_title": "Espèces eutrophes (%)", + "eutrophication_gauge_tooltip": "Cet indicateur présente la proportion des espèces eutrophes sur le site. Les espèces eutrophes sont favorisées par une pollution enrichie en nutriments azotés, principalement liée au trafic automobile en milieu urbain et à l'agriculture en milieu rural. Une proportion élevée d'espèces eutrophes indique souvent un déséquilibre écologique, signalant que le site est fortement affecté par cette forme de pollution.", + "acidity_gauge_title": "Espèces acidophiles (%)", + "acidity_gauge_tooltip": "Les espèces acidophiles sont favorisées par la pollution acide. Cependant, ce type de pollution a pratiquement disparu de nos villes. C'est pourquoi à l'heure actuelle, les espèces acidophiles sont plutôt indicatrices d'une absence de pollution eutrophisante.", + "species_presence_map_title": "Carte de présence de l'espèce sélectionnée", + "species_presence_map_tooltip": "Cette carte illustre la répartition des espèces de lichens sur base des relevés des participants Lichens GO.", + "species_distribution_hist4_title": "Espèces les plus observées", + "species_distribution_hist4_tooltip": "Ce graphique présente le nombre de sites où chaque espèce a été observée.", + "species_dropdown_label": "Espèce", + "species_dropdown_description": "Sélectionnez une espèce pour afficher les informations s'y rapportant", + "toxitolerance_badge": "Toxitolérance", + "acidity_badge": "Acidité", + "eutrophication_badge": "Eutrophisation", + "species_description1": "Ce lichen", + "species_description2": "est", + "species_description3": "en milieu urbain", + "nb_species_cat": "Nombre d'espèces", + "VDL_cat": "VDL", + "deg_toxitolerance_cat": "Espèces toxitolérantes (%)", + "deg_eutrophication_cat": "Espèces eutrophes (%)", + "deg_acidity_cat": "Espèces acidophiles (%)", + "unknown": "inconnu", + "acidophilous": "acidophile", + "neutrophilous": "neutrophile", + "basophilous": "basophile", + "oligotrophic": "oligotrophe", + "mesotrophic": "mésotrophe", + "eutrophic": "eutrophe", + "sensitive": "sensible", + "intermediate": "intermédiaire", + "tolerant": "tolérant", + "resistant": "résistant" +} diff --git a/dashboard/charts.py b/dashboard/charts.py index ceb952e..f969941 100644 --- a/dashboard/charts.py +++ b/dashboard/charts.py @@ -1,6 +1,6 @@ import plotly.express as px import plotly.graph_objects as go -from dashboard.constants import BASE_COLOR_PALETTE, PASTEL_COLOR_PALETTE, PLOTLY_LAYOUT, MAP_SETTINGS +from dashboard.constants import BASE_COLOR_PALETTE, PASTEL_COLOR_PALETTE, PLOTLY_LAYOUT, MAP_COLOR_PALETTES """ @@ -28,7 +28,7 @@ def create_map(filtered_df, selected_map_column, zoom, center): hover_name="date_obs", hover_data=["localisation_lat", "localisation_long"], map_style="open-street-map", - color_discrete_map=MAP_SETTINGS[selected_map_column]["color_map"], + color_discrete_map=MAP_COLOR_PALETTES[selected_map_column], ) fig_map.update_layout( diff --git a/dashboard/constants.py b/dashboard/constants.py index 99019ca..ef5bda9 100644 --- a/dashboard/constants.py +++ b/dashboard/constants.py @@ -45,33 +45,13 @@ ORIENTATIONS = list(ORIENTATIONS_MAPPING.keys()) -MAP_SETTINGS = { - "nb_species_cat": { - "title": "Nombre d'espèces", - "color_map": {'<7': 'red', '7-10': 'orange', '11-14': 'yellow', '>14': 'green'} - }, - "VDL_cat": { - "title": "VDL", - "color_map": {'<25': 'red', '25-50': 'orange', '50-75': 'yellow', '>75': 'green'} - }, - "deg_pollution_acid_cat": { - "title": "Dégré pollution acide", - "color_map": {'0-25%': 'red', '25-50%': 'orange', '50-75%': 'yellow', '75-100%': 'green'} - }, - "deg_pollution_azote_cat": { - "title": "Dégré pollution azote", - "color_map": {'0-25%': 'green', '25-50%': 'yellow', '50-75%': 'orange', '75-100%': 'red'} - }, - "deg_artif_cat": - { - "title": "Dégré artificialisation", - "color_map": {'0-25%': 'green', '25-50%': 'yellow', '50-75%': 'orange', '75-100%': 'red'} - }, - "selected_species_present": - { - "title": "Espèce sélectionnée présente", - "color_map": {True: BASE_COLOR_PALETTE[0], False: BASE_COLOR_PALETTE[-1]} - }, +MAP_COLOR_PALETTES = { + "nb_species_cat": {'<7': 'red', '7-10': 'orange', '11-14': 'yellow', '>14': 'green'}, + "VDL_cat": {'<25': 'red', '25-50': 'orange', '50-75': 'yellow', '>75': 'green'}, + "deg_acidity_cat": {'0-25%': 'red', '25-50%': 'orange', '50-75%': 'yellow', '75-100%': 'green'}, + "deg_eutrophication_cat": {'0-25%': 'green', '25-50%': 'yellow', '50-75%': 'orange', '75-100%': 'red'}, + "deg_toxitolerance_cat": {'0-25%': 'green', '25-50%': 'yellow', '50-75%': 'orange', '75-100%': 'red'}, + "selected_species_present": {True: BASE_COLOR_PALETTE[0], False: BASE_COLOR_PALETTE[-1]}, } @@ -111,17 +91,3 @@ "plot_bgcolor": "rgba(0, 0, 0, 0)", # Transparent plot background "paper_bgcolor": "rgba(0, 0, 0, 0)", # Transparent paper background } - -TRANSLATIONS_EN_FR = { - "unknown": "inconnu", - "acidophilous": "acidophile", - "neutrophilous": "neutrophile", - "basophilous": "basophile", - "oligotrophic": "oligotrophe", - "mesotrophic": "mésotrophe", - "eutrophic": "eutrophe", - "sensitive": "sensible", - "intermediate": "intermédiaire", - "tolerant": "tolérant", - "resistant": "résistant", -} diff --git a/dashboard/demo_dash.py b/dashboard/demo_dash.py deleted file mode 100644 index fc1ce9f..0000000 --- a/dashboard/demo_dash.py +++ /dev/null @@ -1,40 +0,0 @@ -from dash import Dash, html, dcc, Output, Input -import plotly.express as px -import pandas as pd - -# Source : https://discuss.streamlit.io/t/develop-a-dashboard-app-with-streamlit-using-plotly/37148/4 -# Dash version -# run with : python Dashboard/demo_dash.py - -# Load data function -def load_data(): - return pd.read_csv("https://people.sc.fsu.edu/~jburkardt/data/csv/airtravel.csv") - -# Initialize Dash app -app = Dash(__name__) - -# Load data -df = load_data() - -# Define app layout with a hidden input -app.layout = html.Div([ - html.H1("Air Travel Time Series Plot", style={'textAlign': 'center'}), - html.Div("This chart shows the number of air passengers traveled in each month from 1949 to 1960", style={'textAlign': 'center'}), - dcc.Graph(id='air-travel-graph'), - html.Div(id='dummy-div', style={'display': 'none'}) # Hidden div acting as a placeholder -]) - - -# Define callback to update graph -@app.callback( - Output('air-travel-graph', 'figure'), - Input('dummy-div', 'children') # Use the hidden div as input -) -def update_graph(value): - fig = px.line(df, x="Month", y=df.columns[1:], title="Air Passenger Travel") - return fig - - -# Run the app -if __name__ == '__main__': - app.run_server(debug=True) \ No newline at end of file diff --git a/dashboard/demo_streamlit.py b/dashboard/demo_streamlit.py deleted file mode 100644 index 91331ff..0000000 --- a/dashboard/demo_streamlit.py +++ /dev/null @@ -1,20 +0,0 @@ -import streamlit as st -import pandas as pd -import plotly.express as px - -# Source : https://discuss.streamlit.io/t/develop-a-dashboard-app-with-streamlit-using-plotly/37148/4 -# run with : streamlit run Dashboard/demo_streamlit.py - -def load_data(): - return pd.read_csv("https://people.sc.fsu.edu/~jburkardt/data/csv/airtravel.csv") - -# Load data -df = load_data() - -# Display some information -st.title("Air Travel Time Series Plot") -st.write("This chart shows the number of air passenger traveled in each month from 1949 to 1960") - -# Plotly figure -fig = px.line(df, x="Month", y=df.columns[1:], title="Air Passenger Travel") -st.plotly_chart(fig) \ No newline at end of file diff --git a/dashboard/utils/translations.py b/dashboard/utils/translations.py new file mode 100644 index 0000000..a61ef9f --- /dev/null +++ b/dashboard/utils/translations.py @@ -0,0 +1,23 @@ +import json +import os + +def load_translations(lang): + try: + parent_dir = os.path.dirname(os.path.dirname(__file__)) + file_path = os.path.join(parent_dir, 'assets', 'locale', f'{lang}.json') + with open(file_path, 'r') as file: + return json.load(file) + except FileNotFoundError: + print(f"Translation file for language '{lang}' not found.") + return {} + except json.JSONDecodeError: + print(f"Error decoding JSON from translation file for language '{lang}'.") + return {} + +def get_translation(key, lang='fr'): + try: + translations = load_translations(lang) + return translations.get(key, key) + except Exception as e: + print(f"Error getting translation for key '{key}' in language '{lang}': {e}") + return key diff --git a/dashboard/Documentation_DB.md b/my_data/Documentation_DB.md similarity index 100% rename from dashboard/Documentation_DB.md rename to my_data/Documentation_DB.md diff --git a/my_data/computed_datasets.py b/my_data/computed_datasets.py index d79195d..6615cdf 100644 --- a/my_data/computed_datasets.py +++ b/my_data/computed_datasets.py @@ -199,17 +199,16 @@ def calc_degrees_pollution(merged_table_with_nb_lichen_df, lichen_df, merged_lic merged_df = merged_df.fillna(0) # Calculate the ratio of resistant nb_lichen to total nb_lichen - merged_df['deg_artif'] = merged_df['nb_lichen_resistant'] / merged_df['nb_lichen'] - # Add a categorical column based on the number of lichen + merged_df['deg_toxitolerance'] = merged_df['nb_lichen_resistant'] / merged_df['nb_lichen'] # Calculate the degree of acid pollution - merged_df['deg_pollution_acid'] = merged_df['nb_lichen_acid'] / merged_df['nb_lichen'] + merged_df['deg_acidity'] = merged_df['nb_lichen_acid'] / merged_df['nb_lichen'] # Calculate the degree of nitrogen (azote in french) pollution - merged_df['deg_pollution_azote'] = merged_df['nb_lichen_eutrophic'] / merged_df['nb_lichen'] + merged_df['deg_eutrophication'] = merged_df['nb_lichen_eutrophic'] / merged_df['nb_lichen'] # Add categorical columns - for col in ['deg_artif', 'deg_pollution_acid', 'deg_pollution_azote']: + for col in ['deg_toxitolerance', 'deg_acidity', 'deg_eutrophication']: merged_df[col + '_cat'] = pd.cut(merged_df[col], bins=[-0.1, 0.25, 0.5, 0.75, np.inf], labels=["0-25%", "25-50%", "50-75%", "75-100%"]) return merged_df