Code Python de l'enquête

# 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()