Skip to content

View or edit on GitHub

This page is synchronized from trase/data/brazil/soy/indicators/out/q3_2026/qa/comparing_to_previous_results.md. Last modified on 2026-09-20 13:50 CEST by Nicolas Martin. Please view or edit the original file there; changes should be reflected here after a midnight build (CET time), or manually triggering it with a GitHub action (link).

QA Comparison: New vs. Legacy Soy Deforestation & Emissions Indicators

Florian Gollnow 2026-08-30

Setup & Libraries

library(tidyverse)
library(aws.signature)
library(aws.s3)
library(arrow)
library(scales)

aws.signature::use_credentials()

# Helper for text cleaning
str_trans <- function(x) {
  x %>%
    stringi::stri_trans_toupper() %>%
    stringi::stri_trans_general("Latin-ASCII")
}

Data Ingestion & Harmonization

# 1. Load Biome Spatial Mapping Lookup
biomes_lookup <- s3read_using(
  FUN = read_delim,
  delim = ";",
  object = "brazil/spatial/boundaries/ibge/br_municipality_biome/Bioma_Predominante_por_Municipio_2024.csv",
  opts = c("check_region" = TRUE),
  bucket = "trase-storage"
) %>%
  mutate(
    BIOME = str_trans(`Bioma predominante`),
    TRASE_ID = paste0("BR-", `Geocódigo`)
  ) %>%
  select(TRASE_ID, BIOME)

# 2. Load Processed Datasets from S3
df_new <- s3read_using(
  FUN = read_parquet,
  object = "brazil/soy/indicators/out/q3_2026/soy_deforestation_emission_norm_2014_2024_q3_2026_multilevel.parquet",
  opts = c("check_region" = TRUE),
  bucket = "trase-storage"
)

df_legacy <- s3read_using(
  FUN = read_parquet,
  object = "brazil/soy/indicators/out/q4_2025/soy_def_2014_2024_glad_mb_orig_ngb_multilevel_fix_q3_2026.parquet",
  opts = c("check_region" = TRUE),
  bucket = "trase-storage"
)

# 3. Harmonize, Join Metrics & Attach Biome Information
qa_joined <- df_new %>%
  select(
    TRASE_ID,
    YEAR,
    level,
    new_area_ha = SOY_GLAD_HA,
    new_total_def_ha = SOY_DEFORESTATION_5_YEAR_TOTAL,
    new_forest_def_ha = SOY_FOREST_DEFORESTATION_5_YEAR_TOTAL,
    new_non_forest_def_ha = SOY_NON_FOREST_DEFORESTATION_5_YEAR_TOTAL,
    new_total_def_ton = SOY_DEFORESTATION_5_YEAR_TOTAL_NORM_PER_TON,
    new_gross_emiss = CO2_GROSS_EMISSIONS_SOY_DEFORESTATION_5_YEAR_TOTAL,
    new_gross_emiss_forest = CO2_GROSS_EMISSIONS_SOY_FOREST_DEFORESTATION_5_YEAR_TOTAL,
    new_gross_emiss_non_forest = CO2_GROSS_EMISSIONS_SOY_NON_FOREST_DEFORESTATION_5_YEAR_TOTAL,
    new_net_emiss = CO2_NET_EMISSIONS_SOY_DEFORESTATION_5_YEAR_TOTAL
  ) %>%
  inner_join(
    df_legacy %>%
      select(
        TRASE_ID,
        YEAR,
        level,
        leg_area_ha = SOY_GLAD_HA,
        leg_def_ha = SOY_DEFORESTATION_5_YEAR_TOTAL,
        leg_def_ton = SOY_DEFORESTATION_PER_TN_5_YEAR_TOTAL,
        leg_gross_emiss = CO2_GROSS_EMISSIONS_SOY_DEFORESTATION_5_YEAR_TOTAL,
        leg_net_emiss = CO2_NET_EMISSIONS_SOY_DEFORESTATION_5_YEAR_TOTAL
      ),
    by = c("TRASE_ID", "YEAR", "level")
  ) %>%
  left_join(biomes_lookup, by = "TRASE_ID")

Statistical Summaries & Outlier Detection

