Spaces:
Build error
Build error
import os | |
import json | |
import gradio as gr | |
import pandas as pd | |
import numpy as np | |
import plotly.express as px | |
import plotly.graph_objects as go | |
from utils import ( | |
get_continents, get_countries, get_impact_types, | |
get_country_data, get_impact_type_data, create_summary_stats | |
) | |
# Check if we're in a Space environment | |
try: | |
from space_utils import ( | |
is_space_environment, get_continents_space, get_countries_space, | |
get_impact_types_space, get_country_data_space, get_impact_data_space | |
) | |
IN_SPACE = is_space_environment() | |
print(f"[DEBUG] Space environment detected: {IN_SPACE}") | |
except ImportError: | |
IN_SPACE = False | |
print("[DEBUG] Not running in Space environment (ImportError)") | |
# Use Space-specific functions if in a Space environment | |
if IN_SPACE: | |
print("[DEBUG] Using Space-specific functions for data loading") | |
get_continents = get_continents_space | |
get_countries = get_countries_space | |
get_impact_types = get_impact_types_space | |
get_country_data = get_country_data_space | |
get_impact_type_data = get_impact_data_space | |
else: | |
print("[DEBUG] Using standard functions for data loading") | |
# Constants | |
CONTINENTS = get_continents() | |
print(f"[DEBUG] Loaded continents: {CONTINENTS}") | |
IMPACT_TYPES = get_impact_types() | |
print(f"[DEBUG] Loaded impact types: {IMPACT_TYPES}") | |
# Custom CSS | |
CUSTOM_CSS = """ | |
/* Custom CSS for IFVI Value Factors Navigator */ | |
.gradio-container { | |
font-family: 'Arial', sans-serif !important; | |
} | |
.main-header { | |
text-align: center; | |
margin-bottom: 2rem; | |
} | |
.tab-content { | |
padding: 1rem; | |
} | |
.footer { | |
text-align: center; | |
margin-top: 2rem; | |
padding-top: 1rem; | |
border-top: 1px solid #eee; | |
color: #7f8c8d; | |
font-size: 0.9rem; | |
} | |
""" | |
# Function to create value factor visualization | |
def create_visualization(data, title): | |
if not data: | |
return None | |
# Convert data to DataFrame if it's a list | |
if isinstance(data, list): | |
df = pd.DataFrame(data) | |
else: | |
# If it's already a DataFrame or another format, try to convert | |
df = pd.DataFrame(data) | |
# Check if the DataFrame has the expected columns | |
if 'Category' in df.columns and 'ValueFactor' in df.columns: | |
# Create a bar chart | |
fig = px.bar( | |
df, | |
x='Category', | |
y='ValueFactor', | |
title=title, | |
labels={'ValueFactor': 'Value Factor (USD)', 'Category': 'Impact Category'}, | |
color='Impact' if 'Impact' in df.columns else None, | |
hover_data=['Location', 'Unit'] if all(col in df.columns for col in ['Location', 'Unit']) else None | |
) | |
fig.update_layout( | |
xaxis_title="Impact Category", | |
yaxis_title="Value Factor (USD)", | |
legend_title="Impact Type", | |
font=dict(family="Arial, sans-serif", size=12), | |
height=600 | |
) | |
return fig | |
else: | |
# Create a fallback visualization or message | |
return None | |
# Function to create data table | |
def create_data_table(data): | |
if not data: | |
return None | |
# Convert data to DataFrame if it's a list | |
if isinstance(data, list): | |
df = pd.DataFrame(data) | |
else: | |
# If it's already a DataFrame or another format, try to convert | |
df = pd.DataFrame(data) | |
return df | |
# Main app interface | |
def create_app(): | |
with gr.Blocks(title="IFVI Value Factors Navigator", theme=gr.themes.Soft(), css=CUSTOM_CSS) as app: | |
gr.Markdown("# IFVI Value Factors Navigator", elem_classes=["main-header"]) | |
gr.Markdown(""" | |
This application allows you to navigate and visualize the IFVI Value Factors dataset, | |
which provides monetary values for environmental impacts across different regions and impact types. | |
The data is organized by: | |
- Geographic regions (continents and countries) | |
- Impact types (air pollution, GHG impacts, waste, etc.) | |
Each value factor represents the monetary value (in USD) of an environmental impact. | |
""") | |
with gr.Tabs() as tabs: | |
# Tab for navigation by region | |
with gr.TabItem("Navigate by Region", elem_classes=["tab-content"]): | |
with gr.Row(): | |
with gr.Column(scale=1): | |
continent_dropdown = gr.Dropdown( | |
choices=CONTINENTS, | |
label="Select Continent", | |
info="Choose a continent to view countries" | |
) | |
country_dropdown = gr.Dropdown( | |
choices=[], | |
label="Select Country", | |
info="Choose a country to view value factors" | |
) | |
region_view_button = gr.Button("View Value Factors") | |
region_summary = gr.Markdown(label="Summary Statistics") | |
with gr.Column(scale=2): | |
region_plot = gr.Plot(label="Value Factors Visualization") | |
with gr.Row(): | |
region_table = gr.DataFrame(label="Value Factors Data") | |
# Tab for navigation by impact type | |
with gr.TabItem("Navigate by Impact Type", elem_classes=["tab-content"]): | |
with gr.Row(): | |
with gr.Column(scale=1): | |
impact_dropdown = gr.Dropdown( | |
choices=IMPACT_TYPES, | |
label="Select Impact Type", | |
info="Choose an impact type to view value factors" | |
) | |
impact_view_button = gr.Button("View Value Factors") | |
impact_summary = gr.Markdown(label="Summary Statistics") | |
with gr.Column(scale=2): | |
impact_plot = gr.Plot(label="Value Factors Visualization") | |
with gr.Row(): | |
impact_table = gr.DataFrame(label="Value Factors Data") | |
# Tab for data comparison | |
with gr.TabItem("Compare Data", elem_classes=["tab-content"]): | |
with gr.Row(): | |
with gr.Column(scale=1): | |
compare_continent1 = gr.Dropdown( | |
choices=CONTINENTS, | |
label="Select First Continent", | |
info="Choose a continent" | |
) | |
compare_country1 = gr.Dropdown( | |
choices=[], | |
label="Select First Country", | |
info="Choose a country" | |
) | |
compare_continent2 = gr.Dropdown( | |
choices=CONTINENTS, | |
label="Select Second Continent", | |
info="Choose a continent" | |
) | |
compare_country2 = gr.Dropdown( | |
choices=[], | |
label="Select Second Country", | |
info="Choose a country" | |
) | |
compare_button = gr.Button("Compare Value Factors") | |
with gr.Column(scale=2): | |
compare_plot = gr.Plot(label="Comparison Visualization") | |
with gr.Row(): | |
compare_table = gr.DataFrame(label="Comparison Data") | |
# Tab for about the dataset | |
with gr.TabItem("About the Dataset", elem_classes=["tab-content"]): | |
gr.Markdown(""" | |
## About the IFVI Value Factors Dataset | |
The Global Value Factors Database, released by the [International Foundation for Valuing Impacts](https://www.ifvi.org) | |
during UN Climate Week NYC 2023, provides a set of almost 100,000 "value factors" for converting environmental | |
impacts into monetary terms. | |
The GVFD covers 430 different environmental impacts across four main categories of impact: | |
- Air pollution | |
- Land use and conversion | |
- Waste | |
- Water pollution | |
With the exception of the value factor for greenhouse gas emissions, for which a single value factor is provided | |
($236/tco2e), the value factors are geographically stratified (in other words, the value factors are both | |
impact-specific and geolocation-specific). | |
In total, there are 268 geolocations in the dataset reflecting all the world's recognised sovereigns as well | |
as some international dependencies. In addition, one set of value factors, air pollution, provides data at | |
the level of US states. | |
### Data Structure | |
Each value factor in the dataset follows this general structure: | |
```json | |
{ | |
"Category": "String", // Environmental impact category (e.g., "PM2.5", "SOx") | |
"Location": "String", // Geographic location (e.g., "Urban", "Rural") | |
"Impact": "String", // Impact type (e.g., "Primary Health", "Visibility") | |
"Unit": "String", // Measurement unit (e.g., "/metric ton", "/ha", "/kg") | |
"ValueFactorKey": "String", // Unique identifier for the value factor | |
"ValueFactor": Number // Monetary value in USD | |
} | |
``` | |
### Value Factor Calculation | |
Value factors are calculated based on IFVI methodologies that consider: | |
- Local economic conditions | |
- Population density | |
- Environmental sensitivity | |
- Health impacts | |
- Ecosystem service valuation | |
For detailed methodology information, refer to the IFVI documentation at | |
[https://ifvi.org/methodology/environmental-topic-methodology/interim-methodologies/](https://ifvi.org/methodology/environmental-topic-methodology/interim-methodologies/). | |
""") | |
gr.Markdown(""" | |
### Created by Daniel Rosehill | |
This application is a Hugging Face Space that provides an interactive interface for exploring the IFVI Value Factors dataset. | |
Source code available on [GitHub](https://github.com/danielrosehill/ifvi-value-factors-navigator). | |
""", elem_classes=["footer"]) | |
# Event handlers | |
def update_countries(continent): | |
if not continent: | |
return gr.Dropdown(choices=[]) | |
countries = get_countries(continent) | |
return gr.Dropdown(choices=countries) | |
def view_region_data(continent, country): | |
if not continent or not country: | |
return None, None, "Please select both a continent and a country." | |
data = get_country_data(continent, country) | |
if not data: | |
return None, None, "No data available for the selected country." | |
title = f"Value Factors for {country}, {continent}" | |
plot = create_visualization(data, title) | |
table = create_data_table(data) | |
summary = create_summary_stats(data) | |
return plot, table, summary | |
def view_impact_data(impact_type): | |
if not impact_type: | |
return None, None, "Please select an impact type." | |
data = get_impact_type_data(impact_type) | |
if not data: | |
return None, None, "No data available for the selected impact type." | |
title = f"Value Factors for {impact_type}" | |
plot = create_visualization(data, title) | |
table = create_data_table(data) | |
summary = create_summary_stats(data) | |
return plot, table, summary | |
def compare_data(continent1, country1, continent2, country2): | |
if not all([continent1, country1, continent2, country2]): | |
return None, None | |
data1 = get_country_data(continent1, country1) | |
data2 = get_country_data(continent2, country2) | |
if not data1 or not data2: | |
return None, None | |
# Convert to DataFrames | |
df1 = pd.DataFrame(data1) | |
df2 = pd.DataFrame(data2) | |
# Add country column for identification | |
df1['Country'] = country1 | |
df2['Country'] = country2 | |
# Combine data | |
combined_df = pd.concat([df1, df2]) | |
# Create comparison visualization | |
fig = px.bar( | |
combined_df, | |
x='Category', | |
y='ValueFactor', | |
color='Country', | |
barmode='group', | |
title=f"Value Factor Comparison: {country1} vs {country2}", | |
labels={'ValueFactor': 'Value Factor (USD)', 'Category': 'Impact Category'} | |
) | |
fig.update_layout( | |
xaxis_title="Impact Category", | |
yaxis_title="Value Factor (USD)", | |
legend_title="Country", | |
font=dict(family="Arial, sans-serif", size=12), | |
height=600 | |
) | |
return fig, combined_df | |
# Connect event handlers | |
continent_dropdown.change( | |
fn=update_countries, | |
inputs=[continent_dropdown], | |
outputs=[country_dropdown] | |
) | |
compare_continent1.change( | |
fn=update_countries, | |
inputs=[compare_continent1], | |
outputs=[compare_country1] | |
) | |
compare_continent2.change( | |
fn=update_countries, | |
inputs=[compare_continent2], | |
outputs=[compare_country2] | |
) | |
region_view_button.click( | |
fn=view_region_data, | |
inputs=[continent_dropdown, country_dropdown], | |
outputs=[region_plot, region_table, region_summary] | |
) | |
impact_view_button.click( | |
fn=view_impact_data, | |
inputs=[impact_dropdown], | |
outputs=[impact_plot, impact_table, impact_summary] | |
) | |
compare_button.click( | |
fn=compare_data, | |
inputs=[compare_continent1, compare_country1, compare_continent2, compare_country2], | |
outputs=[compare_plot, compare_table] | |
) | |
return app | |
# Create and launch the app | |
if __name__ == "__main__": | |
app = create_app() | |
app.launch() | |