# Librairies pour faires des requêtes HTTP import requests import urllib # Librairie pour lire et écrire des fichiers CSV import pandas as pd # Librairie pour afficher en barre de progression sur une boucle from tqdm import tqdm # Librairies pour afficher des graphiques sous format html import plotly.express as px import plotly.graph_objects as go import numpy as np # Désactiver les warnings import warnings warnings.filterwarnings('ignore') # Fonction pour faire des requêtes à l'API def api_request(url): user_name = 'praillard' api_key = '1Gaqals641cOlr80cL50r7h0p176G00Lrq6b3D0lc6i0c9EnpatS' headers = {"HTTP_ACCEPT":"application/json"} response = requests.get(url, auth=(user_name, api_key), headers=headers) if response.status_code==200: try: df = pd.json_normalize(response.json()) except: df = pd.DataFrame() return df else: return pd.DataFrame() # Fonction pour récupérer les noms des pays def get_all_country_names(): url = 'https://api.footprintnetwork.org/v1/countries' df_country = api_request(url) return df_country # Fonction pour récupérer les données pour tous les pays (et toutes les régions) # et pour toutes les années (entre 1961 et 2022) def data_all_years(): country_codes = list(get_all_country_names()['countryCode']) df_total = pd.DataFrame() for code in tqdm(country_codes): if code!="all": url = f" https://api.footprintnetwork.org/v1/data/{code}/all" df_inter = api_request(url) df_total = pd.concat([df_total, df_inter]) return df_total df = data_all_years() # Sauvegarde de la base de données sous Python df.to_csv("all_data.csv", index=False) # Figure de la répartition des scores de qualité par région def fig_quality(path="all_data.csv", code_path="iso_code.csv"): # Extraction des données de qualité df_all = pd.read_csv(path) df_code = pd.read_csv(code_path) df_code.rename(columns={'alpha-2':'isoa2', 'alpha-3':"ISO_A3"}, inplace=True) df_quality = df_all.merge(df_code, on="isoa2", how="inner") f_c = lambda x: 100 * x / float(x.sum()) df_score = df_quality.groupby(["region", "score"]).agg({"score":"count"}).groupby(level=0).apply(f_c) df_score.rename(columns={"score":"percentage"}, inplace=True) df_score = df_score.reset_index() f_label = lambda x: f"{round(x,2)}%" if x>8 else None df_score["perctext"] = df_score["percentage"].apply(f_label) f_round = lambda x: f"{round(x,2)}%" df_score["perctexthover"] = df_score["percentage"].apply(f_round) fig = px.bar(df_score, x="region", y="percentage", color="score", color_discrete_sequence=px.colors.sequential.Turbo, category_orders={"score": ["3A", "3B", "3C", "3D", "2A", "2B", "2C", "2D", "1A", "1B", "1C", "1D"]}, text="perctext", custom_data=["score", "perctexthover"]) fig.update_traces(textfont_size=12) fig.update_layout( font=dict( family="Gotham", size=12, color="black" ), xaxis=dict( title="Region", titlefont_size=16, tickfont_size=14, color="black" ), yaxis=dict( title="Percentage", titlefont_size=16, tickfont_size=14, color="black" ), legend=dict( title="Score", bgcolor='rgba(0,0,0,0)', bordercolor="White", borderwidth=1, font=dict( family="Gotham", size=16, color="black" ) ), ) fig.update_traces( marker_line_color='black', marker_line_width=1) fig.update_traces(hovertemplate="<b>%{x}</b>"+ "<br><b>%{customdata[0]}:</b> %{customdata[1]}</br>") fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor="black") fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor="black") fig.update_layout(plot_bgcolor='white', paper_bgcolor='white') fig.write_html("fig_quality.html") fig.show() fig_quality() # Figure de l'evoltion du jour du dépassement mondial def overshoot_summary(path = "all_data.csv"): # Importer les données et convertir la colonne "Earth" en date df_all = pd.read_csv(path) df_overshoot = df_all.loc[(df_all["countryName"]=='World') & (df_all["record"]=="Earths")] df_overshoot["year_frac"] = 1/df_overshoot["value"].apply(lambda x: max(1,x))*365 df_overshoot # Génération de la légende du graphe df_overshoot["date"] = pd.to_datetime(df_overshoot["year_frac"], unit='D', origin=pd.Timestamp('2022-01-01')) df_overshoot["date"] = df_overshoot["date"].dt.strftime("%B-%d") for i in range(len(df_overshoot)): if df_overshoot["value"].iloc[i] < 1: df_overshoot["date"].iloc[i] = "No Overshoot Day" # Création du bar chart fig = px.bar(df_overshoot, y="year_frac", x="year",custom_data=["date", "value"]) fig.update_layout( title="Evolution du jour du dépassement mondial", font=dict( family="Gotham", size=12, color="black" ), xaxis=dict( title="Année", titlefont_size=16, tickfont_size=14, color="black" ), yaxis=dict( title="Overshoot Day", titlefont_size=16, tickfont_size=14, color="black" ), legend=dict( title="Countries", bgcolor='rgba(0,0,0,0)', bordercolor="White", borderwidth=1, font=dict( family="Gotham", size=16, color="black" ) ), ) fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor="black") fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor="black") # fig.update_traces(mode="markers+lines") fig.update_traces(hovertemplate="<b>Année %{x}</b>"+ "<br><b>Date : </b>%{customdata[0]}</br>"+ "<b># Terres : </b>%{customdata[1]:.2f}") fig.update_layout(plot_bgcolor='white', paper_bgcolor='white') fig.update_traces(marker_color='#2b9dca', marker_line_color='black', marker_line_width=1) fig.write_html("overshoot_summary.html") fig.show() overshoot_summary() # Extraction des données pour un label de la colonne "record" def extract_var(var = "Earths", data_path="all_data.csv"): df_all = pd.read_csv(data_path) df_all_country = df_all[df_all['isoa2'].isna()==False] df_earths = df_all_country[df_all_country['record']==var] df_earths = df_earths[["countryName", "isoa2", 'value', "year"]] df_earths.rename(columns={"value":var}, inplace=True) df_earths = df_earths.sort_values(by="year", ascending=True) return df_earths # Extraction des données pour une liste de labels de la colonne "record" def extract_vars(l_vars, data_path="all_data.csv"): n = len(l_vars) df_vars = extract_var(var = l_vars[0], data_path=data_path) for i in range(1,n): df_var = extract_var(var = l_vars[i], data_path=data_path) df_vars = df_vars.merge(df_var, on = ["countryName","isoa2", "year"], how = "left") return df_vars # Carte interactive du jour du dépassement def overshoot_mapinteractive(path="all_data.csv",code_path="iso_code.csv"): # Extraction du nombre de terres pour chaque pays et chaque année df_plot = extract_var(data_path=path) # Import des codes ISO2 et ISO3 df_code = pd.read_csv(code_path) df_code.rename(columns={'alpha-2':'isoa2', 'alpha-3':"ISO_A3"}, inplace=True) df_code = df_code[['isoa2', 'ISO_A3']] # Jointure des deux dataframes car plotly a besoin des codes ISO3 df_ready = pd.merge(df_plot, df_code, on='isoa2', how='inner') df_ready = df_ready.fillna(0) # Création de la carte interactive fig = px.choropleth(df_ready, title="Overshoot Day", color="Earths", locations="ISO_A3", hover_name='countryName', color_continuous_scale=[(0, 'green'), (0.2, 'yellow'), (1, 'red')], scope='world', animation_frame="year", custom_data=["year"], range_color=(0, 5)) fig.update_geos(fitbounds="locations", visible=True, showcountries=True, countrycolor="Black", landcolor="darkgray" ) fig.update_layout( title="Overshoot Day", font=dict( family="Gotham", size=12, color="black" ) ) fig.update_traces(hovertemplate="<b>%{hovertext}</b><br>Year: %{customdata}<br>Earths: %{z}") for frame in fig.frames: for trace in frame.data: trace.hovertemplate="<b>%{hovertext}</b><br>Year: %{customdata}<br>Earths: %{z}" fig.update_layout( margin={"r":0,"t":0,"l":0,"b":0}, geo=dict( showland=True, landcolor="LightGrey", showocean=True, oceancolor="rgba(0,0,0,0)", ) ) fig.update_layout(autosize=True) fig.write_html("overshoot_mapinteractive.html") fig.show() overshoot_mapinteractive() # Fonction pour marquer les premières et dernières années sur le graphe pour chaque pays def mark_first_last_years(group): if len(group) > 1: group['text_year'] = None group.loc[group.index[0], 'text_year'] = group.loc[group.index[0], 'year'] group.loc[group.index[-1], 'text_year'] = group.loc[group.index[-1], 'year'] else: group['text_year'] = group['year'] return group # Scatter plot de la corrélation entre le développement et l'empreinte écologique pour les BRICS def overshoot_brics(path="all_data.csv"): # Extraction des données pour les BRICS l_vars = ["HDI", "Earths"] df_select = extract_vars(l_vars, data_path=path) df = df_select.loc[df_select.countryName.isin(['China', 'India', "Russian Federation", "Brazil", "South Africa"])] # Réglage de l'affichage des années sur le graphe df['text_year'] = None df_new = df.groupby('countryName').apply(mark_first_last_years) # Plotting fig = px.line(df_new, x="Earths", y="HDI", color="countryName", text="text_year", custom_data=["year","countryName"]) fig.update_traces(textposition="bottom right") fig.update_layout( title="Corrélation entre le développement "+ "et l'empreinte écologique pour les BRICS", font=dict( family="Gotham", size=12, color="black" ), xaxis=dict( title="# Earths", titlefont_size=16, tickfont_size=14, color="black" ), yaxis=dict( title="HDI", titlefont_size=16, tickfont_size=14, color="black" ), legend=dict( title="Countries", bgcolor='rgba(0,0,0,0)', bordercolor="White", borderwidth=1, font=dict( family="Gotham", size=16, color="black" ) ), ) fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor="black") fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor="black") # fig.update_traces(mode="markers+lines") fig.update_traces(hovertemplate="<b>Country:</b> %{customdata[1]}"+ "<br><b>Year:</b> %{customdata[0]}<br>"+ "<b>Earths:</b> %{x:.2f}"+ "<br><b>HDI:</b> %{y:.2f}<br>") fig.update_layout(plot_bgcolor='white', paper_bgcolor='white') fig.write_html("overshoot_brics.html") fig.show() overshoot_brics() # Scatter plot de la visualisation par pays et par région de l'emprunte écologique en fonction du développement humain def overshoot_workshdi(path="all_data.csv", code_path="iso_code.csv"): # Extraction des données pour les tous les pays l_vars = ["HDI", "Earths"] df_select = extract_vars(l_vars, data_path=path) df_code = pd.read_csv(code_path) df_code.rename(columns={'alpha-2':'isoa2', 'alpha-3':"ISO_A3"}, inplace=True) df_g3 = pd.merge(df_select, df_code, on='isoa2', how='inner') df_g3 = df_g3.loc[df_g3.year==2021] fig = px.scatter(df_g3, x="Earths", y="HDI", color="region", custom_data=["countryName", "region"]) fig.update_layout( title="Visualisation par pays et par région de "+ "l'emprunte écologique en fonction du développement humain", font=dict( family="Gotham", size=12, color="black" ), xaxis=dict( title="# Earths", titlefont_size=16, tickfont_size=14, color="black" ), yaxis=dict( title="HDI", titlefont_size=16, tickfont_size=14, color="black" ), legend=dict( title="Region", bgcolor='rgba(0,0,0,0)', bordercolor="White", borderwidth=1, font=dict( family="Gotham", size=16, color="black" ) ), ) fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor="black") fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor="black") # fig.update_traces(mode="markers+lines") fig.update_traces(hovertemplate="<b>Country:</b> %{customdata[0]}"+ "<br><b>Region:</b> %{customdata[1]}<br>"+ "<b>Earths:</b> %{x:.2f}"+ "<br><b>HDI:</b> %{y:.2f}<br>") fig.update_layout(plot_bgcolor='white', paper_bgcolor='white') fig.update_xaxes(range = [0,5]) fig.update_yaxes(range = [0.2,1]) fig.write_html("overshoot_workshdi.html") fig.show() overshoot_workshdi() # Visualisation de la distribution des empruntes écologiques par région du monde def overshoot_distcontinent(path="all_data.csv", code_path="iso_code.csv"): l_vars = ["HDI", "Earths"] df_select = extract_vars(l_vars,data_path=path) df_code = pd.read_csv(code_path) df_code.rename(columns={'alpha-2':'isoa2', 'alpha-3':"ISO_A3"}, inplace=True) df_g4 = pd.merge(df_select, df_code, on='isoa2', how='inner') df_g4 = df_g4.loc[df_g4.year==2021] fig = go.Figure() fig = px.strip(df_g4, x='region', y='Earths', color="region",custom_data=["countryName"]) fig.update_layout( title="Distribution des empruntes écologiques par région du monde", font=dict( family="Gotham", size=12, color="black" ), xaxis=dict( title="Region", titlefont_size=16, tickfont_size=14, color="black" ), yaxis=dict( title="# Earths", titlefont_size=16, tickfont_size=14, color="black" ), legend=dict( title="Region", bgcolor='rgba(0,0,0,0)', bordercolor="White", borderwidth=1, font=dict( family="Gotham", size=16, color="black" ) ), ) fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor="black") fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor="black") fig.update_layout(plot_bgcolor='white', paper_bgcolor='white') fig.update_yaxes(range = [0,5.5]) fig.update_traces(hovertemplate="<b>Country:</b> %{customdata[0]}"+ "<br><b>Earths:</b> %{y:.2f}<br>") # fig.update_yaxes(range = [0.2,1]) fig.write_html("overshoot_distcontinent.html") fig.show() overshoot_distcontinent() # Figure de la popularité du Jour du Dépassement dans les recherches Google def overshoot_googletrends(path="overshoot_day_googletrends.csv"): # Importer les données sur les recherches Google Trends df_trends = pd.read_csv(path, skiprows=1) fig = px.area(df_trends, x="Mois", y="Earth Overshoot Day: (Dans tous les pays)", color_discrete_sequence=['#2b9dca']) fig.update_layout( title="Popularité du Jour du Dépassement "+ "dans les recherches Google", font=dict( family="Gotham", size=12, color="black" ), xaxis=dict( title="Date", titlefont_size=16, tickfont_size=14, color="black" ), yaxis=dict( title="Popularité relative", titlefont_size=16, tickfont_size=14, color="black" ), legend=dict( title="Countries", bgcolor='rgba(0,0,0,0)', bordercolor="White", borderwidth=1, font=dict( family="Gotham", size=16, color="black" ) ), ) fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor="black") fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor="black") fig.update_traces(hovertemplate="<b>%{x}</b>"+ "<br><b>Popularité : </b>%{y}</br>") fig.update_layout(plot_bgcolor='white', paper_bgcolor='white') fig.update_traces(marker_color='#2b9dca', marker_line_color='black', marker_line_width=1) fig.write_html("overshoot_googletrends.html") fig.show() overshoot_googletrends() # Fonction pour récupérer la popularité relative sur Google NGram pour chaque année def runQuery(query, start_year=2000, end_year=2019, corpus="en-2019", smoothing=3): # Conversion d'une chaîne de caractères en URL query = urllib.parse.quote(query) # Création de l'URL url = 'https://books.google.com/ngrams/json?content=' + query +\ '&year_start=' + str(start_year) + '&year_end=' +\ str(end_year) + '&corpus=' + str(corpus) + '&smoothing=' +\ str(smoothing) + '' # Requête HTTP à partir de l'URL response = requests.get(url) output = response.json() # Création d'une liste vide pour stocker les données return_data = [] if len(output) == 0: return "Pas de données disponibles pour ce Ngram." else: for num in range(len(output)): return_data.append((output[num]['ngram'], output[num]['timeseries']) ) values = return_data[0][1] dates = [year for year in range(start_year, end_year+1)] df = pd.DataFrame({"date":dates, "value":values}) df.value = df.value/df.value.max() return df # Figure de la popularité relative du Jour du Dépassement dans les recherches Google NGram def overshoot_googlengram(): df_ngram = runQuery("Overshoot Day") fig = px.area(df_ngram, x="date", y="value", color_discrete_sequence=['#2b9dca']) fig.update_layout( title="Popularité du Jour du Dépassement "+ "selon Google Ngram", font=dict( family="Gotham", size=12, color="black" ), xaxis=dict( title="Date", titlefont_size=16, tickfont_size=14, color="black" ), yaxis=dict( title="Popularité relative", titlefont_size=16, tickfont_size=14, color="black" ), ) fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor="black") fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor="black") fig.update_traces(hovertemplate="<b>Année %{x}</b>"+ "<br><b>Popularité : </b>%{y}</br>") fig.update_layout(plot_bgcolor='white', paper_bgcolor='white') fig.update_traces(marker_color='#2b9dca', marker_line_color='black', marker_line_width=1) fig.write_html("overshoot_googlengram.html") fig.show() overshoot_googlengram() # Carte interactive de l'évolution des défits écologiques dans le monde def overshoot_mapinteractivedeficit(path="all_data.csv",code_path="iso_code.csv"): df_code = pd.read_csv(code_path) df_code.rename(columns={'alpha-2':'isoa2', 'alpha-3':"ISO_A3"}, inplace=True) df_deficit =extract_vars(["EFConsPerCap", "BiocapPerCap"], data_path=path) df_deficit["deficit"] = df_deficit["EFConsPerCap"]/df_deficit["BiocapPerCap"]*100 df_deficit = pd.merge(df_deficit, df_code, on='isoa2', how='inner') df_deficit = df_deficit.fillna(0) fig = px.choropleth(df_deficit, title="Déficit", color="deficit", locations="ISO_A3", hover_name='countryName', color_continuous_scale=[(0, 'green'), (0.2, 'yellow'), (1, 'red')], scope='world', animation_frame="year", custom_data=["year"], range_color=(0, 500)) fig.update_geos(fitbounds="locations", visible=True, showcountries=True, countrycolor="Black", landcolor="darkgray" ) fig.update_layout( title="Déficit écologique", font=dict( family="Gotham", size=12, color="black" ) ) # Custom hover template fig.update_traces(hovertemplate="<b>%{hovertext}</b>"+ "<br>Year: %{customdata}<br>Deficit: %{z:.2f}%") for frame in fig.frames: for trace in frame.data: trace.hovertemplate="<b>%{hovertext}</b>"+ "<br>Year: %{customdata}<br>Deficit: %{z:.2f}%" fig.update_layout( margin={"r":0,"t":0,"l":0,"b":0}, geo=dict( showland=True, landcolor="LightGrey", showocean=True, oceancolor="rgba(0,0,0,0)", ) ) fig.update_layout(autosize=True) fig.write_html("overshoot_mapinteractivedeficit.html") fig.show() overshoot_mapinteractivedeficit()