# 4a. Statistical Summary Table by Spatial Level (Deforestation, Gross & Net Emissions)
qa_summary_by_level <- qa_joined %>%
  group_by(level) %>%
  summarise(
    n_records = n(),
    total_ha_new = sum(new_total_def_ha, na.rm = TRUE),
    total_ha_legacy = sum(leg_def_ha, na.rm = TRUE),
    ha_diff_pct = (total_ha_new - total_ha_legacy) / total_ha_legacy * 100,
    pearson_r_def_ha = cor(new_total_def_ha, leg_def_ha, use = "complete.obs"),
    spearman_r_def_ha = cor(
      new_total_def_ha,
      leg_def_ha,
      method = "spearman",
      use = "complete.obs"
    ),
    mae_def_ha = mean(abs(new_total_def_ha - leg_def_ha), na.rm = TRUE),
    rmse_def_ha = sqrt(mean((new_total_def_ha - leg_def_ha)^2, na.rm = TRUE)),
    pearson_r_intensity = cor(
      new_total_def_ton,
      leg_def_ton,
      use = "complete.obs"
    ),
    total_gross_emiss_new = sum(new_gross_emiss, na.rm = TRUE),
    total_gross_emiss_legacy = sum(leg_gross_emiss, na.rm = TRUE),
    gross_emiss_diff_pct = (total_gross_emiss_new - total_gross_emiss_legacy) /
      total_gross_emiss_legacy *
      100,
    pearson_r_gross_emiss = cor(
      new_gross_emiss,
      leg_gross_emiss,
      use = "complete.obs"
    ),
    spearman_r_gross_emiss = cor(
      new_gross_emiss,
      leg_gross_emiss,
      method = "spearman",
      use = "complete.obs"
    ),
    total_net_emiss_new = sum(new_net_emiss, na.rm = TRUE),
    total_net_emiss_legacy = sum(leg_net_emiss, na.rm = TRUE),
    net_emiss_diff_pct = (total_net_emiss_new - total_net_emiss_legacy) /
      total_net_emiss_legacy *
      100,
    pearson_r_net_emiss = cor(
      new_net_emiss,
      leg_net_emiss,
      use = "complete.obs"
    ),
    spearman_r_net_emiss = cor(
      new_net_emiss,
      leg_net_emiss,
      method = "spearman",
      use = "complete.obs"
    ),
    .groups = "drop"
  )

knitr::kable(
  qa_summary_by_level,
  caption = "QA Statistical Summary by Level of Total Soy Deforestation, Gross & Net Emissions"
)
level n_records total_ha_new total_ha_legacy ha_diff_pct pearson_r_def_ha spearman_r_def_ha mae_def_ha rmse_def_ha pearson_r_intensity total_gross_emiss_new total_gross_emiss_legacy gross_emiss_diff_pct pearson_r_gross_emiss spearman_r_gross_emiss total_net_emiss_new total_net_emiss_legacy net_emiss_diff_pct pearson_r_net_emiss spearman_r_net_emiss
biome 66 8148210 8285461 -1.656535 0.9972228 0.9967018 5057.20116 10711.7830 0.5828598 1209692883 1236383729 -2.158783 0.9973523 0.9952406 1058473493 780553861 35.60544 0.9857116 0.9876422
country 11 8148210 8285461 -1.656535 0.9949966 0.9818182 16397.57184 19553.5250 0.8333919 1209692883 1236383729 -2.158783 0.9976885 0.9727273 1058473493 780553861 35.60544 0.9955737 0.9636364
municipality 61270 8148210 8285461 -1.656535 0.9915232 0.9542717 8.53944 116.8526 0.3363595 1209692883 1236383729 -2.158783 0.9876614 0.9523298 1058473493 780553861 35.60544 0.9732006 0.9362775
state 297 8148210 8285461 -1.656535 0.9962545 0.9970471 1308.14205 5625.1569 NaN 1209692883 1236383729 -2.158783 0.9938497 0.9962818 1058473493 780553861 35.60544 0.9828536 0.9931134

QA Statistical Summary by Level of Total Soy Deforestation, Gross & Net Emissions

