import streamlit as st import pandas as pd import plotly.express as px #import bar_chart_race as bcr from raceplotly.plots import barplot # Configuration and Constants COUNTRY_MAPPING = { "Italy, San Marino and the Holy See": "Italy", "France and Monaco": "France", "Belgium and Luxembourg": "Belgium", "China (mainland)": "China", "United States of America": "United States", "United Kingdom of Great Britain and Northern Ireland": "United Kingdom", "Spain and Andorra": "Spain" } DEFAULT_COUNTRIES = ["Italy", "France", "Germany"] YEAR_RANGE = (2000, 2020) # Data Loading and Processing Functions @st.cache_data def load_data(sheet_name): df = pd.read_excel("dati/fossilco2emission.xlsx", sheet_name=sheet_name) df_mapped = df.copy() df_mapped['Country'] = df_mapped['Country'].replace(COUNTRY_MAPPING) year_cols = list(range(YEAR_RANGE[0], YEAR_RANGE[1] + 1)) selected_cols = ['Country'] + year_cols return df_mapped[selected_cols].copy() def process_data_for_line_plot(df, selected_countries, year_range): mask = df['Country'].isin(selected_countries) filtered_df = df[mask] df_melted = filtered_df.melt( id_vars=['Country'], value_vars=range(year_range[0], year_range[1] + 1), var_name='Year', value_name='Emissions' ) df_melted['Year'] = pd.to_numeric(df_melted['Year']) return df_melted # Visualization Functions def create_line_plot(data): fig = px.line( data, x='Year', y='Emissions', color='Country', title='CO2 Emissions Over Time', labels={'Emissions': 'CO2 Emissions per Capita (Mton)'}, hover_data={'Year': True, 'Emissions': ':.2f'} ) fig.update_layout(height=600, hovermode='x unified') return fig def create_animated_choropleth(data, start_year, end_year): df_map = data.melt( id_vars=['Country'], value_vars=range(start_year, end_year + 1), var_name='Year', value_name='Emissions' ) fig_map = px.choropleth( df_map, locations='Country', locationmode='country names', color='Emissions', animation_frame='Year', title='CO2 Emissions per Capita Over Time', color_continuous_scale='Reds', range_color=[0, df_map['Emissions'].quantile(0.95)], labels={'Emissions': 'CO2 Emissions per Capita (Mton)'} ) fig_map.update_layout( height=600, margin=dict(l=0, r=0, t=30, b=0), updatemenus=[{ 'type': 'buttons', 'showactive': False, 'buttons': [ dict(label='Play', method='animate', args=[None, {'frame': {'duration': 500, 'redraw': True}, 'fromcurrent': True}]), dict(label='Pause', method='animate', args=[[None], {'frame': {'duration': 0, 'redraw': False}, 'mode': 'immediate', 'transition': {'duration': 0}}]) ] }] ) return fig_map def create_race_plot(df, year_range): # Prepare data for race plot # Convert year columns to rows for raceplotly format df_race = df.melt( id_vars=['Country'], value_vars=range(year_range[0], year_range[1] + 1), var_name='Year', value_name='Emissions' ) # Create the race plot race_plot = barplot( df_race, item_column='Country', value_column='Emissions', time_column='Year', top_entries=10, ) # Plot with custom settings fig = race_plot.plot( title='Top 10 Countries by CO2 Emissions', orientation='horizontal', item_label='Country', value_label='CO2 Emissions (Mton)', time_label='Year: ', frame_duration=800 ) # fig.update_layout( # height=700, # Make plot taller # font=dict(size=12), # Increase base font size # title_font_size=20, # Larger title # xaxis_title_font_size=16, # Larger axis titles # yaxis_title_font_size=16, # yaxis_tickfont_size=14, # Larger tick labels # xaxis_tickfont_size=14 # ) return fig # Main App Function def main(): st.set_page_config(page_title="CO2 Emissions Dashboard", layout="wide") st.title("Global CO2 Emissions Dashboard") # Load Data df1 = load_data("fossil_CO2_per_capita_by_countr") df = load_data("fossil_CO2_totals_by_country") df = df[df['Country'] != 'International Shipping'] df2 = df.copy()[:210] # Sidebar Controls #st.sidebar.header("Controls") #st.sidebar.markdown("---") st.sidebar.image("dati\SIAM-logo.jpg", width=150) visualization_type = st.sidebar.radio( "Choose Visualization", ["Time Series Plot", "Animated World Map", "Bar Chart Race"] ) # Year range selector (common to both visualizations) year_range = st.sidebar.slider( "Select Year Range", min_value=YEAR_RANGE[0], max_value=YEAR_RANGE[1], value=YEAR_RANGE ) # Conditional controls and display if visualization_type == "Time Series Plot": st.subheader("CO2 Emissions Time Series") # Show country selector only for time series countries = df1['Country'].unique().tolist() selected_countries = st.sidebar.multiselect( "Select countries to compare", options=countries, default=DEFAULT_COUNTRIES ) # Process and display time series plot df_processed = process_data_for_line_plot(df1, selected_countries, year_range) fig = create_line_plot(df_processed) st.plotly_chart(fig, use_container_width=True) elif visualization_type == "Animated World Map": st.subheader("Global Emissions Map (Animated)") fig_map = create_animated_choropleth(df1, year_range[0], year_range[1]) st.plotly_chart(fig_map, use_container_width=True) else: st.subheader("Top 10 CO2 Emitters Race") fig_race = create_race_plot(df2, year_range) st.plotly_chart(fig_race, use_container_width=True) st.sidebar.markdown("---") st.sidebar.markdown(""" GRUPPO 5 (EMANUELA, FULVIO, MARCO, TINSAE) """) if __name__ == "__main__": main()