library(ggplot2)
library(ggrepel)
datos <- data.frame(
estado = c("Tlaxcala", "Morelos", "Hidalgo", "Puebla",
"Estado de México", "Ciudad de México"),
exportaciones_mdd = c(1983.3, 3483.6, 3056.7, 17118.3, 21823.3, 3763.6),
pib_por_ocupado = c(223.1437796, 298.7985726, 307.9788193,
286.1081232, 285.7081906, 793.92934)
)
ggplot(datos, aes(x = exportaciones_mdd, y = pib_por_ocupado, label = estado)) +
geom_point(color = "#0077B6", size = 4) +
geom_text_repel(size = 4, fontface = "bold", color = "#061A40",
max.overlaps = 10) +
labs(
title = "Inserción exportadora y productividad aparente",
subtitle = "Relación entre exportaciones (mdd) y PIB por ocupado, T-MEC",
x = "Exportaciones (millones de dólares)",
y = "PIB por ocupado (miles de pesos)"
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold", size = 15, color = "#061A40"),
plot.subtitle = element_text(color = "#5B4B9E"),
panel.grid.minor = element_blank(),
panel.grid.major = element_line(color = "#B7A9E0", linewidth = 0.2)
)

library(ggplot2)
library(ggrepel)
datos <- data.frame(
estado = c("Tlaxcala", "Morelos", "Hidalgo", "Puebla",
"Estado de México", "Ciudad de México"),
disponibilidad_agua_hm3 = c(62.746, 28.116, 163.558, 30.88, -557.755, -480.43),
capacidad_instalada_mw = c(NA, 656, 2492, 702, 1658, 266)
)
ggplot(datos, aes(x = disponibilidad_agua_hm3, y = capacidad_instalada_mw, label = estado)) +
geom_vline(xintercept = 0, linetype = "dashed", color = "#9AAFD1", linewidth = 0.8) +
geom_point(color = "#0077B6", size = 4, na.rm = TRUE) +
geom_text_repel(size = 4, fontface = "bold", color = "#061A40",
max.overlaps = 10, na.rm = TRUE) +
labs(
title = "Agua y energía como restricciones al crecimiento industrial",
subtitle = "Disponibilidad hídrica vs. capacidad eléctrica instalada por estado",
x = expression("Disponibilidad de agua (hm"^3*")"),
y = "Capacidad instalada (MW)",
caption = "Nota: Tlaxcala no cuenta con dato de capacidad instalada (NA) y no aparece en la gráfica."
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold", size = 15, color = "#061A40"),
plot.subtitle = element_text(color = "#5B4B9E"),
plot.caption = element_text(color = "gray50", hjust = 0),
panel.grid.minor = element_blank(),
panel.grid.major = element_line(color = "#B7A9E0", linewidth = 0.2)
)

library(ggplot2)
library(ggrepel)
datos <- data.frame(
estado = c("Tlaxcala", "Morelos", "Hidalgo", "Puebla",
"Estado de México", "Ciudad de México"),
escolaridad_promedio = c(9.83, 9.84, 9.37, 9.16, 10.08, 11.48),
tasa_informalidad = c(70.3, 64.7, 71.3, 72.1, 54.5, 45.7)
)
ggplot(datos, aes(x = escolaridad_promedio, y = tasa_informalidad, label = estado)) +
geom_point(color = "#0077B6", size = 4) +
geom_text_repel(size = 4, fontface = "bold", color = "#061A40",
max.overlaps = 10) +
labs(
title = "Capital humano e informalidad laboral",
subtitle = "Escolaridad promedio vs. tasa de informalidad por estado",
x = "Escolaridad promedio (años)",
y = "Tasa de informalidad (%)"
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold", size = 15, color = "#061A40"),
plot.subtitle = element_text(color = "#5B4B9E"),
plot.caption = element_text(color = "gray50", hjust = 0),
panel.grid.minor = element_blank(),
panel.grid.major = element_line(color = "#B7A9E0", linewidth = 0.2)
)