# 4b. Statistical Summary Table by Year (Municipal Level)
qa_summary_by_year <- qa_joined %>%
  filter(level == "municipality") %>%
  group_by(YEAR) %>%
  summarise(
    n_records = n(),
    total_ha_new = sum(new_total_def_ha, na.rm = TRUE),
    total_ha_legacy = sum(leg_def_ha, na.rm = TRUE),
    ha_diff_pct = (total_ha_new - total_ha_legacy) / total_ha_legacy * 100,
    pearson_r_def_ha = cor(new_total_def_ha, leg_def_ha, use = "complete.obs"),
    total_gross_emiss_new = sum(new_gross_emiss, na.rm = TRUE),
    total_gross_emiss_legacy = sum(leg_gross_emiss, na.rm = TRUE),
    gross_emiss_diff_pct = (total_gross_emiss_new - total_gross_emiss_legacy) /
      total_gross_emiss_legacy *
      100,
    pearson_r_gross_emiss = cor(
      new_gross_emiss,
      leg_gross_emiss,
      use = "complete.obs"
    ),
    total_net_emiss_new = sum(new_net_emiss, na.rm = TRUE),
    total_net_emiss_legacy = sum(leg_net_emiss, na.rm = TRUE),
    net_emiss_diff_pct = (total_net_emiss_new - total_net_emiss_legacy) /
      total_net_emiss_legacy *
      100,
    pearson_r_net_emiss = cor(
      new_net_emiss,
      leg_net_emiss,
      use = "complete.obs"
    ),
    .groups = "drop"
  )

knitr::kable(
  qa_summary_by_year,
  caption = "QA Statistical Summary by Year (Total Soy Deforestation, Gross & Net Emissions)"
)
YEAR n_records total_ha_new total_ha_legacy ha_diff_pct pearson_r_def_ha total_gross_emiss_new total_gross_emiss_legacy gross_emiss_diff_pct pearson_r_gross_emiss total_net_emiss_new total_net_emiss_legacy net_emiss_diff_pct pearson_r_net_emiss
2014 5570 474039.3 466956.0 1.5169261 0.9981936 61209454 61993706 -1.2650515 0.9990232 52536759 37766921 39.10787 0.9826653
2015 5570 701153.4 687934.9 1.9214735 0.9977887 95570730 95660777 -0.0941317 0.9982390 82745459 58892287 40.50305 0.9830934
2016 5570 581025.8 587952.1 -1.1780271 0.9980833 80031590 81661393 -1.9958063 0.9987778 69398164 50848347 36.48067 0.9790400
2017 5570 886167.3 893996.5 -0.8757527 0.9985188 127541983 130613393 -2.3515271 0.9987135 111290592 81291976 36.90231 0.9804314
2018 5570 791910.5 803109.7 -1.3944792 0.9987081 116648628 119573722 -2.4462679 0.9991988 102094497 74695788 36.68039 0.9833212
2019 5570 746709.4 767526.4 -2.7122246 0.9978006 110461606 113980035 -3.0868817 0.9985365 96676280 72053151 34.17356 0.9821933
2020 5570 570702.0 599000.9 -4.7243569 0.9956317 85003167 88298482 -3.7320185 0.9944273 74353547 56431317 31.75937 0.9850333
2021 5570 801386.5 838821.5 -4.4628010 0.9977377 121481795 127375577 -4.6270898 0.9978412 106493175 81997268 29.87405 0.9842048
2022 5570 834106.5 861552.2 -3.1856109 0.9968879 129295872 133286147 -2.9937655 0.9972328 113664715 84834006 33.98485 0.9838024
2023 5570 944922.8 963784.1 -1.9569947 0.9835769 154636229 157180265 -1.6185469 0.9776249 136799054 101475288 34.81021 0.9671373
2024 5570 816086.0 814827.1 0.1545082 0.9658272 127811828 126760232 0.8295951 0.9481672 112421251 80267510 40.05823 0.9357898

QA Statistical Summary by Year (Total Soy Deforestation, Gross & Net Emissions)

# 5a. Outlier & Mismatch Flagging (Top 10 Municipal Total Soy Deforestation Discrepancies)
muni_discrepancies_ha <- qa_joined %>%
  filter(level == "municipality") %>%
  mutate(
    abs_diff_ha = abs(new_total_def_ha - leg_def_ha),
    rel_diff_pct = if_else(
      leg_def_ha > 0,
      (new_total_def_ha - leg_def_ha) / leg_def_ha * 100,
      NA_real_
    )
  ) %>%
  arrange(desc(abs_diff_ha)) %>%
  slice_head(n = 10)

