Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,205 +1,205 @@
|
|
1 |
-
import streamlit as st
|
2 |
-
import pandas as pd
|
3 |
-
import plotly.express as px
|
4 |
-
#import bar_chart_race as bcr
|
5 |
-
from raceplotly.plots import barplot
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
# Configuration and Constants
|
10 |
-
COUNTRY_MAPPING = {
|
11 |
-
"Italy, San Marino and the Holy See": "Italy",
|
12 |
-
"France and Monaco": "France",
|
13 |
-
"Belgium and Luxembourg": "Belgium",
|
14 |
-
"China (mainland)": "China",
|
15 |
-
"United States of America": "United States",
|
16 |
-
"United Kingdom of Great Britain and Northern Ireland": "United Kingdom",
|
17 |
-
"Spain and Andorra": "Spain"
|
18 |
-
}
|
19 |
-
|
20 |
-
DEFAULT_COUNTRIES = ["Italy", "France", "Germany"]
|
21 |
-
YEAR_RANGE = (2000, 2020)
|
22 |
-
|
23 |
-
# Data Loading and Processing Functions
|
24 |
-
@st.cache_data
|
25 |
-
def load_data(sheet_name):
|
26 |
-
df = pd.read_excel("dati/fossilco2emission.xlsx", sheet_name=sheet_name)
|
27 |
-
df_mapped = df.copy()
|
28 |
-
df_mapped['Country'] = df_mapped['Country'].replace(COUNTRY_MAPPING)
|
29 |
-
|
30 |
-
year_cols = list(range(YEAR_RANGE[0], YEAR_RANGE[1] + 1))
|
31 |
-
selected_cols = ['Country'] + year_cols
|
32 |
-
return df_mapped[selected_cols].copy()
|
33 |
-
|
34 |
-
def process_data_for_line_plot(df, selected_countries, year_range):
|
35 |
-
mask = df['Country'].isin(selected_countries)
|
36 |
-
filtered_df = df[mask]
|
37 |
-
|
38 |
-
df_melted = filtered_df.melt(
|
39 |
-
id_vars=['Country'],
|
40 |
-
value_vars=range(year_range[0], year_range[1] + 1),
|
41 |
-
var_name='Year',
|
42 |
-
value_name='Emissions'
|
43 |
-
)
|
44 |
-
df_melted['Year'] = pd.to_numeric(df_melted['Year'])
|
45 |
-
return df_melted
|
46 |
-
|
47 |
-
# Visualization Functions
|
48 |
-
def create_line_plot(data):
|
49 |
-
fig = px.line(
|
50 |
-
data,
|
51 |
-
x='Year',
|
52 |
-
y='Emissions',
|
53 |
-
color='Country',
|
54 |
-
title='CO2 Emissions Over Time',
|
55 |
-
labels={'Emissions': 'CO2 Emissions per Capita (Mton)'},
|
56 |
-
hover_data={'Year': True, 'Emissions': ':.2f'}
|
57 |
-
)
|
58 |
-
fig.update_layout(height=600, hovermode='x unified')
|
59 |
-
return fig
|
60 |
-
|
61 |
-
def create_animated_choropleth(data, start_year, end_year):
|
62 |
-
df_map = data.melt(
|
63 |
-
id_vars=['Country'],
|
64 |
-
value_vars=range(start_year, end_year + 1),
|
65 |
-
var_name='Year',
|
66 |
-
value_name='Emissions'
|
67 |
-
)
|
68 |
-
|
69 |
-
fig_map = px.choropleth(
|
70 |
-
df_map,
|
71 |
-
locations='Country',
|
72 |
-
locationmode='country names',
|
73 |
-
color='Emissions',
|
74 |
-
animation_frame='Year',
|
75 |
-
title='CO2 Emissions per Capita Over Time',
|
76 |
-
color_continuous_scale='Reds',
|
77 |
-
range_color=[0, df_map['Emissions'].quantile(0.95)],
|
78 |
-
labels={'Emissions': 'CO2 Emissions per Capita (Mton)'}
|
79 |
-
)
|
80 |
-
|
81 |
-
fig_map.update_layout(
|
82 |
-
height=600,
|
83 |
-
margin=dict(l=0, r=0, t=30, b=0),
|
84 |
-
updatemenus=[{
|
85 |
-
'type': 'buttons',
|
86 |
-
'showactive': False,
|
87 |
-
'buttons': [
|
88 |
-
dict(label='Play',
|
89 |
-
method='animate',
|
90 |
-
args=[None, {'frame': {'duration': 500, 'redraw': True},
|
91 |
-
'fromcurrent': True}]),
|
92 |
-
dict(label='Pause',
|
93 |
-
method='animate',
|
94 |
-
args=[[None], {'frame': {'duration': 0, 'redraw': False},
|
95 |
-
'mode': 'immediate',
|
96 |
-
'transition': {'duration': 0}}])
|
97 |
-
]
|
98 |
-
}]
|
99 |
-
)
|
100 |
-
return fig_map
|
101 |
-
|
102 |
-
|
103 |
-
def create_race_plot(df, year_range):
|
104 |
-
# Prepare data for race plot
|
105 |
-
# Convert year columns to rows for raceplotly format
|
106 |
-
df_race = df.melt(
|
107 |
-
id_vars=['Country'],
|
108 |
-
value_vars=range(year_range[0], year_range[1] + 1),
|
109 |
-
var_name='Year',
|
110 |
-
value_name='Emissions'
|
111 |
-
)
|
112 |
-
|
113 |
-
# Create the race plot
|
114 |
-
race_plot = barplot(
|
115 |
-
df_race,
|
116 |
-
item_column='Country',
|
117 |
-
value_column='Emissions',
|
118 |
-
time_column='Year',
|
119 |
-
top_entries=10,
|
120 |
-
)
|
121 |
-
|
122 |
-
# Plot with custom settings
|
123 |
-
fig = race_plot.plot(
|
124 |
-
title='Top 10 Countries by CO2 Emissions',
|
125 |
-
orientation='horizontal',
|
126 |
-
item_label='Country',
|
127 |
-
value_label='CO2 Emissions (Mton)',
|
128 |
-
time_label='Year: ',
|
129 |
-
frame_duration=800
|
130 |
-
)
|
131 |
-
|
132 |
-
# fig.update_layout(
|
133 |
-
# height=700, # Make plot taller
|
134 |
-
# font=dict(size=12), # Increase base font size
|
135 |
-
# title_font_size=20, # Larger title
|
136 |
-
# xaxis_title_font_size=16, # Larger axis titles
|
137 |
-
# yaxis_title_font_size=16,
|
138 |
-
# yaxis_tickfont_size=14, # Larger tick labels
|
139 |
-
# xaxis_tickfont_size=14
|
140 |
-
# )
|
141 |
-
|
142 |
-
return fig
|
143 |
-
|
144 |
-
|
145 |
-
# Main App Function
|
146 |
-
def main():
|
147 |
-
st.set_page_config(page_title="CO2 Emissions Dashboard", layout="wide")
|
148 |
-
st.title("Global CO2 Emissions Dashboard")
|
149 |
-
|
150 |
-
# Load Data
|
151 |
-
df1 = load_data("fossil_CO2_per_capita_by_countr")
|
152 |
-
df = load_data("fossil_CO2_totals_by_country")
|
153 |
-
df = df[df['Country'] != 'International Shipping']
|
154 |
-
df2 = df.copy()[:210]
|
155 |
-
|
156 |
-
# Sidebar Controls
|
157 |
-
#st.sidebar.header("Controls")
|
158 |
-
|
159 |
-
#st.sidebar.markdown("---")
|
160 |
-
st.sidebar.image("dati
|
161 |
-
|
162 |
-
visualization_type = st.sidebar.radio(
|
163 |
-
"Choose Visualization",
|
164 |
-
["Time Series Plot", "Animated World Map", "Bar Chart Race"]
|
165 |
-
)
|
166 |
-
|
167 |
-
# Year range selector (common to both visualizations)
|
168 |
-
year_range = st.sidebar.slider(
|
169 |
-
"Select Year Range",
|
170 |
-
min_value=YEAR_RANGE[0],
|
171 |
-
max_value=YEAR_RANGE[1],
|
172 |
-
value=YEAR_RANGE
|
173 |
-
)
|
174 |
-
|
175 |
-
# Conditional controls and display
|
176 |
-
if visualization_type == "Time Series Plot":
|
177 |
-
st.subheader("CO2 Emissions Time Series")
|
178 |
-
|
179 |
-
# Show country selector only for time series
|
180 |
-
countries = df1['Country'].unique().tolist()
|
181 |
-
selected_countries = st.sidebar.multiselect(
|
182 |
-
"Select countries to compare",
|
183 |
-
options=countries,
|
184 |
-
default=DEFAULT_COUNTRIES
|
185 |
-
)
|
186 |
-
|
187 |
-
# Process and display time series plot
|
188 |
-
df_processed = process_data_for_line_plot(df1, selected_countries, year_range)
|
189 |
-
fig = create_line_plot(df_processed)
|
190 |
-
st.plotly_chart(fig, use_container_width=True)
|
191 |
-
|
192 |
-
elif visualization_type == "Animated World Map":
|
193 |
-
st.subheader("Global Emissions Map (Animated)")
|
194 |
-
fig_map = create_animated_choropleth(df1, year_range[0], year_range[1])
|
195 |
-
st.plotly_chart(fig_map, use_container_width=True)
|
196 |
-
else:
|
197 |
-
st.subheader("Top 10 CO2 Emitters Race")
|
198 |
-
fig_race = create_race_plot(df2, year_range)
|
199 |
-
st.plotly_chart(fig_race, use_container_width=True)
|
200 |
-
|
201 |
-
st.sidebar.markdown("---")
|
202 |
-
st.sidebar.markdown(""" GRUPPO 5 (EMANUELA, FULVIO, MARCO, TINSAE) """)
|
203 |
-
|
204 |
-
if __name__ == "__main__":
|
205 |
-
main()
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
import plotly.express as px
|
4 |
+
#import bar_chart_race as bcr
|
5 |
+
from raceplotly.plots import barplot
|
6 |
+
|
7 |
+
|
8 |
+
|
9 |
+
# Configuration and Constants
|
10 |
+
COUNTRY_MAPPING = {
|
11 |
+
"Italy, San Marino and the Holy See": "Italy",
|
12 |
+
"France and Monaco": "France",
|
13 |
+
"Belgium and Luxembourg": "Belgium",
|
14 |
+
"China (mainland)": "China",
|
15 |
+
"United States of America": "United States",
|
16 |
+
"United Kingdom of Great Britain and Northern Ireland": "United Kingdom",
|
17 |
+
"Spain and Andorra": "Spain"
|
18 |
+
}
|
19 |
+
|
20 |
+
DEFAULT_COUNTRIES = ["Italy", "France", "Germany"]
|
21 |
+
YEAR_RANGE = (2000, 2020)
|
22 |
+
|
23 |
+
# Data Loading and Processing Functions
|
24 |
+
@st.cache_data
|
25 |
+
def load_data(sheet_name):
|
26 |
+
df = pd.read_excel("dati/fossilco2emission.xlsx", sheet_name=sheet_name)
|
27 |
+
df_mapped = df.copy()
|
28 |
+
df_mapped['Country'] = df_mapped['Country'].replace(COUNTRY_MAPPING)
|
29 |
+
|
30 |
+
year_cols = list(range(YEAR_RANGE[0], YEAR_RANGE[1] + 1))
|
31 |
+
selected_cols = ['Country'] + year_cols
|
32 |
+
return df_mapped[selected_cols].copy()
|
33 |
+
|
34 |
+
def process_data_for_line_plot(df, selected_countries, year_range):
|
35 |
+
mask = df['Country'].isin(selected_countries)
|
36 |
+
filtered_df = df[mask]
|
37 |
+
|
38 |
+
df_melted = filtered_df.melt(
|
39 |
+
id_vars=['Country'],
|
40 |
+
value_vars=range(year_range[0], year_range[1] + 1),
|
41 |
+
var_name='Year',
|
42 |
+
value_name='Emissions'
|
43 |
+
)
|
44 |
+
df_melted['Year'] = pd.to_numeric(df_melted['Year'])
|
45 |
+
return df_melted
|
46 |
+
|
47 |
+
# Visualization Functions
|
48 |
+
def create_line_plot(data):
|
49 |
+
fig = px.line(
|
50 |
+
data,
|
51 |
+
x='Year',
|
52 |
+
y='Emissions',
|
53 |
+
color='Country',
|
54 |
+
title='CO2 Emissions Over Time',
|
55 |
+
labels={'Emissions': 'CO2 Emissions per Capita (Mton)'},
|
56 |
+
hover_data={'Year': True, 'Emissions': ':.2f'}
|
57 |
+
)
|
58 |
+
fig.update_layout(height=600, hovermode='x unified')
|
59 |
+
return fig
|
60 |
+
|
61 |
+
def create_animated_choropleth(data, start_year, end_year):
|
62 |
+
df_map = data.melt(
|
63 |
+
id_vars=['Country'],
|
64 |
+
value_vars=range(start_year, end_year + 1),
|
65 |
+
var_name='Year',
|
66 |
+
value_name='Emissions'
|
67 |
+
)
|
68 |
+
|
69 |
+
fig_map = px.choropleth(
|
70 |
+
df_map,
|
71 |
+
locations='Country',
|
72 |
+
locationmode='country names',
|
73 |
+
color='Emissions',
|
74 |
+
animation_frame='Year',
|
75 |
+
title='CO2 Emissions per Capita Over Time',
|
76 |
+
color_continuous_scale='Reds',
|
77 |
+
range_color=[0, df_map['Emissions'].quantile(0.95)],
|
78 |
+
labels={'Emissions': 'CO2 Emissions per Capita (Mton)'}
|
79 |
+
)
|
80 |
+
|
81 |
+
fig_map.update_layout(
|
82 |
+
height=600,
|
83 |
+
margin=dict(l=0, r=0, t=30, b=0),
|
84 |
+
updatemenus=[{
|
85 |
+
'type': 'buttons',
|
86 |
+
'showactive': False,
|
87 |
+
'buttons': [
|
88 |
+
dict(label='Play',
|
89 |
+
method='animate',
|
90 |
+
args=[None, {'frame': {'duration': 500, 'redraw': True},
|
91 |
+
'fromcurrent': True}]),
|
92 |
+
dict(label='Pause',
|
93 |
+
method='animate',
|
94 |
+
args=[[None], {'frame': {'duration': 0, 'redraw': False},
|
95 |
+
'mode': 'immediate',
|
96 |
+
'transition': {'duration': 0}}])
|
97 |
+
]
|
98 |
+
}]
|
99 |
+
)
|
100 |
+
return fig_map
|
101 |
+
|
102 |
+
|
103 |
+
def create_race_plot(df, year_range):
|
104 |
+
# Prepare data for race plot
|
105 |
+
# Convert year columns to rows for raceplotly format
|
106 |
+
df_race = df.melt(
|
107 |
+
id_vars=['Country'],
|
108 |
+
value_vars=range(year_range[0], year_range[1] + 1),
|
109 |
+
var_name='Year',
|
110 |
+
value_name='Emissions'
|
111 |
+
)
|
112 |
+
|
113 |
+
# Create the race plot
|
114 |
+
race_plot = barplot(
|
115 |
+
df_race,
|
116 |
+
item_column='Country',
|
117 |
+
value_column='Emissions',
|
118 |
+
time_column='Year',
|
119 |
+
top_entries=10,
|
120 |
+
)
|
121 |
+
|
122 |
+
# Plot with custom settings
|
123 |
+
fig = race_plot.plot(
|
124 |
+
title='Top 10 Countries by CO2 Emissions',
|
125 |
+
orientation='horizontal',
|
126 |
+
item_label='Country',
|
127 |
+
value_label='CO2 Emissions (Mton)',
|
128 |
+
time_label='Year: ',
|
129 |
+
frame_duration=800
|
130 |
+
)
|
131 |
+
|
132 |
+
# fig.update_layout(
|
133 |
+
# height=700, # Make plot taller
|
134 |
+
# font=dict(size=12), # Increase base font size
|
135 |
+
# title_font_size=20, # Larger title
|
136 |
+
# xaxis_title_font_size=16, # Larger axis titles
|
137 |
+
# yaxis_title_font_size=16,
|
138 |
+
# yaxis_tickfont_size=14, # Larger tick labels
|
139 |
+
# xaxis_tickfont_size=14
|
140 |
+
# )
|
141 |
+
|
142 |
+
return fig
|
143 |
+
|
144 |
+
|
145 |
+
# Main App Function
|
146 |
+
def main():
|
147 |
+
st.set_page_config(page_title="CO2 Emissions Dashboard", layout="wide")
|
148 |
+
st.title("Global CO2 Emissions Dashboard")
|
149 |
+
|
150 |
+
# Load Data
|
151 |
+
df1 = load_data("fossil_CO2_per_capita_by_countr")
|
152 |
+
df = load_data("fossil_CO2_totals_by_country")
|
153 |
+
df = df[df['Country'] != 'International Shipping']
|
154 |
+
df2 = df.copy()[:210]
|
155 |
+
|
156 |
+
# Sidebar Controls
|
157 |
+
#st.sidebar.header("Controls")
|
158 |
+
|
159 |
+
#st.sidebar.markdown("---")
|
160 |
+
st.sidebar.image("dati/SIAM-logo.jpg", width=150)
|
161 |
+
|
162 |
+
visualization_type = st.sidebar.radio(
|
163 |
+
"Choose Visualization",
|
164 |
+
["Time Series Plot", "Animated World Map", "Bar Chart Race"]
|
165 |
+
)
|
166 |
+
|
167 |
+
# Year range selector (common to both visualizations)
|
168 |
+
year_range = st.sidebar.slider(
|
169 |
+
"Select Year Range",
|
170 |
+
min_value=YEAR_RANGE[0],
|
171 |
+
max_value=YEAR_RANGE[1],
|
172 |
+
value=YEAR_RANGE
|
173 |
+
)
|
174 |
+
|
175 |
+
# Conditional controls and display
|
176 |
+
if visualization_type == "Time Series Plot":
|
177 |
+
st.subheader("CO2 Emissions Time Series")
|
178 |
+
|
179 |
+
# Show country selector only for time series
|
180 |
+
countries = df1['Country'].unique().tolist()
|
181 |
+
selected_countries = st.sidebar.multiselect(
|
182 |
+
"Select countries to compare",
|
183 |
+
options=countries,
|
184 |
+
default=DEFAULT_COUNTRIES
|
185 |
+
)
|
186 |
+
|
187 |
+
# Process and display time series plot
|
188 |
+
df_processed = process_data_for_line_plot(df1, selected_countries, year_range)
|
189 |
+
fig = create_line_plot(df_processed)
|
190 |
+
st.plotly_chart(fig, use_container_width=True)
|
191 |
+
|
192 |
+
elif visualization_type == "Animated World Map":
|
193 |
+
st.subheader("Global Emissions Map (Animated)")
|
194 |
+
fig_map = create_animated_choropleth(df1, year_range[0], year_range[1])
|
195 |
+
st.plotly_chart(fig_map, use_container_width=True)
|
196 |
+
else:
|
197 |
+
st.subheader("Top 10 CO2 Emitters Race")
|
198 |
+
fig_race = create_race_plot(df2, year_range)
|
199 |
+
st.plotly_chart(fig_race, use_container_width=True)
|
200 |
+
|
201 |
+
st.sidebar.markdown("---")
|
202 |
+
st.sidebar.markdown(""" GRUPPO 5 (EMANUELA, FULVIO, MARCO, TINSAE) """)
|
203 |
+
|
204 |
+
if __name__ == "__main__":
|
205 |
+
main()
|