library(ggplot2)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(tidyr)
datos <- data.frame(
estado = c("Tlaxcala", "Morelos", "Hidalgo", "Puebla",
"Estado de México", "Ciudad de México"),
disponibilidad_agua_hm3 = c(62.746, 28.116, 163.558, 30.88, -557.755, -480.43),
homicidios_100mil = c(8.36, 54.42, 8.79, 12.7, 8.57, 9.24),
tasa_informalidad = c(70.3, 64.7, 71.3, 72.1, 54.5, 45.7),
grado_marginacion = c("Medio", "Medio", "Alto", "Alto", "Bajo", "Muy bajo"),
zona_sismica = c("B y C", "C", "B", "B y C", "B y C", "B y C"),
precipitacion_media_anual_mm = c(846.4, 2098.7, 825.5, 1343.8, 1067.8, 894.1)
)
clasif_agua <- function(x) {
case_when(
x < 0 ~ "Rojo", # déficit hídrico
x >= 0 & x < 100 ~ "Amarillo", # disponibilidad baja
x >= 100 ~ "Verde" # disponibilidad holgada
)
}
clasif_seguridad <- function(x) {
case_when(
x < 8.5 ~ "Verde",
x >= 8.5 & x < 30 ~ "Amarillo",
x >= 30 ~ "Rojo"
)
}
clasif_informalidad <- function(x) {
case_when(
x < 40 ~ "Verde",
x >= 40 & x < 60 ~ "Amarillo",
x >= 60 ~ "Rojo"
)
}
clasif_marginacion <- function(x) {
case_when(
x %in% c("Muy bajo", "Bajo") ~ "Verde",
x == "Medio" ~ "Amarillo",
x %in% c("Alto", "Muy alto") ~ "Rojo"
)
}
clasif_sismo <- function(x) {
case_when(
grepl("D", x) ~ "Rojo", # zona sísmica muy alta
grepl("C", x) ~ "Amarillo", # zona sísmica alta
grepl("B", x) ~ "Verde", # zona sísmica moderada
TRUE ~ "Amarillo"
)
}
clasif_clima <- function(x) {
case_when(
x > 1800 ~ "Rojo", # riesgo de inundación
x >= 1200 & x <= 1800 ~ "Amarillo",
x < 1200 ~ "Verde"
)
}
matriz <- datos %>%
transmute(
estado,
Agua = clasif_agua(disponibilidad_agua_hm3),
Seguridad = clasif_seguridad(homicidios_100mil),
Informalidad = clasif_informalidad(tasa_informalidad),
Marginacion = clasif_marginacion(grado_marginacion),
Sismos = clasif_sismo(zona_sismica),
Clima = clasif_clima(precipitacion_media_anual_mm)
)
matriz_larga <- matriz %>%
pivot_longer(cols = -estado, names_to = "variable", values_to = "riesgo") %>%
mutate(
riesgo = factor(riesgo, levels = c("Verde", "Amarillo", "Rojo")),
estado = factor(estado, levels = rev(c("Tlaxcala", "Morelos", "Hidalgo",
"Puebla", "Estado de México",
"Ciudad de México"))),
variable = factor(variable, levels = c("Agua", "Seguridad", "Informalidad",
"Marginacion", "Sismos", "Clima"))
)
ggplot(matriz_larga, aes(x = variable, y = estado, fill = riesgo)) +
geom_tile(color = "white", linewidth = 1.5) +
geom_text(aes(label = riesgo), color = "black", fontface = "bold", size = 3.5) +
scale_fill_manual(values = c("Verde" = "#82E0AA",
"Amarillo" = "#F7DC6F",
"Rojo" = "#F1948A")) +
labs(
title = "Matriz de restricciones territoriales para inversión",
subtitle = "Semáforo de riesgo por estado y dimensión",
x = NULL, y = NULL, fill = "Nivel de riesgo"
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold", size = 15),
plot.subtitle = element_text(color = "gray40"),
axis.text.x = element_text(face = "bold", size = 11),
axis.text.y = element_text(face = "bold", size = 11),
panel.grid = element_blank(),
legend.position = "none"
)