knitr::kable(
  muni_discrepancies_ha %>%
    select(
      TRASE_ID,
      BIOME,
      YEAR,
      new_total_def_ha,
      leg_def_ha,
      abs_diff_ha,
      rel_diff_pct
    ),
  caption = "Top 10 Municipal Total Soy Deforestation Discrepancies (ha)"
)
TRASE_ID BIOME YEAR new_total_def_ha leg_def_ha abs_diff_ha rel_diff_pct
BR-1400100 AMAZONIA 2024 16840.281 2519.173 14321.108 568.48448
BR-1400100 AMAZONIA 2023 17948.633 7351.431 10597.202 144.15156
BR-1400050 AMAZONIA 2024 12533.554 2533.216 10000.338 394.76844
BR-1400159 AMAZONIA 2024 11687.608 1889.453 9798.155 518.57084
BR-1400050 AMAZONIA 2023 11245.050 4412.313 6832.738 154.85615
BR-1400159 AMAZONIA 2023 9966.577 4350.830 5615.747 129.07301
BR-4318309 PAMPA 2023 16789.237 20030.610 3241.373 -16.18210
BR-1400100 AMAZONIA 2022 10134.910 7163.723 2971.187 41.47546
BR-4306601 PAMPA 2022 13771.218 15798.960 2027.742 -12.83465
BR-4306601 PAMPA 2023 13719.616 15687.987 1968.371 -12.54699

Top 10 Municipal Total Soy Deforestation Discrepancies (ha)

# 5b. Outlier & Mismatch Flagging (Top 10 Municipal Gross Emissions Discrepancies)
muni_discrepancies_gross <- qa_joined %>%
  filter(level == "municipality") %>%
  mutate(
    abs_diff_gross = abs(new_gross_emiss - leg_gross_emiss),
    rel_diff_pct = if_else(
      leg_gross_emiss > 0,
      (new_gross_emiss - leg_gross_emiss) / leg_gross_emiss * 100,
      NA_real_
    )
  ) %>%
  arrange(desc(abs_diff_gross)) %>%
  slice_head(n = 10)

knitr::kable(
  muni_discrepancies_gross %>%
    select(
      TRASE_ID,
      BIOME,
      YEAR,
      new_gross_emiss,
      leg_gross_emiss,
      abs_diff_gross,
      rel_diff_pct
    ),
  caption = "Top 10 Municipal Soy Gross CO2 Emissions Discrepancies (tCO2)"
)
TRASE_ID BIOME YEAR new_gross_emiss leg_gross_emiss abs_diff_gross rel_diff_pct
BR-1400100 AMAZONIA 2024 3749424 621753.6 3127670.6 503.04024
BR-1400100 AMAZONIA 2023 4223235 1886194.2 2337041.2 123.90247
BR-1400050 AMAZONIA 2024 2453394 576623.8 1876769.9 325.47559
BR-1400050 AMAZONIA 2023 2464652 1137505.5 1327147.0 116.67170
BR-1400159 AMAZONIA 2024 1543931 258416.3 1285514.3 497.45862
BR-1400159 AMAZONIA 2023 1391829 643311.2 748518.1 116.35396
BR-1400100 AMAZONIA 2022 2355373 1825872.2 529500.3 28.99986
BR-1400100 AMAZONIA 2020 1700664 1265710.7 434953.1 34.36434
BR-1400050 AMAZONIA 2020 1607444 1191162.7 416281.6 34.94750
BR-4306908 PAMPA 2021 1735996 2133056.7 397060.4 -18.61462

Top 10 Municipal Soy Gross CO2 Emissions Discrepancies (tCO2)

# 5c. Outlier & Mismatch Flagging (Top 10 Municipal Net Emissions Discrepancies)
muni_discrepancies_net <- qa_joined %>%
  filter(level == "municipality") %>%
  mutate(
    abs_diff_net = abs(new_net_emiss - leg_net_emiss),
    rel_diff_pct = if_else(
      leg_net_emiss > 0,
      (new_net_emiss - leg_net_emiss) / leg_net_emiss * 100,
      NA_real_
    )
  ) %>%
  arrange(desc(abs_diff_net)) %>%
  slice_head(n = 10)

