danielrosehill's picture
Fixed dataset paths and improved data loading methods
9cdf397
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()