library(ggplot2)
library(dplyr)
library(tidyr)
datos <- data.frame(
estado = c("Tlaxcala", "Morelos", "Hidalgo", "Puebla",
"Estado de México", "Ciudad de México"),
parques_industriales = c(4, 7, 12, 4, 35, 5),
km_red_carretera = c(3031, 3005, 11024, 12005, 5119, 45),
km_red_ferroviaria = c(352, 259, 876, 1065, 1304, 281),
unidades_manufactureras = c(14382, 9742, 15865, 58410, 73271, 31218)
)
# Máximo regional = 100
normalizar_100 <- function(x) {
100 * x / max(x, na.rm = TRUE)
}
datos_norm <- datos %>%
mutate(
parques_industriales = normalizar_100(parques_industriales),
km_red_carretera = normalizar_100(km_red_carretera),
km_red_ferroviaria = normalizar_100(km_red_ferroviaria),
unidades_manufactureras = normalizar_100(unidades_manufactureras)
)
# Índice total
# Promedio simple de los cuatro componentes normalizados
datos_norm <- datos_norm %>%
mutate(
indice_total = rowMeans(
select(
.,
parques_industriales,
km_red_carretera,
km_red_ferroviaria,
unidades_manufactureras
),
na.rm = TRUE
)
)
# Ordenar estados por índice total ----
orden_estados <- datos_norm %>%
arrange(desc(indice_total)) %>%
pull(estado)
matriz_larga <- datos_norm %>%
pivot_longer(
cols = -estado,
names_to = "componente",
values_to = "valor"
) %>%
mutate(
estado = factor(estado, levels = rev(orden_estados)),
componente = factor(
componente,
levels = c(
"parques_industriales",
"km_red_carretera",
"km_red_ferroviaria",
"unidades_manufactureras",
"indice_total"
),
labels = c(
"Parques\nindustriales",
"Red\ncarretera",
"Red\nferroviaria",
"Unidades\nmanufactureras",
"ÍNDICE\nTOTAL"
)
),
etiqueta = round(valor, 0),
color_texto = ifelse(valor >= 55, "white", "black")
)
grafica <- ggplot(matriz_larga, aes(x = componente, y = estado, fill = valor)) +
geom_tile(color = "white", linewidth = 1.5) +
geom_text(
aes(label = etiqueta, color = color_texto),
fontface = "bold",
size = 4
) +
scale_color_identity() +
scale_fill_gradient2(
low = "#F1948A",
mid = "#F7DC6F",
high = "#1E8449",
midpoint = 50,
limits = c(0, 100),
name = "Índice\n(0-100)"
) +
labs(
title = "Componentes de la plataforma logístico-industrial por
estado",
subtitle = "Valores normalizados (0-100, máximo regional = 100) e índice sintético total",
caption = "Nota: el índice total corresponde al promedio simple de los cuatro componentes normalizados. Se usa
como herramienta comparativa, no como medida absoluta de competitividad.",
x = NULL,
y = NULL
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold", size = 15),
plot.subtitle = element_text(color = "gray40", size = 12),
plot.caption = element_text(color = "gray35", size = 9, hjust = 0),
axis.text.x = element_text(face = "bold", size = 10),
axis.text.y = element_text(face = "bold", size = 11),
panel.grid = element_blank(),
legend.position = "right"
)
grafica