knitr::kable(
  muni_discrepancies_net %>%
    select(
      TRASE_ID,
      BIOME,
      YEAR,
      new_net_emiss,
      leg_net_emiss,
      abs_diff_net,
      rel_diff_pct
    ),
  caption = "Top 10 Municipal Soy Net CO2 Emissions Discrepancies (tCO2)"
)
TRASE_ID BIOME YEAR new_net_emiss leg_net_emiss abs_diff_net rel_diff_pct
BR-1400100 AMAZONIA 2024 3375761 468709.1 2907052 620.22512
BR-1400100 AMAZONIA 2023 3824247 1435459.2 2388788 166.41277
BR-1400050 AMAZONIA 2024 2175319 423155.0 1752164 414.07131
BR-2911105 CERRADO 2024 4083493 2391635.4 1691858 70.74062
BR-2911105 CERRADO 2023 3596049 2059438.6 1536611 74.61309
BR-2201150 CERRADO 2017 4053387 2537524.9 1515863 59.73784
BR-2101400 CERRADO 2024 3337654 1847990.5 1489663 80.60989
BR-2911105 CERRADO 2017 3548738 2153619.0 1395119 64.78022
BR-1400050 AMAZONIA 2023 2214448 857551.5 1356897 158.22917
BR-2101400 CERRADO 2023 2858833 1519610.3 1339223 88.12936

Top 10 Municipal Soy Net CO2 Emissions Discrepancies (tCO2)

Diagnostic Visualizations: Total Soy Deforestation Area

# 6a. Multi-Level Comparison Faceted by Aggregation Level (Total Deforestation)
ggplot(qa_joined, aes(x = leg_def_ha + 1, y = new_total_def_ha + 1)) +
  geom_point(alpha = 0.3, color = "#2c7fb8", size = 1.2) +
  geom_abline(
    intercept = 0,
    slope = 1,
    linetype = "dashed",
    color = "firebrick",
    linewidth = 0.8
  ) +
  scale_x_log10(labels = label_comma()) +
  scale_y_log10(labels = label_comma()) +
  facet_wrap(~level, scales = "free") +
  labs(
    title = "QA Check: Total Soy Deforestation Area Across Spatial Levels",
    subtitle = "New pipeline (Q3 2026) vs. Legacy pipeline (Q4 2025) (+1 log shift)",
    x = "Legacy Pipeline Total Deforestation (ha)",
    y = "New Pipeline Total Deforestation (ha)"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    panel.grid.minor = element_blank(),
    plot.title = element_text(face = "bold")
  )

# 6b. Municipal Level Comparison Highlighted and Color-Coded by Biome (Total Deforestation)
qa_muni <- qa_joined %>% filter(level == "municipality", !is.na(BIOME))

ggplot(
  qa_muni,
  aes(x = leg_def_ha + 1, y = new_total_def_ha + 1, color = YEAR)
) +
  geom_point(alpha = 0.4, size = 1.5) +
  geom_abline(
    intercept = 0,
    slope = 1,
    linetype = "dashed",
    color = "black",
    linewidth = 0.8
  ) +
  scale_x_log10(labels = label_comma()) +
  scale_y_log10(labels = label_comma()) +
  scale_color_viridis_c(option = "viridis", na.value = "grey50") +
  labs(
    title = "QA Check: Municipal Total Soy Deforestation Discrepancies by Biome",
    subtitle = "Points aligned along the dashed line show strong parity; colored by predominant biome",
    x = "Legacy Pipeline Total Deforestation (ha + 1)",
    y = "New Pipeline Total Deforestation (ha + 1)",
    color = "Year"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    panel.grid.minor = element_blank(),
    plot.title = element_text(face = "bold"),
    legend.position = "right",
    legend.title = element_text(face = "bold")
  ) +
  facet_wrap(~BIOME)

Diagnostic Visualizations: Soy Deforestation Intensity (Area per Ton)

# 7a. Multi-Level Comparison for Intensity Metrics
ggplot(qa_joined, aes(x = leg_def_ton + 1e-4, y = new_total_def_ton + 1e-4)) +
  geom_point(alpha = 0.3, color = "#d95f02", size = 1.2) +
  geom_abline(
    intercept = 0,
    slope = 1,
    linetype = "dashed",
    color = "firebrick",
    linewidth = 0.8
  ) +
  scale_x_log10(labels = label_comma()) +
  scale_y_log10(labels = label_comma()) +
  facet_wrap(~level, scales = "free") +
  labs(
    title = "QA Check: Total Soy Deforestation Intensity (ha/ton) Across Spatial Levels",
    subtitle = "New pipeline (Q3 2026) vs. Legacy pipeline (Q4 2025) (+1e-4 log shift)",
    x = "Legacy Pipeline Deforestation Intensity (ha/t)",
    y = "New Pipeline Deforestation Intensity (ha/t)"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    panel.grid.minor = element_blank(),
    plot.title = element_text(face = "bold")
  )

