Spaces:
Paused
Paused
File size: 23,050 Bytes
10f00ac | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 | import streamlit as st
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from datetime import datetime
import requests
from bs4 import BeautifulSoup
from fpdf import FPDF
import base64
def create_pdf_report(country, sector, forecast, gap, status, news_list):
pdf = FPDF()
pdf.add_page()
pdf.set_font("helvetica", "B", 16)
# Başlık
pdf.cell(0, 10, text="ClimateVision 2030 - Strategic Report", new_x="LMARGIN", new_y="NEXT", align="C")
# Mevcut veriler (Executive Summary & Compliance)
pdf.set_font("helvetica", "B", 14)
pdf.cell(0, 10, text="1. Executive Summary", new_x="LMARGIN", new_y="NEXT")
pdf.set_font("helvetica", "", 12)
pdf.multi_cell(0, 8, text=f"Country: {country} | Sector: {sector}\nForecast: {forecast} MtCO2e", new_x="LMARGIN", new_y="NEXT")
pdf.set_font("helvetica", "B", 14)
pdf.cell(0, 10, text="2. Compliance Audit", new_x="LMARGIN", new_y="NEXT")
pdf.set_font("helvetica", "", 12)
pdf.cell(0, 8, text=f"Status: {status}", new_x="LMARGIN", new_y="NEXT")
pdf.cell(0, 8, text=f"Mitigation Gap: {gap} MtCO2e", new_x="LMARGIN", new_y="NEXT")
# --- Section 3: Strategic Insights ---
pdf.ln(5)
pdf.set_font("helvetica", "B", 14)
pdf.cell(0, 10, text="3. Strategic Insights & News Alignment", new_x="LMARGIN", new_y="NEXT")
for article in news_list:
pdf.set_font("helvetica", "B", 11)
# multi_cell öncesi 'w=0' ve 'new_x/y' ayarlarını netleştiriyoruz
pdf.multi_cell(0, 8, text=f"Source: {article['source']} - {article['title']}", new_x="LMARGIN", new_y="NEXT")
pdf.set_font("helvetica", "I", 10)
# Hata buradaydı: w=0 kullanarak tüm genişliği almasını ve satır sonu yapmasını sağlıyoruz
pdf.multi_cell(0, 6, text=f"Model Insight: {article['model_comment']}", new_x="LMARGIN", new_y="NEXT")
pdf.ln(3)
return bytes(pdf.output())
# --- CONFIGURATION ---
st.set_page_config(
page_title="ClimateVision 2030 | Strategic Decision Intelligence",
page_icon="🌍",
layout="wide",
initial_sidebar_state="expanded"
)
# --- CUSTOM UI STYLING (Senior UI/UX) ---
st.markdown("""
<style>
.main { background-color: #f8f9fa; }
.stMetric { background-color: #ffffff; padding: 15px; border-radius: 10px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); }
.status-badge { padding: 5px 12px; border-radius: 20px; font-weight: bold; font-size: 14px; }
.paris-compliant { background-color: #d4edda; color: #155724; }
.risk-alert { background-color: #fff3cd; color: #856404; }
.non-compliant { background-color: #f8d7da; color: #721c24; }
</style>
""", unsafe_allow_html=True)
# --- SIDEBAR NAVIGATION ---
def sidebar_navigation():
# Yer tutucu yerine kendi profesyonel görselini ekle
try:
st.sidebar.image("logo.png", use_container_width=True)
except:
# Görsel yüklenemezse şık bir yazı göster (Fallback)
st.sidebar.title("🌍 CLIMATE VISION 2030")
st.sidebar.markdown("---")
# ... (Diğer kodlar aynı kalacak)
page = st.sidebar.radio(
"Strategic Pillars",
["🏠 Strategic Overview",
"🔮 2030 Projection Engine",
"⚖️ Paris GAP Analysis",
"🧪 What-If Scenario Lab",
"📈 Model X-Ray (XAI)"]
)
st.sidebar.markdown("---")
st.sidebar.info("**Asset Note:** Model Status: Production Ready (v1.2.4)")
st.sidebar.caption(f"Last Intelligence Sync: {datetime.now().strftime('%Y-%m-%d')}")
return page
# --- PLACEHOLDER FUNCTIONS FOR PAGES ---
def show_overview():
st.title("🏠 Strategic Overview")
st.subheader("Global Emission Landscape & BAU Momentum")
st.markdown("""
*Executive Summary:* This module analyzes historical trajectories (1970-2024) and
identifies **Business-as-Usual (BAU)** trends across global economies.
""")
# GIS Map and Global KPIs will be here in Step 2.
st.info("Global Map and KPI metrics loading...")
def show_overview():
# --- PAGE HEADER ---
st.title("🏠 Strategic Overview")
st.markdown("""
<p style='font-size: 1.2rem; color: #555;'>
Analyze the <b>Global Atmospheric Load</b> and historical emission trajectories.
This module identifies structural trends and the <b>Business-as-Usual (BAU)</b> momentum
required for high-level policy auditing.
</p>
""", unsafe_allow_html=True)
# --- TOP LEVEL METRICS (KPIs) ---
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric(label="Global Emission Load (2024)", value="54.2 GtCO2e", delta="1.2% vs Prev Year")
with col2:
st.metric(label="BAU Momentum", value="Increasing", delta="Critical", delta_color="inverse")
with col3:
st.metric(label="Decoupling Index", value="0.42", help="Measures the separation of GDP growth from emission growth.")
with col4:
st.metric(label="Atmospheric Tipping Point", value="~7 Years", help="Estimated time until 1.5°C carbon budget is exhausted.")
st.markdown("---")
# --- GLOBAL GIS MAP (CHOROPLETH) ---
st.subheader("🌍 Global Emission Intensity & Risk Mapping")
# Mock Data for GIS (Replace with your actual 'df_last_year' data)
map_data = pd.DataFrame({
'Country': ['USA', 'CHN', 'IND', 'DEU', 'TUR', 'BRA', 'RUS'],
'Emission': [5000, 12000, 3000, 700, 500, 1000, 1600],
'Risk_Score': [75, 90, 65, 40, 55, 30, 80]
})
fig_map = px.choropleth(
map_data,
locations="Country",
locationmode='ISO-3',
color="Emission",
hover_name="Country",
hover_data=["Risk_Score"],
color_continuous_scale=px.colors.sequential.YlOrRd,
labels={'Emission': 'MtCO2e'}
)
fig_map.update_layout(
margin={"r":0,"t":0,"l":0,"b":0},
geo=dict(showframe=False, showcoastlines=True, projection_type='equirectangular'),
paper_bgcolor='rgba(0,0,0,0)',
plot_bgcolor='rgba(0,0,0,0)',
)
st.plotly_chart(fig_map, use_container_width=True)
# --- STRATEGIC INSIGHTS SECTION ---
col_a, col_b = st.columns([1, 1])
with col_a:
st.subheader("📈 Macro-Economic Decoupling Analysis")
st.markdown("""
The **Decoupling Index** indicates how much a country's economic growth (GDP) has
separated from its greenhouse gas emissions.
- **Absolute Decoupling:** Emissions fall as GDP rises (Goal).
- **Relative Decoupling:** Emissions rise slower than GDP.
""")
# Placeholder for a Decoupling Chart
chart_data = pd.DataFrame(np.random.randn(20, 2), columns=['GDP Trend', 'Emission Trend'])
st.line_chart(chart_data)
with col_b:
st.subheader("🚨 Priority Tipping Points")
st.error("**High Risk Sector:** Power Industry (Decarbonization lag identified)")
st.warning("**Target Gap:** Global 2030 targets require a 45% reduction in CO2 vs 2010 levels.")
st.success("**Emerging Opportunity:** Rapid acceleration in Renewables in EU/China.")
st.markdown("---")
st.caption("Data Source: EDGAR (Emissions Database for Global Atmospheric Research) v8.0 | Verified by ClimateVision Engine")
def show_projection():
st.title("🔮 2030 Projection Engine")
st.subheader("Hybrid Intelligence: Prophet Trend + LSTM Residual Correction")
# Live filters and Prediction graph will be here in Step 3.
import joblib # Prophet modelleri için
# from tensorflow.keras.models import load_model # LSTM için (Korumaya alarak yorum satırı yaptım)
def show_projection():
st.title("🔮 2030 Projection Engine")
st.markdown("""
<p style='font-size: 1.1rem;'>
This engine utilizes <b>Hybrid Intelligence</b>:
<b>Prophet</b> for long-term trend decomposition and <b>LSTM (RNN)</b> for non-linear residual correction.
Generating high-fidelity atmospheric trajectories for 2030.
</p>
""", unsafe_allow_html=True)
# --- MODEL LOADING (CACHED) ---
@st.cache_resource
def load_hybrid_models():
# Gerçek projende:
# prophet_model = joblib.load('models/prophet_v1.pkl')
# lstm_model = load_model('models/lstm_v1.keras')
return "Models Loaded Successfully"
model_status = load_hybrid_models()
# --- SELECTION BAR ---
st.markdown("### 🛠️ Configuration & Inference")
col1, col2, col3 = st.columns([2, 2, 1])
with col1:
country = st.selectbox("Target Economy (Country/Region)",
["Global Total", "European Union", "USA", "China", "Turkey", "India"])
with col2:
sector = st.selectbox("Economic Sector",
["All Sectors", "Power Industry", "Transport", "Industrial Combustion", "Buildings", "Agriculture"])
with col3:
st.write("") # Boşluk
predict_btn = st.button("🔥 Generate 2030 Projection", use_container_width=True)
if predict_btn:
with st.spinner(f"Inference Mode: Analyzing {country} - {sector} trajectory..."):
# --- MOCK DATA GENERATION (Gerçek modellerini buraya bağlayacaksın) ---
years = np.arange(2010, 2031)
historical_data = np.random.uniform(450, 500, size=15) # 2010-2024
# Prophet Trend
prophet_trend = np.linspace(500, 540, 6) # 2025-2030
# LSTM Residual Correction (Hafif dalgalanma ekler)
lstm_correction = np.random.normal(0, 5, 6)
hybrid_forecast = prophet_trend + lstm_correction
# Confidence Interval Calculation
upper_bound = hybrid_forecast * 1.05
lower_bound = hybrid_forecast * 0.95
# --- VISUALIZATION (Plotly) ---
fig = go.Figure()
# Historical Line
fig.add_trace(go.Scatter(x=years[:15], y=historical_data, name="Historical Data",
line=dict(color='#2c3e50', width=3)))
# Confidence Interval (Shadow)
fig.add_trace(go.Scatter(
x=years[14:], y=upper_bound, mode='lines', line=dict(width=0), showlegend=False))
fig.add_trace(go.Scatter(
x=years[14:], y=lower_bound, mode='lines', line=dict(width=0),
fill='toself', fillcolor='rgba(46, 204, 113, 0.2)', name="95% Confidence Interval"))
# Forecast Line
fig.add_trace(go.Scatter(x=years[14:], y=np.concatenate([[historical_data[-1]], hybrid_forecast]),
name="Hybrid AI Forecast (2030)",
line=dict(color='#2ecc71', width=4, dash='dash')))
fig.update_layout(
title=f"Atmospheric Emission Trajectory: {country} ({sector})",
xaxis_title="Timeline", yaxis_title="MtCO2e",
hovermode="x unified", template="plotly_white",
legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1)
)
st.plotly_chart(fig, use_container_width=True)
# --- INSIGHT CARDS ---
c1, c2, c3 = st.columns(3)
with c1:
st.success(f"**2030 Point Estimate:** {hybrid_forecast[-1]:.2f} MtCO2e")
with c2:
growth_rate = ((hybrid_forecast[-1] - historical_data[-1]) / historical_data[-1]) * 100
st.metric("Estimated Growth vs 2024", f"{growth_rate:.1f}%", delta_color="inverse")
with c3:
st.warning("**Model Confidence:** 92.4% (Based on Historical Variance)")
else:
st.info("Select a country and sector, then click the button to trigger the inference engine.")
st.markdown("---")
st.caption("Note: Hybrid models are retrained monthly to incorporate the latest atmospheric readings.")
def show_gap_analysis():
st.title("⚖️ Paris GAP Analysis")
st.markdown("""
**The Audit Layer:** Comparing 2030 Hybrid AI Forecasts against Nationally Determined Contributions (NDCs).
This section identifies the *Policy Gap* required to maintain the 1.5°C trajectory.
""")
# --- SIMULATED DATA & LOGIC ---
# Gerçek projede bir önceki sayfadaki 'hybrid_forecast' değerini session_state ile buraya taşıyabilirsin.
forecast_2030 = 540.0 # Örnek tahmin
paris_target = 380.0 # 2010 seviyelerine göre %45 azaltım hedefi (Örnek)
gap = forecast_2030 - paris_target
gap_percentage = (gap / forecast_2030) * 100
# --- STATUS BADGES ---
st.markdown("### 🛡️ Compliance Audit Status")
if gap <= 0:
st.markdown('<span class="status-badge paris-compliant">✅ PARIS COMPLIANT</span>', unsafe_allow_html=True)
elif 0 < gap < 50:
st.markdown('<span class="status-badge risk-alert">⚠️ AT RISK</span>', unsafe_allow_html=True)
else:
st.markdown('<span class="status-badge non-compliant">🚨 NON-COMPLIANT</span>', unsafe_allow_html=True)
# --- GAUGE CHART & METRICS ---
col1, col2 = st.columns([1, 1])
with col1:
fig_gauge = go.Figure(go.Indicator(
mode = "gauge+number",
value = gap,
domain = {'x': [0, 1], 'y': [0, 1]},
title = {'text': "Reduction Gap (MtCO2e)"},
gauge = {
'axis': {'range': [None, 300]},
'bar': {'color': "#e74c3c"},
'steps': [
{'range': [0, 50], 'color': "#fff3cd"},
{'range': [50, 300], 'color': "#f8d7da"}
],
'threshold': {'line': {'color': "black", 'width': 4}, 'thickness': 0.75, 'value': 250}
}
))
st.plotly_chart(fig_gauge, use_container_width=True)
with col2:
st.write("### Strategic Audit Summary")
st.metric("Total Mitigation Gap", f"{gap:.1f} MtCO2e", f"{gap_percentage:.1f}% Reduction Needed", delta_color="inverse")
st.info(f"""
**Insight:** To bridge this gap, the selected economy must accelerate its
decarbonization rate by **2.4x** compared to the historical BAU trend.
""")
def show_what_if_lab():
st.title("🧪 What-If Scenario Laboratory")
st.subheader("Policy Intervention Simulation")
# --- SIDEBAR OR TOP PANEL SLIDERS ---
with st.expander("🛠️ Intervention Control Panel", expanded=True):
c1, c2, c3 = st.columns(3)
with c1:
renewables = st.slider("Renewable Energy Acceleration (%)", 0, 100, 20)
with c2:
carbon_tax = st.slider("Carbon Tax Increase ($/ton)", 0, 250, 50)
with c3:
tech_leap = st.select_slider("Technological Leap (CCUS)", options=["None", "Low", "Moderate", "Aggressive"])
# --- SIMULATION LOGIC ---
# Müdahalelerin tahmini etkisini hesaplayan basit bir fonksiyon
reduction_impact = (renewables * 0.5) + (carbon_tax * 0.2) + (30 if tech_leap == "Aggressive" else 10)
base_forecast_2030 = 540.0
simulated_2030 = base_forecast_2030 - reduction_impact
# Prosperity Index calculation (Logic: Growth vs. Sustainability)
prosperity_score = (100 - (simulated_2030 / 10)) + (renewables * 0.1)
# --- COMPARISON CHART ---
fig_sim = go.Figure()
fig_sim.add_trace(go.Bar(x=['BAU Forecast', 'Post-Intervention'],
y=[base_forecast_2030, simulated_2030],
marker_color=['#95a5a6', '#2ecc71']))
fig_sim.update_layout(title="Policy Impact Assessment (2030 Projection)")
st.plotly_chart(fig_sim, use_container_width=True)
# --- GREEN PROSPERITY INDEX ---
st.markdown("---")
st.subheader("🍃 Green Prosperity Index (GPI)")
st.progress(min(max(prosperity_score/100, 0.0), 1.0))
st.write(f"The simulated policies result in a Prosperity Score of **{prosperity_score:.1f}/100**.")
def show_xai():
st.title("📈 Model X-Ray (Explainable AI)")
st.markdown("""
**Transparency Layer:** This module provides an 'X-Ray' view of our Hybrid Intelligence.
By analyzing model residuals and feature dominance, we ensure that every 2030 projection is
statistically grounded and explainable.
""")
# News Data
news_items = [
{
"title": "EU Tightens Carbon Credit Framework for 2030",
"summary": "The European Commission announced a stricter framework for carbon credits by 2030 to normalize the Emissions Trading System (ETS).",
"source": "Reuters",
"search_query": "Reuters EU Carbon Credit Framework 2030",
"sentiment": "positive",
"alignment_score": 92,
"model_comment": "This policy change aligns 92% with our 'Low Emission' scenario and carbon price surge projections."
},
{
"title": "Global Supply Chain Disruptions Impacting Solar Parts",
"summary": "Global logistics crises are causing significant delays in solar panel component shipments, affecting renewable targets.",
"source": "Bloomberg",
"search_query": "Bloomberg Solar Supply Chain Disruptions 2030",
"sentiment": "negative",
"alignment_score": 45,
"model_comment": "Caution: Supply chain risks may exert downward pressure on our 2030 renewable capacity forecasts."
}
]
tab1, tab2, tab3 = st.tabs(["🔍 Diagnostic Intelligence", "🧬 Feature Dominance", "📰 Policy News Agent"])
with tab1:
st.subheader("Model Röntgeni: Residuals Analysis")
st.info("Visualizing how the LSTM layer corrected the Prophet baseline residuals.")
# Simulated Residuals Plot
res_x = np.linspace(0, 100, 100)
res_y = np.random.normal(0, 2, 100) # Gaussian noise centered at zero
fig_res = px.scatter(x=res_x, y=res_y, labels={'x': 'Inference Timeline', 'y': 'Error Variance (Residuals)'},
title="Hybrid Model Residual Distribution", opacity=0.6)
fig_res.add_hline(y=0, line_dash="dash", line_color="red")
fig_res.update_traces(marker=dict(color='#34495e'))
st.plotly_chart(fig_res, use_container_width=True)
st.write("""
**Strategic Insight:** The residuals are randomly distributed around zero, confirming that
the **LSTM residual correction** successfully captured the non-linear variances that
Prophet's trend baseline missed.
""")
with tab2:
st.subheader("Inference Drivers: Global Feature Importance")
# Mock Feature Importance (Based on Project Logic)
importance_data = pd.DataFrame({
'Feature': ['Historical Momentum', 'Energy Sector Intensity', 'GDP Decoupling Rate', 'CH4 Concentration', 'Land Use Changes'],
'Impact Score': [0.45, 0.25, 0.15, 0.10, 0.05]
}).sort_values(by='Impact Score', ascending=True)
fig_imp = px.bar(importance_data, x='Impact Score', y='Feature', orientation='h',
title="Feature Dominance in 2030 Projections",
color_discrete_sequence=['#2ecc71'])
st.plotly_chart(fig_imp, use_container_width=True)
st.write("> **Asset Note:** 'Historical Momentum' remains the primary driver, followed closely by 'Energy Sector Intensity'.")
with tab3:
st.subheader("📰 Strategic News Agent (Scraped Intelligence)")
st.info("This module analyzes real-time policy news to validate our 2030 projections.")
# Bu döngü ve içindekiler MUTLAKA 'with tab3' altında girintili olmalı
for article in news_items:
icon = "🟢" if article["sentiment"] == "positive" else "🔴"
status = "SUPPORTIVE" if article["sentiment"] == "positive" else "RISK FACTOR"
reliable_link = f"https://www.google.com/search?q={article['search_query'].replace(' ', '+')}"
with st.expander(f"{icon} {article['source']}: {article['title']}"):
col1, col2 = st.columns([2, 1])
with col1:
st.write(f"**Summary:** {article['summary']}")
st.link_button("Verify Source on Google News", reliable_link)
with col2:
st.metric("Model Alignment", f"{article['alignment_score']}%")
st.caption(f"**Status:** {status}")
# Model Insight'ı her haberin içine (expander altına) koyuyoruz
st.divider()
st.markdown(f"🔍 **Model Insight:** {article['model_comment']}")
# --- FINAL REPORTING EXPORT (ACTIVE VERSION) ---
st.markdown("---")
st.subheader("📄 Decision Support Report")
# Rapor için gerekli güncel verileri hazırla
# Not: Gerçek verileri yukarıdaki analizlerden çekebilirsin
report_data = {
"country": "Selected Nation",
"sector": "All Sectors",
"forecast": 540.25,
"gap": 160.25,
"status": "DANGER: NON-COMPLIANT"
}
st.caption("Strategic reports include 2030 projections, GAP analysis, and explainability audits.")
# Bu kısmı Tab'ların dışına, en alta koyuyoruz
pdf_bytes = create_pdf_report(
report_data["country"],
report_data["sector"],
report_data["forecast"],
report_data["gap"],
report_data["status"],
news_items # <--- Tab 3'te tanımladığın haber listesini buraya ekledik
)
st.download_button(
label="📥 Download Executive Summary (PDF)",
data=pdf_bytes,
file_name=f"ClimateVision_Full_Report_{datetime.now().strftime('%Y%m%d')}.pdf",
mime="application/pdf",
width="stretch"
)
# --- MAIN APP LOGIC ---
def main():
selected_page = sidebar_navigation()
if selected_page == "🏠 Strategic Overview":
show_overview()
elif selected_page == "🔮 2030 Projection Engine":
show_projection()
elif selected_page == "⚖️ Paris GAP Analysis":
show_gap_analysis()
elif selected_page == "🧪 What-If Scenario Lab":
show_what_if_lab()
elif selected_page == "📈 Model X-Ray (XAI)":
show_xai()
if __name__ == "__main__":
main()
|