---
id: missingness_corr_heatmap_figure_py_datascience
name: missingness_corr_heatmap_figure
kind: function
lang: py
domain: datascience
version: "1.0.0"
purity: impure
signature: "def missingness_corr_heatmap_figure(matrix, labels, title=\"Co-ocurrencia de ausencias\") -> \"matplotlib.figure.Figure\""
description: "Construye una figura matplotlib (heatmap) de la matriz NxN de correlación de ausencias entre columnas: +1 = dos columnas suelen ser nulas a la vez, -1 = cuando una falta la otra está presente, 0 = ausencias independientes. Usa ax.imshow con coolwarm fijado a [-1,1], ticks con los labels truncados (X rotados 45º), colorbar y anota el valor de cada celda si N<=12. Devuelve un matplotlib.figure.Figure listo para rasterizar por el renderer del informe EDA (capítulo de datos faltantes). Backend Agg sin pyplot global; defensivo ante matrix/labels vacíos o celdas no numéricas (nunca lanza)."
tags: [eda, missing, missingness, correlation, heatmap, matplotlib, figure, visualization, datascience, impure]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [matplotlib]
example: |
  from datascience.missingness_corr_heatmap_figure import missingness_corr_heatmap_figure
  matrix = [
      [1.0, 0.82, -0.10],
      [0.82, 1.0, 0.05],
      [-0.10, 0.05, 1.0],
  ]
  labels = ["telefono", "movil", "email"]
  fig = missingness_corr_heatmap_figure(matrix, labels, title="Co-ocurrencia de ausencias")
tested: true
tests:
  - "test_returns_figure_with_axes"
  - "test_empty_matrix_does_not_raise_and_returns_figure"
  - "test_empty_labels_returns_message_figure"
  - "test_large_matrix_omits_annotations"
  - "test_ragged_and_non_numeric_cells_are_handled"
test_file_path: "python/functions/datascience/missingness_corr_heatmap_figure_test.py"
file_path: "python/functions/datascience/missingness_corr_heatmap_figure.py"
params:
  - name: matrix
    desc: "Lista de listas (NxN) de floats en [-1,1]: la correlación de ausencias por pares de columnas. Puede venir vacía. Filas de longitud desigual se toleran (se rellenan/recortan a N); celdas None, NaN o no numéricas se coercen a 0.0. No se muta el original."
  - name: labels
    desc: "Lista de N nombres de columna, paralela a matrix. Puede venir vacía (devuelve figura \"sin columnas con ausencia variable\"). Se truncan a ~14 chars con elipsis para los ticks; los originales no se mutan."
  - name: title
    desc: "Título de la figura. Se trunca a ~60 chars con elipsis si es muy largo. Default \"Co-ocurrencia de ausencias\"."
output: "Un matplotlib.figure.Figure (figsize 6.4x5.2, dpi 150) con un Axes heatmap (imshow vmin=-1, vmax=1, cmap coolwarm) más una colorbar etiquetada \"correlación de ausencias\". Ticks en ambos ejes con los labels truncados (X rotados 45º). Si N<=12 cada celda lleva su valor numérico anotado (texto blanco sobre celdas saturadas, oscuro sobre pálidas); con N grande se omiten las anotaciones para no saturar. Si matrix o labels vienen vacíos devuelve una Figure con texto centrado \"sin columnas con ausencia variable\"; cualquier error inesperado se captura y devuelve una Figure con el mensaje de error (nunca lanza). El caller rasteriza/cierra la figura; la función no la muestra ni la guarda."
---

## Ejemplo

```python
from datascience.missingness_corr_heatmap_figure import missingness_corr_heatmap_figure

# Correlación de ausencias entre 3 columnas de contacto:
# telefono y movil tienden a faltar juntos (0.82); email es casi independiente.
matrix = [
    [1.00, 0.82, -0.10],
    [0.82, 1.00,  0.05],
    [-0.10, 0.05, 1.00],
]
labels = ["telefono", "movil", "email"]

fig = missingness_corr_heatmap_figure(
    matrix,
    labels,
    title="Co-ocurrencia de ausencias",
)

# El renderer del informe lo rasteriza; aquí solo persistimos para inspección.
fig.savefig("/tmp/missingness_heatmap.png")
```

## Cuando usarla

Úsala en el capítulo de datos faltantes de un informe EDA cuando quieras ver de
un vistazo qué columnas faltan juntas (mismo formulario sin rellenar, mismo
proceso roto) frente a columnas cuyas ausencias son independientes. Pásale la
matriz de correlación de ausencias (calculada sobre la máscara de nulos, p. ej.
`df.isnull().corr()`) restringida a las columnas que de verdad tienen ausencia
variable, junto con sus nombres. Es la pareja "estructura" del ranking de % de
nulos: las barras dicen *cuánto* falta cada columna, este heatmap dice *si las
ausencias están relacionadas* entre columnas.

## Gotchas

- **Impura por matplotlib.** Toca la maquinaria de render. Usa el backend `Agg`
  y la API orientada a objetos `Figure`/`add_subplot` — NUNCA `pyplot.*` aquí,
  para no tocar el estado global ni filtrar figuras entre llamadas. `pyplot` NO
  es thread-safe; esta función evita ese riesgo construyendo el `Figure`
  directamente, así que es segura de llamar en bucle desde el renderer.
- **El caller cierra la figura.** Devuelve el `Figure` pero no lo muestra ni lo
  guarda. Quien la consume debe rasterizarla y luego liberarla
  (`matplotlib.pyplot.close(fig)`) para no acumular memoria en lotes grandes.
- **Escala de color fija en [-1, 1].** `vmin=-1`, `vmax=1` están fijados a
  propósito para que el color sea comparable entre informes y entre columnas. No
  se autoescala al rango real de la matriz; valores fuera de `[-1, 1]` se
  saturan al extremo del colormap.
- **Anotaciones solo con N<=12.** Por encima de 12 columnas el grid de números
  se vuelve ilegible y se omite; queda solo el color + la colorbar. Filtra a las
  columnas con ausencia variable antes de llamar para no llegar a matrices
  enormes.
- **Defensiva, nunca lanza.** `matrix=[]`, `labels=[]`, filas cortas, celdas
  `None`/`NaN`/no numéricas o cualquier error inesperado se manejan sin propagar:
  en el peor caso devuelve una `Figure` con "sin columnas con ausencia variable"
  o con el texto del error. No envuelvas la llamada en try/except por miedo a un
  raise — no lo hay.