# 7b. Municipal Level Intensity Comparison Highlighted by Biome
ggplot(
  qa_muni,
  aes(x = leg_def_ton + 1e-4, y = new_total_def_ton + 1e-4, color = YEAR)
) +
  geom_point(alpha = 0.4, size = 1.5) +
  geom_abline(
    intercept = 0,
    slope = 1,
    linetype = "dashed",
    color = "black",
    linewidth = 0.8
  ) +
  scale_x_log10(labels = label_comma()) +
  scale_y_log10(labels = label_comma()) +
  scale_color_viridis_c(option = "viridis", na.value = "grey50") +
  labs(
    title = "QA Check: Municipal Total Soy Deforestation Intensity Discrepancies by Biome",
    subtitle = "Points aligned along the dashed line show parity",
    x = "Legacy Pipeline Deforestation Intensity (ha/t + 1e-4)",
    y = "New Pipeline Deforestation Intensity (ha/t + 1e-4)",
    color = "Year"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    panel.grid.minor = element_blank(),
    plot.title = element_text(face = "bold")
  ) +
  facet_wrap(~BIOME)

Diagnostic Visualizations: Gross Emissions

# 8a. Multi-Level Gross Emissions Comparison Faceted by Aggregation Level
ggplot(qa_joined, aes(x = leg_gross_emiss + 1, y = new_gross_emiss + 1)) +
  geom_point(alpha = 0.3, color = "#31a354", size = 1.2) +
  geom_abline(
    intercept = 0,
    slope = 1,
    linetype = "dashed",
    color = "firebrick",
    linewidth = 0.8
  ) +
  scale_x_log10(labels = label_comma()) +
  scale_y_log10(labels = label_comma()) +
  facet_wrap(~level, scales = "free") +
  labs(
    title = "QA Check: Total Soy Gross CO2 Emissions Across Spatial Levels",
    subtitle = "New pipeline (Q3 2026) vs. Legacy pipeline (Q4 2025) (+1 log shift)",
    x = "Legacy Pipeline Gross Emissions (tCO2)",
    y = "New Pipeline Gross Emissions (tCO2)"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    panel.grid.minor = element_blank(),
    plot.title = element_text(face = "bold")
  )

# 8b. Municipal Level Gross Emissions Comparison Highlighted by Biome
ggplot(
  qa_muni,
  aes(x = leg_gross_emiss + 1, y = new_gross_emiss + 1, color = YEAR)
) +
  geom_point(alpha = 0.4, size = 1.5) +
  geom_abline(
    intercept = 0,
    slope = 1,
    linetype = "dashed",
    color = "black",
    linewidth = 0.8
  ) +
  scale_x_log10(labels = label_comma()) +
  scale_y_log10(labels = label_comma()) +
  scale_color_viridis_c(option = "viridis", na.value = "grey50") +
  labs(
    title = "QA Check: Municipal Total Soy Gross CO2 Emissions Discrepancies by Biome",
    subtitle = "Points aligned along the dashed line show strong parity; colored by predominant biome",
    x = "Legacy Pipeline Gross Emissions (tCO2 + 1)",
    y = "New Pipeline Gross Emissions (tCO2 + 1)",
    color = "Year"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    panel.grid.minor = element_blank(),
    plot.title = element_text(face = "bold"),
    legend.position = "right",
    legend.title = element_text(face = "bold")
  ) +
  facet_wrap(~BIOME)

Diagnostic Visualizations: Net Emissions

# 9a. Multi-Level Net Emissions Comparison
ggplot(qa_joined, aes(x = leg_net_emiss + 1, y = new_net_emiss + 1)) +
  geom_point(alpha = 0.3, color = "#756bb1", size = 1.2) +
  geom_abline(
    intercept = 0,
    slope = 1,
    linetype = "dashed",
    color = "firebrick",
    linewidth = 0.8
  ) +
  scale_x_log10(labels = label_comma()) +
  scale_y_log10(labels = label_comma()) +
  facet_wrap(~level, scales = "free") +
  labs(
    title = "QA Check: Total Soy Net CO2 Emissions Across Spatial Levels",
    subtitle = "New pipeline (Q3 2026) vs. Legacy pipeline (Q4 2025) (+1 log shift)",
    x = "Legacy Pipeline Net Emissions (tCO2)",
    y = "New Pipeline Net Emissions (tCO2)"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    panel.grid.minor = element_blank(),
    plot.title = element_text(face = "bold")
  )

