# Librairies pour faires des requêtes HTTP
importrequestsimporturllib# Librairie pour lire et écrire des fichiers CSV
importpandasaspd# Librairie pour afficher en barre de progression sur une boucle
fromtqdmimporttqdm# Librairies pour afficher des graphiques sous format html
importplotly.expressaspximportplotly.graph_objectsasgoimportnumpyasnp# Désactiver les warnings
importwarningswarnings.filterwarnings('ignore')
# Fonction pour faire des requêtes à l'API
defapi_request(url):user_name='praillard'api_key='1Gaqals641cOlr80cL50r7h0p176G00Lrq6b3D0lc6i0c9EnpatS'headers={"HTTP_ACCEPT":"application/json"}response=requests.get(url,auth=(user_name,api_key),headers=headers)ifresponse.status_code==200:try:df=pd.json_normalize(response.json())except:df=pd.DataFrame()returndfelse:returnpd.DataFrame()# Fonction pour récupérer les noms des pays
defget_all_country_names():url='https://api.footprintnetwork.org/v1/countries'df_country=api_request(url)returndf_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)
defdata_all_years():country_codes=list(get_all_country_names()['countryCode'])df_total=pd.DataFrame()forcodeintqdm(country_codes):ifcode!="all":url=f" https://api.footprintnetwork.org/v1/data/{code}/all"df_inter=api_request(url)df_total=pd.concat([df_total,df_inter])returndf_totaldf=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
deffig_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=lambdax: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=lambdax:f"{round(x,2)}%"ifx>8elseNonedf_score["perctext"]=df_score["percentage"].apply(f_label)f_round=lambdax: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
defovershoot_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(lambdax:max(1,x))*365df_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")foriinrange(len(df_overshoot)):ifdf_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"
defextract_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)returndf_earths# Extraction des données pour une liste de labels de la colonne "record"
defextract_vars(l_vars,data_path="all_data.csv"):n=len(l_vars)df_vars=extract_var(var=l_vars[0],data_path=data_path)foriinrange(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")returndf_vars
# Carte interactive du jour du dépassement
defovershoot_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}")forframeinfig.frames:fortraceinframe.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
defmark_first_last_years(group):iflen(group)>1:group['text_year']=Nonegroup.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']returngroup# Scatter plot de la corrélation entre le développement et l'empreinte écologique pour les BRICS
defovershoot_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']=Nonedf_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
defovershoot_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
defovershoot_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
defovershoot_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
defrunQuery(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=[]iflen(output)==0:return"Pas de données disponibles pour ce Ngram."else:fornuminrange(len(output)):return_data.append((output[num]['ngram'],output[num]['timeseries']))values=return_data[0][1]dates=[yearforyearinrange(start_year,end_year+1)]df=pd.DataFrame({"date":dates,"value":values})df.value=df.value/df.value.max()returndf
# Figure de la popularité relative du Jour du Dépassement dans les recherches Google NGram
defovershoot_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
defovershoot_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"]*100df_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}%")forframeinfig.frames:fortraceinframe.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()