En el contexto de la agroclimatología y la planificación territorial, resulta fundamental comprender cómo las condiciones climáticas influyen en la aptitud de diferentes regiones para el cultivo de especies agrícolas estratégicas como la caña de azúcar. Factores como la temperatura y la precipitación determinan en gran medida la productividad potencial del cultivo, por lo que el análisis espacial del clima permite identificar zonas favorables, evaluar riesgos y orientar decisiones relacionadas con expansión agrícola, sostenibilidad y adaptación al cambio climático.
A partir de información climática global de línea base, se busca construir mapas de aptitud climática para la caña de azúcar utilizando rangos óptimos de variables ambientales asociados al desarrollo del cultivo. Asimismo, se pretende explorar la distribución espacial de áreas con alto potencial productivo en distintos países del mundo, así como comparar dichas zonas con regiones agrícolas reconocidas por su producción cañera.
Adicionalmente, se busca analizar condiciones climáticas específicas dentro del Valle del Cauca, una de las principales regiones productoras de caña de azúcar en Colombia, mediante la selección de algunos puntos geográficos y la extracción de información climática asociada. Finalmente, se pretende evaluar la similitud climática entre estas zonas y otras regiones del mundo utilizando métricas cuantitativas como la distancia euclidiana, con el fin de identificar territorios con características ambientales comparables.
Este análisis permitirá generar una visión integral de la distribución espacial de la aptitud climática para la caña de azúcar, identificar regiones con condiciones favorables para el cultivo y comparar diferentes metodologías de caracterización agroclimática. Los resultados pueden servir como apoyo para procesos de planificación agrícola, evaluación de expansión productiva, priorización de inversiones y formulación de estrategias de adaptación frente a variaciones climáticas futuras.
El objetivo es desarrollar un análisis espacial y climático que permita identificar regiones con condiciones adecuadas para el cultivo de caña de azúcar a escala global, utilizando información climática de línea base y herramientas de análisis geográfico en R. Para ello, se busca construir mapas de aptitud climática a partir de rangos óptimos de temperatura y precipitación, así como identificar países y regiones con alto potencial productivo.
Adicionalmente, se pretende analizar el comportamiento climático de algunos puntos representativos del Valle del Cauca mediante la extracción y visualización de series de tiempo de temperatura y precipitación. Posteriormente, se busca aplicar métricas de similaridad climática para identificar regiones del mundo con condiciones comparables a las observadas en el Valle del Cauca y contrastar los resultados obtenidos mediante diferentes aproximaciones metodológicas.
Con esta información será posible evaluar patrones espaciales de aptitud agrícola, identificar similitudes climáticas entre regiones productoras y generar insumos útiles para la planificación agroindustrial y territorial asociada al cultivo de caña de azúcar.
En este caso se tienen 5 preguntas a resolver:
¿Qué regiones del mundo presentan condiciones climáticas óptimas para el cultivo de caña de azúcar según los rangos ideales de temperatura y precipitación?
¿Qué países concentran áreas de alto potencial climático para la caña de azúcar y cómo se distribuyen espacialmente dichas zonas dentro de su territorio?
¿Cómo se comportan las variables climáticas de temperatura y precipitación en algunos puntos representativos del Valle del Cauca?
¿Qué regiones del mundo presentan condiciones climáticas similares a las observadas en los puntos seleccionados del Valle del Cauca según métricas de similaridad climática?
¿Qué diferencias y similitudes se observan entre los mapas generados mediante la aproximación de aptitud climática y aquellos obtenidos a partir de métricas de similaridad?
Los tipos de variable de acuerdo con su naturaleza son los siguientes:
library(dplyr)
library(knitr)
tabla_variables <- tibble::tibble(
Variable = paste0("BIO", 1:19),
Nombre_bioclimatico = c(
"Annual Mean Temperature",
"Mean Diurnal Range",
"Isothermality",
"Temperature Seasonality",
"Max Temperature of Warmest Month",
"Min Temperature of Coldest Month",
"Temperature Annual Range",
"Mean Temperature of Wettest Quarter",
"Mean Temperature of Driest Quarter",
"Mean Temperature of Warmest Quarter",
"Mean Temperature of Coldest Quarter",
"Annual Precipitation",
"Precipitation of Wettest Month",
"Precipitation of Driest Month",
"Precipitation Seasonality",
"Precipitation of Wettest Quarter",
"Precipitation of Driest Quarter",
"Precipitation of Warmest Quarter",
"Precipitation of Coldest Quarter"
),
Que_mide = c(
"Temperatura media anual",
"Rango medio diurno de temperatura",
"Relación entre variación diaria y anual de temperatura",
"Variabilidad anual de temperatura",
"Temperatura máxima del mes más cálido",
"Temperatura mínima del mes más frío",
"Diferencia entre temperaturas extremas anuales",
"Temperatura media del trimestre más lluvioso",
"Temperatura media del trimestre más seco",
"Temperatura media del trimestre más cálido",
"Temperatura media del trimestre más frío",
"Precipitación total anual",
"Precipitación del mes más lluvioso",
"Precipitación del mes más seco",
"Variabilidad de precipitación",
"Precipitación del trimestre más lluvioso",
"Precipitación del trimestre más seco",
"Precipitación del trimestre más cálido",
"Precipitación del trimestre más frío"
),
Unidad = c(
"°C (×10)",
"°C (×10)",
"%",
"Desviación estándar ×100",
"°C (×10)",
"°C (×10)",
"°C (×10)",
"°C (×10)",
"°C (×10)",
"°C (×10)",
"°C (×10)",
"mm",
"mm",
"mm",
"Coeficiente de variación",
"mm",
"mm",
"mm",
"mm"
),
Relevancia_cana = c(
"Muy alta. Determina productividad general y duración del ciclo",
"Media. Alta amplitud térmica puede generar estrés fisiológico",
"Baja-media. Describe estabilidad térmica",
"Media. La caña prefiere baja estacionalidad térmica",
"Muy alta. Relacionada con estrés térmico y reducción de sacarosa",
"Muy alta. La caña es sensible al frío y heladas",
"Media. Alta amplitud puede indicar climas menos favorables",
"Media-alta. Influye en crecimiento vegetativo",
"Alta. Importante para maduración y acumulación de azúcar",
"Muy alta. Relacionada con productividad potencial",
"Alta. Útil para evaluar limitaciones térmicas",
"Muy alta. Principal determinante hídrico",
"Media. Exceso de lluvia puede afectar cosecha y enfermedades",
"Alta. Indica riesgo de estrés hídrico",
"Alta. La caña requiere cierto balance entre humedad y estación seca",
"Alta. Relacionada con crecimiento máximo",
"Muy alta. Fundamental para evaluar necesidad de riego",
"Muy útil. Alta relevancia para productividad en zonas tropicales",
"Media-baja. Menos crítica en regiones tropicales cálidas"
)
)
kable(
tabla_variables,
caption = "Descripción de las variables bioclimáticas BIO utilizadas en el análisis de aptitud climática para caña de azúcar"
)
| Variable | Nombre_bioclimatico | Que_mide | Unidad | Relevancia_cana |
|---|---|---|---|---|
| BIO1 | Annual Mean Temperature | Temperatura media anual | °C (×10) | Muy alta. Determina productividad general y duración del ciclo |
| BIO2 | Mean Diurnal Range | Rango medio diurno de temperatura | °C (×10) | Media. Alta amplitud térmica puede generar estrés fisiológico |
| BIO3 | Isothermality | Relación entre variación diaria y anual de temperatura | % | Baja-media. Describe estabilidad térmica |
| BIO4 | Temperature Seasonality | Variabilidad anual de temperatura | Desviación estándar ×100 | Media. La caña prefiere baja estacionalidad térmica |
| BIO5 | Max Temperature of Warmest Month | Temperatura máxima del mes más cálido | °C (×10) | Muy alta. Relacionada con estrés térmico y reducción de sacarosa |
| BIO6 | Min Temperature of Coldest Month | Temperatura mínima del mes más frío | °C (×10) | Muy alta. La caña es sensible al frío y heladas |
| BIO7 | Temperature Annual Range | Diferencia entre temperaturas extremas anuales | °C (×10) | Media. Alta amplitud puede indicar climas menos favorables |
| BIO8 | Mean Temperature of Wettest Quarter | Temperatura media del trimestre más lluvioso | °C (×10) | Media-alta. Influye en crecimiento vegetativo |
| BIO9 | Mean Temperature of Driest Quarter | Temperatura media del trimestre más seco | °C (×10) | Alta. Importante para maduración y acumulación de azúcar |
| BIO10 | Mean Temperature of Warmest Quarter | Temperatura media del trimestre más cálido | °C (×10) | Muy alta. Relacionada con productividad potencial |
| BIO11 | Mean Temperature of Coldest Quarter | Temperatura media del trimestre más frío | °C (×10) | Alta. Útil para evaluar limitaciones térmicas |
| BIO12 | Annual Precipitation | Precipitación total anual | mm | Muy alta. Principal determinante hídrico |
| BIO13 | Precipitation of Wettest Month | Precipitación del mes más lluvioso | mm | Media. Exceso de lluvia puede afectar cosecha y enfermedades |
| BIO14 | Precipitation of Driest Month | Precipitación del mes más seco | mm | Alta. Indica riesgo de estrés hídrico |
| BIO15 | Precipitation Seasonality | Variabilidad de precipitación | Coeficiente de variación | Alta. La caña requiere cierto balance entre humedad y estación seca |
| BIO16 | Precipitation of Wettest Quarter | Precipitación del trimestre más lluvioso | mm | Alta. Relacionada con crecimiento máximo |
| BIO17 | Precipitation of Driest Quarter | Precipitación del trimestre más seco | mm | Muy alta. Fundamental para evaluar necesidad de riego |
| BIO18 | Precipitation of Warmest Quarter | Precipitación del trimestre más cálido | mm | Muy útil. Alta relevancia para productividad en zonas tropicales |
| BIO19 | Precipitation of Coldest Quarter | Precipitación del trimestre más frío | mm | Media-baja. Menos crítica en regiones tropicales cálidas |
El objeto cmip corresponde a un conjunto de capas raster
multivariadas provenientes de WorldClim versión 2.1 y proyecciones
climáticas CMIP6.
Características principales:
SpatRasterLas variables BIO sintetizan condiciones de temperatura y precipitación mediante métricas ecológicamente relevantes, ampliamente utilizadas en modelación climática, análisis agroclimático y distribución potencial de especies.
No se reportan valores faltantes significativos en zonas continentales. Los valores NA corresponden principalmente a océanos o regiones sin cobertura climática válida.
Utilizando el paquete geodata, se realiza el caché de datos de WorldClim. El archivo seleccionado contiene las 19 variables BIO de WorldClim para:
modelo: EC-Earth Consortium EC-Earth3-Veg escenario: SSP245 periodo: 2041–2060 resolución: 2.5 minutos
path_act<-"C:/Users/User/Documents/2025 PUJ R projects/Modulo 1 - Unidad 1 - AIGE/Casos/"
library(geodata)
cmip <- load_or_download_cmip(
model = "EC-Earth3-Veg",
ssp = "245",
time = "2041-2060",
var = "bio",
res = 2.5,
path = "data/"
)
## Descargando archivo...
names(cmip) <- paste0("BIO", 1:19)
names(cmip)
## [1] "BIO1" "BIO2" "BIO3" "BIO4" "BIO5" "BIO6" "BIO7" "BIO8" "BIO9"
## [10] "BIO10" "BIO11" "BIO12" "BIO13" "BIO14" "BIO15" "BIO16" "BIO17" "BIO18"
## [19] "BIO19"
bio1 <- cmip[["BIO1"]]
bio5 <- cmip[["BIO5"]]
bio6 <- cmip[["BIO6"]]
bio12 <- cmip[["BIO12"]]
bio15 <- cmip[["BIO15"]]
bio17 <- cmip[["BIO17"]]
bio18 <- cmip[["BIO18"]]
global(bio5, c("min","max"), na.rm=TRUE)
## min max
## BIO5 -29.4 51.2
global(bio12, c("min","max"), na.rm=TRUE)
## min max
## BIO12 0 11693
Para responder a la pregunta se ejecutan los siguientes pasos:
Para crear funciones de aptitud se cargan las siguientes variables que se consideran de mayor relevancia para el cultivo de caña:
Óptimo:
24–30°C
s_bio1 <- classify(
bio1,
rcl = matrix(c(
-Inf, 20, 0,
20, 24, 0.5,
24, 30, 1,
30, 34, 0.5,
34, Inf, 0
), ncol=3, byrow=TRUE)
)
## |---------|---------|---------|---------|=========================================
Temperaturas muy altas (Tmax) afectan sacarosa, por lo cual no es deseable contar con
s_bio5 <- classify(
bio5,
rcl = matrix(c(
-Inf, 32, 1,
32, 36, 0.7,
36, 40, 0.3,
40, Inf, 0
), ncol=3, byrow=TRUE)
)
## |---------|---------|---------|---------|=========================================
La caña es sensible al frío.
s_bio6 <- classify(
bio6,
rcl = matrix(c(
-Inf, 5, 0,
5, 10, 0.5,
10, Inf, 1
), ncol=3, byrow=TRUE)
)
## |---------|---------|---------|---------|=========================================
s_bio12 <- classify(
bio12,
rcl = matrix(c(
-Inf, 800, 0,
800, 1200, 0.5,
1200, 2500, 1,
2500, 3500, 0.5,
3500, Inf, 0
), ncol=3, byrow=TRUE)
)
## |---------|---------|---------|---------|=========================================
Demasiada variabilidad puede ser problemática.
s_bio15 <- classify(
bio15,
rcl = matrix(c(
-Inf, 40, 1,
40, 70, 0.7,
70, 100, 0.3,
100, Inf, 0
), ncol=3, byrow=TRUE)
)
## |---------|---------|---------|---------|=========================================
s_bio17 <- classify(
bio17,
rcl = matrix(c(
-Inf, 50, 0,
50, 150, 0.5,
150, Inf, 1
), ncol=3, byrow=TRUE)
)
## |---------|---------|---------|---------|=========================================
s_bio18 <- classify(
bio18,
rcl = matrix(c(
-Inf, 300, 0.3,
300, 800, 1,
800, 1500, 0.7,
1500, Inf, 0.3
), ncol=3, byrow=TRUE)
)
## |---------|---------|---------|---------|=========================================
Promedio simple
# Verificar si existe el raster final
if (!file.exists("cache/sugarcane_index.tif")) {
sugarcane_index <- (
s_bio1 +
s_bio5 +
s_bio6 +
s_bio12 +
s_bio15 +
s_bio17 +
s_bio18
) / 7
sugarcane_index <- writeRaster(
sugarcane_index,
"cache/sugarcane_index.tif",
overwrite = TRUE
)
} else {
sugarcane_index <- rast(
"cache/sugarcane_index.tif"
)
}
Como resultado se obtiene el índice de aptitud climática:
El objeto sugarcane_index corresponde a un raster
continuo de aptitud climática para el cultivo de caña de azúcar
construido mediante análisis multicriterio.
Características principales:
SpatRasterEl índice se construye a partir de siete variables bioclimáticas relacionadas con temperatura, precipitación y estacionalidad climática:
Cada variable fue reclasificada según rangos óptimos reportados para el cultivo de caña de azúcar y posteriormente integrada mediante promedio simple.
Valores cercanos a 1 representan condiciones climáticas más favorables para el cultivo.
plot(
sugarcane_index,
main="Índice de aptitud climática para caña de azúcar"
)
library(tibble)
library(knitr)
tabla_aptitud <- tibble(
Valor = c(
"0–0.2",
"0.2–0.4",
"0.4–0.6",
"0.6–0.8",
"0.8–1"
),
Interpretacion = c(
"No apto",
"Baja aptitud",
"Aptitud moderada",
"Alta aptitud",
"Muy alta aptitud"
)
)
kable(
tabla_aptitud,
caption = "Clasificación del índice de aptitud climática para caña de azúcar"
)
| Valor | Interpretacion |
|---|---|
| 0–0.2 | No apto |
| 0.2–0.4 | Baja aptitud |
| 0.4–0.6 | Aptitud moderada |
| 0.6–0.8 | Alta aptitud |
| 0.8–1 | Muy alta aptitud |
la idea es:
#library(terra)
library(geodata)
library(dplyr)
world <- world(path = "data/")
tabla_categorias <- tibble(
Categoria = c(
"No apto",
"Baja",
"Moderada",
"Alta",
"Muy alta"
),
Rango = c(
"0–0.2",
"0.2–0.4",
"0.4–0.6",
"0.6–0.8",
"0.8–1"
)
)
kable(
tabla_categorias,
caption = "Categorías del índice de aptitud climática para caña de azúcar"
)
| Categoria | Rango |
|---|---|
| No apto | 0–0.2 |
| Baja | 0.2–0.4 |
| Moderada | 0.4–0.6 |
| Alta | 0.6–0.8 |
| Muy alta | 0.8–1 |
El objeto elev corresponde a un raster global de elevación descargado desde WorldClim.
Características principales:
Tipo de objeto: SpatRaster Número de capas: 1 Resolución espacial: 2.5 minutos (~5 km) Cobertura espacial: global Sistema de referencia: WGS84 (EPSG:4326) Unidad de medida: metros sobre el nivel del mar (msnm) Fuente: WorldClim v2.1
La variable representa la altitud promedio por celda raster y se utiliza para restringir áreas potencialmente aptas para el cultivo de caña de azúcar, dado que este cultivo presenta limitaciones fisiológicas importantes en zonas de alta montaña.
Los valores faltantes corresponden principalmente a océanos.
elev <- worldclim_global(
var = "elev",
res = 2.5,
path = "data/"
)
sugarcane_index <- mask(
sugarcane_index,
elev < 1500,
maskvalues = FALSE
)
## |---------|---------|---------|---------|========================================= |---------|---------|---------|---------|=========================================
names(sugarcane_index) <- "suitability_index"
aptitud_cat <- classify(
sugarcane_index,
rcl = matrix(c(
0.0, 0.2, 1,
0.2, 0.4, 2,
0.4, 0.6, 3,
0.6, 0.8, 4,
0.8, 1.0, 5
),
ncol = 3,
byrow = TRUE)
)
## |---------|---------|---------|---------|=========================================
#
# aptitud_cat <- writeRaster(
# aptitud_cat,
# "cache/aptitud_cat.tif",
# overwrite = TRUE
# )
high_suitability <- ifel(
aptitud_cat >= 4,
1,
0
)
## |---------|---------|---------|---------|========================================= |---------|---------|---------|---------|========================================= |---------|---------|---------|---------|=========================================
high_suitability <- writeRaster(
high_suitability,
"cache/high_suitability.tif",
overwrite = TRUE
)
## |---------|---------|---------|---------|=========================================
Cada pixel tiene diferente tamaño según latitud.
high_suitability <- rast(
"cache/high_suitability.tif"
)
pixel_area <- cellSize(
high_suitability,
unit = "km"
)
## |---------|---------|---------|---------|=========================================
pixel_area <- writeRaster(
pixel_area,
"cache/pixel_area.tif",
overwrite = TRUE
)
## |---------|---------|---------|---------|=========================================
high_suitability <- rast(
"cache/high_suitability.tif"
)
pixel_area <- rast(
"cache/pixel_area.tif"
)
high_area <- cache_raster(
"cache/high_area.tif",
{
high_suitability * pixel_area
}
)
## Leyendo raster desde cache:
## cache/high_area.tif
names(high_area) <- "area_km2"
world <- geodata::world(
path = "data/"
)
country_area <- cache_rds(
"cache/country_area.rds",
{
x <- terra::extract(
high_area,
world,
fun = sum,
na.rm = TRUE
)
names(x)[2] <- "area_km2"
### Agregar nombres de países
x$country <- world$NAME_0
### Limpiar y ordenar
x <- x %>%
filter(
!is.na(area_km2)
) %>%
arrange(
desc(area_km2)
)
x
}
)
## Leyendo desde cache:
## cache/country_area.rds
names(country_area)
## [1] "ID" "area_km2" "country"
library(terra)
library(dplyr)
library(ggplot2)
#library(tidyterra)
# Top 20
top20 <- country_area %>%
arrange(desc(area_km2)) %>%
slice(1:20)
# Unir tabla al SpatVector
world_top <- merge(
world,
top20,
by.x = "NAME_0",
by.y = "country",
all.x = FALSE
)
# Graficar
library(tidyterra)
library(ggplot2)
ggplot() +
geom_spatvector(
data = world_top,
aes(fill = area_km2),
color = "black",
linewidth = 0.2
) +
scale_fill_viridis_c(
option = "C"
) +
coord_sf(
xlim = c(-120,160),
ylim = c(-40,40)
) +
labs(
title = "Países con mayor superficie de alta aptitud climática",
subtitle = "Caña de azúcar — SSP245 (2041–2060)"
) +
theme_minimal()
library(knitr)
# Tabla final
kable(
head(
country_area[, c("country", "area_km2")],
20
),
digits = 0,
col.names = c(
"País",
"Área apta (km²)"
),
caption = "Países con mayor superficie de alta aptitud climática para caña de azúcar"
)
| País | Área apta (km²) |
|---|---|
| Brazil | 6917079 |
| Democratic Republic of the Congo | 1989998 |
| Indonesia | 1788169 |
| United States | 1622461 |
| Canada | 1062994 |
| China | 998261 |
| Colombia | 918876 |
| Peru | 701404 |
| Venezuela | 662897 |
| Bolivia | 591271 |
| Australia | 514593 |
| Argentina | 436336 |
| Angola | 405490 |
| Papua New Guinea | 387225 |
| Central African Republic | 382498 |
| Mexico | 372057 |
| Cameroon | 344625 |
| Congo | 341650 |
| India | 338760 |
| Malaysia | 326608 |
aptitud_cat <- rast(
"cache/aptitud_cat.tif"
)
world_plot <- geodata::world(
path = "data/"
)
plot(
aptitud_cat,
main = "Aptitud climática mundial para caña de azúcar"
)
lines(world_plot)
elev <- cache_raster(
"cache/elev_2_5m.tif",
{
worldclim_global(
var = "elev",
res = 2.5,
path = "data/"
)
}
)
## Leyendo raster desde cache:
## cache/elev_2_5m.tif
pts <- vect(
data.frame(
sitio = c(
"Cartago",
"Palmira",
"Cali",
"Buga",
"Tulua"
),
lon = c(
-75.91,
-76.30,
-76.53,
-76.30,
-76.20
),
lat = c(
4.75,
3.54,
3.45,
3.90,
4.08
)
),
geom = c("lon","lat"),
crs = "EPSG:4326"
)
altitud <- cache_rds(
"cache/altitud_pts.rds",
{
terra::extract(
elev,
pts
)
}
)
## Leyendo desde cache:
## cache/altitud_pts.rds
pts$altitud_m <- altitud[[2]]
El objeto pr_current corresponde a un conjunto raster multitemporal de precipitación mensual promedio.
Características principales:
Tipo de objeto: SpatRaster Número de capas: 12 (una por cada mes) Resolución espacial: 2.5 minutos Cobertura espacial: global Sistema de referencia: WGS84 (EPSG:4326) Unidad de medida: milímetros (mm) Fuente: WorldClim v2.1
Cada capa representa la precipitación acumulada promedio mensual para condiciones climáticas históricas de referencia.
Estas variables permiten caracterizar la distribución intra-anual de lluvias y evaluar patrones de estacionalidad hídrica relevantes para el cultivo de caña de azúcar.
pr_current <- cache_raster(
"cache/prec_current.tif",
{
geodata::worldclim_global(
var = "prec",
res = 2.5,
path = "data/"
)
}
)
## Leyendo raster desde cache:
## cache/prec_current.tif
El objeto tmin_current corresponde a un conjunto raster de temperatura mínima mensual promedio.
Características principales:
Tipo de objeto: SpatRaster Número de capas: 12 Resolución espacial: 2.5 minutos Cobertura espacial: global Sistema de referencia: WGS84 (EPSG:4326) Unidad de medida: °C Fuente: WorldClim v2.1
Las temperaturas fueron ajustadas dividiendo los valores originales entre 10 debido a la escala utilizada por WorldClim.
Estas variables permiten evaluar condiciones térmicas mínimas relevantes para el crecimiento y posibles restricciones fisiológicas del cultivo.
tmin_current <- cache_raster(
"cache/tmin_current.tif",
{
geodata::worldclim_global(
var = "tmin",
res = 2.5,
path = "data/"
) / 10
}
)
## Leyendo raster desde cache:
## cache/tmin_current.tif
El objeto tmax_current corresponde a un conjunto raster de temperatura máxima mensual promedio.
Características principales:
Tipo de objeto: SpatRaster Número de capas: 12 Resolución espacial: 2.5 minutos Cobertura espacial: global Sistema de referencia: WGS84 (EPSG:4326) Unidad de medida: °C Fuente: WorldClim v2.1
Las variables permiten analizar condiciones de calor extremo y posibles efectos de estrés térmico sobre la productividad potencial de la caña de azúcar.
tmax_current <- worldclim_global(
var = "tmax",
res = 2.5,
path = "data/"
)
prec_vals <- cache_rds(
"cache/prec_vals.rds",
{
terra::extract(
pr_current,
pts
)
}
)
## Leyendo desde cache:
## cache/prec_vals.rds
tmin_vals <- cache_rds(
"cache/tmin_vals.rds",
{
terra::extract(
tmin_current,
pts
)
}
)
## Leyendo desde cache:
## cache/tmin_vals.rds
tmax_vals <- cache_rds(
"cache/tmax_vals.rds",
{
terra::extract(
tmax_current,
pts
)
}
)
## Leyendo desde cache:
## cache/tmax_vals.rds
temp_mean <- (
tmin_vals[,-1] +
tmax_vals[,-1]
) / 2
El objeto pts corresponde a un conjunto de puntos geográficos seleccionados dentro del Valle del Cauca.
Características principales:
Tipo de objeto: SpatVector Número de observaciones: 5 Tipo geométrico: puntos Sistema de referencia: WGS84 (EPSG:4326)
Los puntos representan municipios estratégicos de la región cañera del Valle del Cauca:
Cartago Palmira Cali Buga Tuluá
Para cada punto se analizaron condiciones de temperatura, precipitación y similaridad climática global.
pts <- vect(
data.frame(
sitio = c(
"Cartago",
"Palmira",
"Cali",
"Buga",
"Tulua"
),
lon = c(
-75.91,
-76.30,
-76.53,
-76.30,
-76.20
),
lat = c(
4.75,
3.54,
3.45,
3.90,
4.08
)
),
geom = c("lon","lat"),
crs = "EPSG:4326"
)
writeVector(
pts,
"cache/pts.gpkg",
overwrite = TRUE
)
## Crear vector de meses
meses <- c(
"Ene","Feb","Mar","Abr","May","Jun",
"Jul","Ago","Sep","Oct","Nov","Dic"
)
pts <- vect(
"cache/pts.gpkg"
)
temp_df <- as.data.frame(temp_mean)
names(temp_df) <- meses
temp_df$sitio <- pts$sitio
temp_long <- pivot_longer(
temp_df,
cols = all_of(meses),
names_to = "mes",
values_to = "temperatura"
)
prec_df <- as.data.frame(
prec_vals[,-1]
)
names(prec_df) <- meses
prec_df$sitio <- pts$sitio
prec_long <- pivot_longer(
prec_df,
cols = all_of(meses),
names_to = "mes",
values_to = "precipitacion"
)
temp_long$mes <- factor(
temp_long$mes,
levels = meses,
ordered = TRUE
)
ggplot(
temp_long,
aes(
x = mes,
y = temperatura,
color = sitio,
group = sitio
)
) +
geom_line(linewidth = 1.1) +
geom_point(size = 2) +
labs(
title = "Temperatura media mensual",
subtitle = "Puntos representativos del Valle del Cauca",
x = "Mes - último año",
y = "Temperatura (°C)"
) +
theme_minimal()
prec_long$mes <- factor(
prec_long$mes,
levels = meses,
ordered = TRUE
)
ggplot(
prec_long,
aes(
x = mes,
y = precipitacion,
color = sitio,
group = sitio
)
) +
geom_line(linewidth = 1.1) +
geom_point(size = 2) +
labs(
title = "Precipitación mensual",
subtitle = "Puntos representativos del Valle del Cauca",
x = "Mes",
y = "Precipitación (mm)"
) +
theme_minimal()
## Reconstruir puntos completamente
pts_df <- data.frame(
sitio = c(
"Cartago",
"Palmira",
"Cali",
"Buga",
"Tulua"
),
lon = c(
-75.91,
-76.30,
-76.53,
-76.30,
-76.20
),
lat = c(
4.75,
3.54,
3.45,
3.90,
4.08
),
altitud_m = as.numeric(c(
917,
1001,
1018,
969,
960
))
)
## Crear nuevamente el SpatVector
pts <- terra::vect(
pts_df,
geom = c("lon","lat"),
crs = "EPSG:4326"
)
## Extraer coordenadas
coords <- terra::crds(pts)
## Tabla final
tabla_puntos <- data.frame(
Sitio = pts_df$sitio,
Longitud = round(coords[,1], 3),
Latitud = round(coords[,2], 3),
Altitud_m = round(
pts_df$altitud_m,
0
)
)
## Mostrar tabla
knitr::kable(
tabla_puntos,
digits = 3,
caption = "Puntos representativos seleccionados en el Valle del Cauca"
)
| Sitio | Longitud | Latitud | Altitud_m |
|---|---|---|---|
| Cartago | -75.91 | 4.75 | 917 |
| Palmira | -76.30 | 3.54 | 1001 |
| Cali | -76.53 | 3.45 | 1018 |
| Buga | -76.30 | 3.90 | 969 |
| Tulua | -76.20 | 4.08 | 960 |
Identificar regiones del mundo con condiciones climáticas similares a las observadas en distintos puntos representativos del Valle del Cauca mediante métricas de distancia climática construidas a partir de variables bioclimáticas de temperatura y precipitación.
Se utilizan variables bioclimáticas relacionadas con:
Posteriormente:
Las zonas resaltadas representan las regiones del mundo con condiciones ambientales más similares a cada punto del Valle del Cauca.
## =========================
## Cargar CMIP6 con cache
## =========================
cmip <- cache_raster(
"cache/cmip_bio_2041_2060.tif",
{
geodata::cmip6_world(
model = "EC-Earth3-Veg",
ssp = "245",
time = "2041-2060",
var = "bio",
res = 2.5,
path = "data/"
)
}
)
## Leyendo raster desde cache:
## cache/cmip_bio_2041_2060.tif
## Renombrar variables BIO
names(cmip) <- paste0(
"BIO",
1:19
)
## Variables bioclimáticas relevantes
bio_vars <- c(
"BIO1",
"BIO5",
"BIO6",
"BIO12",
"BIO15",
"BIO17",
"BIO18"
)
## Crear stack reducido
bio_stack <- cmip[[bio_vars]]
bio_stack
## class : SpatRaster
## size : 4320, 8640, 7 (nrow, ncol, nlyr)
## resolution : 0.04166667, 0.04166667 (x, y)
## extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326)
## source : cmip_bio_2041_2060.tif
## names : BIO1, BIO5, BIO6, BIO12, BIO15, BIO17, ...
## min values : -53.3, -29.4, -71.5, 0, 0.0, 0, ...
## max values : 33.4, 51.2, 27.8, 11693, 230.7, 1524, ...
pts_climate <- cache_rds(
"cache/pts_climate.rds",
{
terra::extract(
bio_stack,
pts
)
}
)
## Leyendo desde cache:
## cache/pts_climate.rds
La estandarización evita que variables con escalas grandes dominen el cálculo de distancia climática.
global_values <- values(
bio_stack
)
complete_rows <- complete.cases(
global_values
)
global_matrix <- global_values[
complete_rows,
]
clim_matrix <- scale(
global_matrix
)
centers <- attr(
clim_matrix,
"scaled:center"
)
scales <- attr(
clim_matrix,
"scaled:scale"
)
library(terra)
library(ggplot2)
library(tidyterra)
library(dplyr)
library(terra)
library(ggplot2)
library(tidyterra)
library(dplyr)
library(tidyr)
#========================================
# RECARGAR CMIP DESDE CACHE
#========================================
cmip <- cache_raster(
"cache/cmip_bio.tif",
{
x <- load_or_download_cmip(
model = "EC-Earth3-Veg",
ssp = "245",
time = "2041-2060",
var = "bio",
res = 2.5,
path = "data/"
)
names(x) <- paste0("BIO", 1:19)
x
}
)
## Leyendo raster desde cache:
## cache/cmip_bio.tif
#========================================
# VARIABLES BIO
#========================================
bio_vars <- c(
"BIO1",
"BIO5",
"BIO6",
"BIO12",
"BIO15",
"BIO17",
"BIO18"
)
#========================================
# STACK REDUCIDO
#========================================
bio_stack <- cache_raster(
"cache/bio_stack_selected.tif",
{
cmip[[bio_vars]]
}
)
## Leyendo raster desde cache:
## cache/bio_stack_selected.tif
#========================================
# FRONTERAS
#========================================
world_plot <- geodata::world(
path = "data/"
)
#========================================
# INFORMACIÓN PUNTOS
#========================================
pts_info <- data.frame(
sitio = c(
"Cartago",
"Palmira",
"Cali",
"Buga",
"Tulua"
),
lon = c(
-75.91,
-76.30,
-76.53,
-76.30,
-76.20
),
lat = c(
4.75,
3.54,
3.45,
3.90,
4.08
)
)
#========================================
# PUNTOS VECTORIALES
#========================================
pts_vect <- vect(
pts_info,
geom = c("lon","lat"),
crs = "EPSG:4326"
)
#========================================
# EXTRAER CLIMA PUNTOS
#========================================
pts_climate <- cache_rds(
"cache/pts_climate_similarity.rds",
{
terra::extract(
bio_stack,
pts_vect
)
}
)
## Leyendo desde cache:
## cache/pts_climate_similarity.rds
#========================================
# MUESTREO GLOBAL
#========================================
bio_df <- cache_rds(
"cache/bio_df_global.rds",
{
spatSample(
bio_stack,
size = 200000,
method = "regular",
as.df = TRUE,
xy = TRUE,
na.rm = TRUE
)
}
)
## Leyendo desde cache:
## cache/bio_df_global.rds
#========================================
# LIMPIAR NAs
#========================================
bio_df_clean <- cache_rds(
"cache/bio_df_clean.rds",
{
bio_df %>%
drop_na(
all_of(bio_vars)
)
}
)
## Leyendo desde cache:
## cache/bio_df_clean.rds
#========================================
# MATRIZ CLIMÁTICA ESTANDARIZADA
#========================================
clim_objects <- cache_rds(
"cache/clim_matrix_objects.rds",
{
clim_matrix <- scale(
bio_df_clean[, bio_vars]
)
list(
clim_matrix = clim_matrix,
centers = attr(
clim_matrix,
"scaled:center"
),
scales = attr(
clim_matrix,
"scaled:scale"
)
)
}
)
## Leyendo desde cache:
## cache/clim_matrix_objects.rds
#========================================
# RECUPERAR OBJETOS
#========================================
clim_matrix <- clim_objects$clim_matrix
centers <- clim_objects$centers
scales <- clim_objects$scales
#========================================
# MATRIZ CLIMÁTICA
#========================================
clim_matrix <- scale(
bio_df_clean[, bio_vars]
)
centers <- attr(
clim_matrix,
"scaled:center"
)
scales <- attr(
clim_matrix,
"scaled:scale"
)
#========================================
# TEMPLATE RASTER NUEVO
#========================================
template_raster <- bio_stack[[1]]
template_raster <- rast(
"cache/bio_stack_selected.tif"
)[[1]]
#========================================
# LOOP DE MAPAS
#========================================
for(i in 1:nrow(pts_info)){
#-----------------------------------
# Información del punto
#-----------------------------------
sitio_actual <- pts_info$sitio[i]
lon_actual <- pts_info$lon[i]
lat_actual <- pts_info$lat[i]
#-----------------------------------
# Vector climático referencia
#-----------------------------------
ref <- pts_climate[
i,
bio_vars
]
ref_scaled <- scale(
ref,
center = centers,
scale = scales
)
#-----------------------------------
# Distancia climática
#-----------------------------------
dist_clim <- sqrt(
rowSums(
(
clim_matrix -
matrix(
as.numeric(ref_scaled),
nrow(clim_matrix),
length(bio_vars),
byrow = TRUE
)
)^2
)
)
#-----------------------------------
# Similaridad
#-----------------------------------
similarity_values <- 1 / (1 + dist_clim)
#-----------------------------------
# Percentil 95
#-----------------------------------
threshold <- quantile(
similarity_values,
probs = 0.95,
na.rm = TRUE
)
#-----------------------------------
# Dataframe espacial
#-----------------------------------
sim_df <- bio_df_clean[, c("x","y")]
sim_df$similar <- ifelse(
similarity_values >= threshold,
"Muy similar",
NA
)
sim_df <- sim_df %>%
filter(
!is.na(similar)
)
#-----------------------------------
# MAPA
#-----------------------------------
p <- ggplot() +
geom_point(
data = sim_df,
aes(
x = x,
y = y
),
color = "darkgreen",
alpha = 0.5,
size = 0.4
) +
geom_spatvector(
data = world_plot,
fill = NA,
color = "black",
linewidth = 0.2
) +
geom_point(
aes(
x = lon_actual,
y = lat_actual
),
color = "red",
size = 3
) +
coord_sf(
xlim = c(-120,160),
ylim = c(-40,40)
) +
labs(
title = paste(
"Regiones climáticamente similares a",
sitio_actual
),
subtitle = "Top 5% de regiones con mayor similaridad climática",
caption = paste(
"Variables utilizadas:",
paste(bio_vars, collapse = ", ")
)
) +
theme_minimal()
print(p)
gc()
}
Comparar espacialmente las regiones identificadas como altamente aptas para el cultivo de caña de azúcar con aquellas regiones que presentan alta similaridad climática respecto a los puntos seleccionados del Valle del Cauca.
La comparación permite evaluar:
Se comparan dos resultados previamente obtenidos:
Para cada punto se genera un mapa de superposición espacial con tres categorías:
library(terra)
library(ggplot2)
library(tidyterra)
library(dplyr)
#========================================
# CARGAR APTITUD
#========================================
high_suitability <- rast(
"cache/high_suitability.tif"
)
#========================================
# TEMPLATE
#========================================
template_raster <- rast(
"cache/bio_stack_selected.tif"
)[[1]]
#========================================
# FRONTERAS
#========================================
world_plot <- geodata::world(
path = "data/"
)
#========================================
# LOOP
#========================================
for(i in 1:nrow(pts_info)){
#-----------------------------------
# Información punto
#-----------------------------------
sitio_actual <- pts_info$sitio[i]
lon_actual <- pts_info$lon[i]
lat_actual <- pts_info$lat[i]
#-----------------------------------
# Referencia climática
#-----------------------------------
ref <- pts_climate[
i,
bio_vars
]
ref_scaled <- scale(
ref,
center = centers,
scale = scales
)
#-----------------------------------
# Distancia climática
#-----------------------------------
dist_clim <- sqrt(
rowSums(
(
clim_matrix -
matrix(
as.numeric(ref_scaled),
nrow(clim_matrix),
length(bio_vars),
byrow = TRUE
)
)^2
)
)
#-----------------------------------
# Similaridad
#-----------------------------------
similarity_values <- 1 / (1 + dist_clim)
threshold <- quantile(
similarity_values,
probs = 0.95,
na.rm = TRUE
)
#-----------------------------------
# Raster similaridad
#-----------------------------------
similarity_raster <- rast(
template_raster
)
values(similarity_raster) <- NA
cells <- cellFromXY(
template_raster,
bio_df_clean[, c("x","y")]
)
similarity_binary <- ifelse(
similarity_values >= threshold,
1,
NA
)
similarity_raster[cells] <- similarity_binary
#-----------------------------------
# COMPARACIÓN
#-----------------------------------
comparison <- high_suitability + (similarity_raster * 2)
names(comparison) <- "categoria"
#-----------------------------------
# DATAFRAME
#-----------------------------------
comparison_df <- as.data.frame(
comparison,
xy = TRUE,
na.rm = TRUE
)
names(comparison_df)[3] <- "categoria"
comparison_df$categoria <- factor(
comparison_df$categoria,
levels = c(1,2,3),
labels = c(
"Solo aptitud",
"Solo similaridad",
"Solapamiento"
)
)
#-----------------------------------
# MAPA
#-----------------------------------
p <- ggplot() +
geom_raster(
data = comparison_df,
aes(
x = x,
y = y,
fill = categoria
)
) +
scale_fill_manual(
values = c(
"Solo aptitud" = "orange",
"Solo similaridad" = "steelblue",
"Solapamiento" = "darkgreen"
),
na.value = "white",
name = "Clasificación"
) +
geom_spatvector(
data = world_plot,
fill = NA,
color = "black",
linewidth = 0.2
) +
geom_point(
aes(
x = lon_actual,
y = lat_actual
),
color = "red",
size = 3
) +
coord_sf(
xlim = c(-120,160),
ylim = c(-40,40)
) +
labs(
title = paste(
"Comparación entre aptitud y similaridad:",
sitio_actual
),
subtitle = "Superposición espacial de regiones aptas y regiones similares",
caption = "Verde = coincidencia entre ambas metodologías"
) +
theme_minimal()
print(p)
gc()
}
## |---------|---------|---------|---------|========================================= |---------|---------|---------|---------|========================================= |---------|---------|---------|---------|=========================================
## |---------|---------|---------|---------|========================================= |---------|---------|---------|---------|========================================= |---------|---------|---------|---------|=========================================
## |---------|---------|---------|---------|========================================= |---------|---------|---------|---------|========================================= |---------|---------|---------|---------|=========================================
## |---------|---------|---------|---------|========================================= |---------|---------|---------|---------|========================================= |---------|---------|---------|---------|=========================================
## |---------|---------|---------|---------|========================================= |---------|---------|---------|---------|========================================= |---------|---------|---------|---------|=========================================
Los mapas obtenidos mediante la aproximación de aptitud climática y aquellos construidos a partir de métricas de similaridad presentan importantes coincidencias espaciales, aunque responden a enfoques metodológicos diferentes.
Por un lado, el índice de aptitud climática identifica regiones que cumplen simultáneamente con rangos considerados óptimos para el cultivo de caña de azúcar. Esta metodología utiliza criterios agronómicos predefinidos asociados principalmente con temperatura, precipitación y estacionalidad climática. Como resultado, los mapas muestran grandes extensiones tropicales y subtropicales con condiciones favorables para el cultivo, especialmente en regiones de Brasil, India, Centroamérica, el sudeste asiático y África tropical.
Por otro lado, el análisis de similaridad climática no evalúa directamente la aptitud agrícola, sino el grado de parecido climático entre diferentes regiones del mundo y puntos específicos seleccionados en el Valle del Cauca. Para ello se utilizan métricas cuantitativas basadas en distancia euclidiana sobre variables bioclimáticas estandarizadas. Esta aproximación permite identificar regiones que presentan combinaciones climáticas comparables a las observadas localmente, independientemente de si dichas condiciones corresponden o no a rangos óptimos teóricos para la caña de azúcar.
Entre las principales similitudes se observa que ambas metodologías resaltan predominantemente regiones tropicales húmedas y cálidas. Esto sugiere que las condiciones climáticas del Valle del Cauca coinciden con algunos de los principales cinturones productores de caña de azúcar a nivel mundial. Asimismo, ambos enfoques identifican una fuerte concentración de áreas favorables en latitudes bajas cercanas al ecuador.
Sin embargo, también se observan diferencias importantes. El índice de aptitud climática genera mapas más continuos y generalizados, debido a que clasifica áreas según umbrales fijos de adecuación agrícola. En contraste, los mapas de similaridad muestran patrones más fragmentados y específicos, ya que dependen de la combinación multivariada exacta de condiciones climáticas presentes en cada punto analizado.
Adicionalmente, la aproximación de aptitud climática está orientada a evaluar potencial productivo para un cultivo específico, mientras que la similaridad climática permite explorar analogías ambientales y posibles regiones comparables desde una perspectiva ecológica y agroclimática más amplia.
En conjunto, ambas metodologías son complementarias. El análisis de aptitud permite identificar regiones potencialmente favorables para la producción de caña de azúcar, mientras que el análisis de similaridad climática permite reconocer territorios con comportamientos ambientales comparables al Valle del Cauca y explorar posibles patrones globales de adaptación climática y distribución agrícola.
Los resultados muestran que las regiones climáticamente similares a los puntos seleccionados del Valle del Cauca se concentran principalmente en zonas tropicales y subtropicales del planeta.
Las áreas identificadas presentan patrones comparables de temperatura media anual, disponibilidad hídrica y estacionalidad climática, características fundamentales para el desarrollo del cultivo de caña de azúcar.
En general, las regiones con mayor similaridad se localizan en:
Estos resultados coinciden con importantes regiones productoras de caña de azúcar a nivel mundial, lo que sugiere que las condiciones agroclimáticas del Valle del Cauca son comparables con varios de los principales cinturones cañeros del planeta.
Asimismo, se observan diferencias espaciales entre los puntos seleccionados, lo cual refleja la variabilidad altitudinal y climática existente dentro del Valle del Cauca.