library(ggplot2)
library(dplyr)
library(ggrepel)
# Datos de capacidad logístico-industrial
# Índice total del heatmap
datos <- data.frame(
estado = c("Ciudad de México", "Estado de México", "Hidalgo",
"Morelos", "Puebla", "Tlaxcala"),
capacidad_logistico_industrial = c(20, 86, 54, 20, 68, 21)
)
# Recordar que Verde = 1, Amarillo = 2, Rojo = 3
# Mientras más alto, mayor restricción
riesgos <- data.frame(
estado = c("Ciudad de México", "Estado de México", "Hidalgo",
"Morelos", "Puebla", "Tlaxcala"),
agua = c(3, 3, 1, 2, 2, 2),
seguridad = c(2, 2, 2, 3, 2, 1),
informalidad = c(2, 2, 3, 3, 3, 3),
marginacion = c(1, 1, 3, 2, 3, 2),
sismos = c(2, 2, 1, 2, 2, 2),
clima = c(1, 1, 1, 3, 2, 1)
)
# Primero se obtiene el promedio de riesgo.
# Luego se normaliza:
# 1 = 0 puntos de restricción
# 2 = 50 puntos
# 3 = 100 puntos
riesgos <- riesgos %>%
mutate(
riesgo_promedio = rowMeans(select(., agua, seguridad, informalidad,
marginacion, sismos, clima)),
restricciones_territoriales = ((riesgo_promedio - 1) / 2) * 100
)
diagnostico <- datos %>%
left_join(riesgos, by = "estado") %>%
mutate(
cuadrante = case_when(
capacidad_logistico_industrial >= 50 & restricciones_territoriales < 50 ~
"Alta capacidad / bajas restricciones",
capacidad_logistico_industrial >= 50 & restricciones_territoriales >= 50 ~
"Alta capacidad / altas restricciones",
capacidad_logistico_industrial < 50 & restricciones_territoriales < 50 ~
"Baja capacidad / bajas restricciones",
capacidad_logistico_industrial < 50 & restricciones_territoriales >= 50 ~
"Baja capacidad / altas restricciones"
)
)
grafica_diagnostico <- ggplot(diagnostico,
aes(x = restricciones_territoriales,
y = capacidad_logistico_industrial)) +
# Fondos de cuadrantes
annotate("rect", xmin = 0, xmax = 50, ymin = 50, ymax = 100,
fill = "#D5F5E3", alpha = 0.45) +
annotate("rect", xmin = 50, xmax = 100, ymin = 50, ymax = 100,
fill = "#FCF3CF", alpha = 0.55) +
annotate("rect", xmin = 0, xmax = 50, ymin = 0, ymax = 50,
fill = "#EBF5FB", alpha = 0.55) +
annotate("rect", xmin = 50, xmax = 100, ymin = 0, ymax = 50,
fill = "#FADBD8", alpha = 0.55) +
geom_vline(xintercept = 50, linetype = "dashed", color = "gray45") +
geom_hline(yintercept = 50, linetype = "dashed", color = "gray45") +
geom_point(size = 4, color = "#0B6FA4") +
geom_text_repel(
aes(label = estado),
size = 4.2,
fontface = "bold",
color = "#0A2240",
max.overlaps = Inf
) +
# Etiquetas de cuadrantes
annotate("text", x = 25, y = 94,
label = "Plataformas prioritarias",
fontface = "bold", size = 4, color = "#1D8348") +
annotate("text", x = 75, y = 94,
label = "Potencial con cuellos\nde botella",
fontface = "bold", size = 4, color = "#9A6A00") +
annotate("text", x = 25, y = 8,
label = "Desarrollo selectivo\no complementario",
fontface = "bold", size = 4, color = "#21618C") +
annotate("text", x = 75, y = 8,
label = "Inversión condicionada",
fontface = "bold", size = 4, color = "#922B21") +
scale_x_continuous(
limits = c(0, 100),
breaks = seq(0, 100, 25)
) +
scale_y_continuous(
limits = c(0, 100),
breaks = seq(0, 100, 25)
) +
labs(
title = "Matriz de diagnóstico para inversión vinculada al nearshoring",
subtitle = "Capacidad logístico-industrial vs. restricciones territoriales",
x = "Restricciones territoriales (0 = bajas, 100 = altas)",
y = "Capacidad logístico-industrial (0 = baja, 100 = alta)",
caption = "Nota: la capacidad logístico-industrial proviene del índice sintético de infraestructura.
Las restricciones se calcularon con una escala semáforo: verde=1, amarillo=2, rojo=3."
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold", size = 16),
plot.subtitle = element_text(size = 12, color = "gray35"),
plot.caption = element_text(size = 9, color = "gray35", hjust = 0),
axis.title = element_text(face = "bold"),
panel.grid.minor = element_blank()
)
grafica_diagnostico

ggsave(
filename = "matriz_diagnostico_nearshoring.png",
plot = grafica_diagnostico,
width = 10,
height = 6.5,
dpi = 300
)