malcolmSQ
Fix: Use cumulative soil carbon for all tables and outputs; remove cumsum from table logic
fa68af3 | """ | |
| Table formatting functions for the Mangrove ER Dashboard. | |
| """ | |
| # Imports will be updated as needed when moving functions from app.py | |
| import pandas as pd | |
| import numpy as np | |
| from er_model_core.er_model import ERModel | |
| from pathlib import Path | |
| import yaml | |
| # Helper for pretty table titles | |
| def pretty_table_title(title): | |
| return f"<span style='font-size:1.3em; font-weight:bold'>{title}</span>" | |
| # Table: Biomass Table (was debug table) | |
| def create_biomass_table(config): | |
| """ | |
| Returns a DataFrame with years as rows and columns for each species: | |
| - Surviving Trees | |
| - DBH (cm) | |
| - Height (m) | |
| - Biomass per Tree (kg) | |
| - Total Biomass (kg) | |
| Uses model.species_metrics for all values. | |
| """ | |
| import tempfile | |
| with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as tmp: | |
| yaml.dump(config, tmp) | |
| tmp_path = tmp.name | |
| model = ERModel(Path(tmp_path)) | |
| model.run() | |
| df = model.species_metrics.copy() | |
| # Pivot to multi-index columns: (Species, Metric) | |
| df = df.pivot(index="Year", columns="Species") | |
| # Flatten columns | |
| SPECIES_DISPLAY_NAMES = { | |
| 'species_A': 'Rhizophora spp.', | |
| 'species_B': 'Avicennia germinans' | |
| } | |
| df.columns = [f"{SPECIES_DISPLAY_NAMES.get(sp, sp)}, {metric}" for metric, sp in df.columns] | |
| # Format numbers | |
| for col in df.columns: | |
| if "Surviving Trees" in col: | |
| df[col] = df[col].apply(lambda x: f"{x:,.0f}") | |
| elif "Biomass" in col or "DBH" in col or "Height" in col: | |
| df[col] = df[col].apply(lambda x: f"{x:,.2f}") | |
| return df | |
| # Table: Surviving Trees Table | |
| def create_survival_table(model): | |
| """ | |
| Returns a DataFrame with years as rows and columns for each species and total surviving trees. | |
| Uses model.species_metrics for all values. | |
| """ | |
| SPECIES_DISPLAY_NAMES = { | |
| 'species_A': 'Rhizophora spp.', | |
| 'species_B': 'Avicennia germinans' | |
| } | |
| df = model.species_metrics.copy() | |
| # Pivot to wide format: years as rows, species as columns | |
| surv = df.pivot(index="Year", columns="Species", values="Surviving Trees") | |
| # Rename columns to display names | |
| surv.columns = [SPECIES_DISPLAY_NAMES.get(sp, sp) for sp in surv.columns] | |
| # Add total surviving trees column | |
| surv["Total Surviving Trees"] = surv.sum(axis=1) | |
| # Format numbers | |
| for col in surv.columns: | |
| surv[col] = surv[col].apply(lambda x: f"{x:,.0f}") | |
| surv = surv.reset_index() | |
| return surv | |
| def create_project_results_table(results: pd.DataFrame) -> pd.DataFrame: | |
| df = results.copy() | |
| # No need to cumsum soil_carbon; model now provides cumulative values | |
| # Optionally format numbers for display | |
| for col in df.columns: | |
| if df[col].dtype in [float, int]: | |
| df[col] = df[col].apply(lambda x: f"{x:,.2f}" if isinstance(x, float) else f"{x:,}") | |
| return df |