# 9b. Municipal Level Net Emissions Comparison Highlighted by Biome
ggplot(
  qa_muni,
  aes(x = leg_net_emiss + 1, y = new_net_emiss + 1, color = YEAR)
) +
  geom_point(alpha = 0.4, size = 1.5) +
  geom_abline(
    intercept = 0,
    slope = 1,
    linetype = "dashed",
    color = "black",
    linewidth = 0.8
  ) +
  scale_x_log10(labels = label_comma()) +
  scale_y_log10(labels = label_comma()) +
  scale_color_viridis_c(option = "viridis", na.value = "grey50") +
  labs(
    title = "QA Check: Municipal Total Soy Net CO2 Emissions Discrepancies by Biome",
    subtitle = "Points aligned along the dashed line show strong parity; colored by predominant biome",
    x = "Legacy Pipeline Net Emissions (tCO2 + 1)",
    y = "New Pipeline Net Emissions (tCO2 + 1)",
    color = "Year"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    panel.grid.minor = element_blank(),
    plot.title = element_text(face = "bold"),
    legend.position = "right",
    legend.title = element_text(face = "bold")
  ) +
  facet_wrap(~BIOME)

Internal Validation: Forest vs. Non-Forest Breakdown (New Pipeline)

# 10a. Forest vs Non-Forest Soy Deforestation Trends over Time by Biome
df_fn_long_ha <- qa_muni %>%
  group_by(YEAR, BIOME) %>%
  summarise(
    Forest = sum(new_forest_def_ha, na.rm = TRUE),
    `Non-Forest` = sum(new_non_forest_def_ha, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  pivot_longer(
    cols = c(Forest, `Non-Forest`),
    names_to = "land_cover",
    values_to = "deforestation_ha"
  )

ggplot(df_fn_long_ha, aes(x = YEAR, y = deforestation_ha, fill = land_cover)) +
  geom_col(position = "stack") +
  scale_y_continuous(labels = label_comma()) +
  scale_fill_manual(
    values = c("Forest" = "#2b83ba", "Non-Forest" = "#fdae61")
  ) +
  labs(
    title = "New Pipeline: Forest vs. Non-Forest Soy Deforestation Area by Biome",
    subtitle = "Annual breakdown of soy deforestation across major biomes",
    x = "Year",
    y = "Deforestation Area (ha)",
    fill = "Land Cover Class"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    panel.grid.minor = element_blank(),
    plot.title = element_text(face = "bold"),
    legend.position = "bottom"
  ) +
  facet_wrap(~BIOME, scales = "free_y")

# 10b. Forest vs Non-Forest Soy Gross CO2 Emissions Trends over Time by Biome
df_fn_long_emiss <- qa_muni %>%
  group_by(YEAR, BIOME) %>%
  summarise(
    Forest = sum(new_gross_emiss_forest, na.rm = TRUE),
    `Non-Forest` = sum(new_gross_emiss_non_forest, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  pivot_longer(
    cols = c(Forest, `Non-Forest`),
    names_to = "land_cover",
    values_to = "emissions_tco2"
  )

ggplot(df_fn_long_emiss, aes(x = YEAR, y = emissions_tco2, fill = land_cover)) +
  geom_col(position = "stack") +
  scale_y_continuous(labels = label_comma()) +
  scale_fill_manual(
    values = c("Forest" = "#006837", "Non-Forest" = "#a6d96a")
  ) +
  labs(
    title = "New Pipeline: Forest vs. Non-Forest Soy Gross CO2 Emissions by Biome",
    subtitle = "Annual breakdown of soy gross emissions across major biomes",
    x = "Year",
    y = "Gross CO2 Emissions (tCO2)",
    fill = "Land Cover Class"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    panel.grid.minor = element_blank(),
    plot.title = element_text(face = "bold"),
    legend.position = "bottom"
  ) +
  facet_wrap(~BIOME, scales = "free_y")