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(""" """, 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("""

Analyze the Global Atmospheric Load and historical emission trajectories. This module identifies structural trends and the Business-as-Usual (BAU) momentum required for high-level policy auditing.

""", 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("""

This engine utilizes Hybrid Intelligence: Prophet for long-term trend decomposition and LSTM (RNN) for non-linear residual correction. Generating high-fidelity atmospheric trajectories for 2030.

""", 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('✅ PARIS COMPLIANT', unsafe_allow_html=True) elif 0 < gap < 50: st.markdown('⚠️ AT RISK', unsafe_allow_html=True) else: st.markdown('🚨 NON-COMPLIANT', 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()