---
id: missingness_rank_bar_figure_py_datascience
name: missingness_rank_bar_figure
kind: function
lang: py
domain: datascience
version: "1.0.0"
purity: impure
signature: "def missingness_rank_bar_figure(names, pcts, title=\"% de valores faltantes por columna\") -> \"matplotlib.figure.Figure\""
description: "Construye una figura matplotlib de barras horizontales que ordena las columnas de un dataset por su porcentaje de valores faltantes (0-100), la mayor arriba, etiquetando cada barra con su NN.N% al final. Usa ax.barh, eje X fijo 0-100 y labels truncados a ~22 chars. 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 listas vacías, longitudes desiguales o valores no numéricos (nunca lanza)."
tags: [eda, missing, missingness, ranking, bar, barh, matplotlib, figure, visualization, datascience, impure]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [matplotlib]
example: |
  from datascience.missingness_rank_bar_figure import missingness_rank_bar_figure
  names = ["edad", "ingresos", "ciudad", "email"]
  pcts = [12.5, 40.0, 3.2, 0.0]
  fig = missingness_rank_bar_figure(names, pcts, title="% de valores faltantes por columna")
tested: true
tests:
  - "test_returns_figure_with_axes"
  - "test_sorted_descending_largest_on_top"
  - "test_empty_lists_do_not_raise_and_returns_figure"
  - "test_xlim_is_zero_to_hundred"
  - "test_length_mismatch_and_non_numeric_are_handled"
test_file_path: "python/functions/datascience/missingness_rank_bar_figure_test.py"
file_path: "python/functions/datascience/missingness_rank_bar_figure.py"
params:
  - name: names
    desc: "Lista de nombres de columna. Puede venir vacía (devuelve figura \"sin datos faltantes\"). Los items se convierten a str y se truncan a ~22 chars con elipsis para las etiquetas del eje Y; los originales no se mutan."
  - name: pcts
    desc: "Lista paralela a names con el % de nulos en [0,100]. Valores None, NaN o no numéricos se coercen a 0.0 y los negativos se recortan a 0. Si len(names) != len(pcts) se recorta al menor de ambos para no romper."
  - name: title
    desc: "Título de la figura. Se trunca a ~60 chars con elipsis si es muy largo. Default \"% de valores faltantes por columna\"."
output: "Un matplotlib.figure.Figure (figsize 6.4 x alto adaptativo según nº de barras, dpi 150) con un Axes de barras horizontales (ax.barh) ordenadas por % descendente, la mayor arriba. Eje X fijado a [0,100] con label \"% faltante\", etiquetas del eje Y truncadas a ~22 chars, y cada barra anotada con su NN.N% al final. Si names o pcts vienen vacíos devuelve una Figure con texto centrado \"sin datos faltantes\"; 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_rank_bar_figure import missingness_rank_bar_figure

# % de nulos por columna (p. ej. (df.isnull().mean() * 100).
names = ["edad", "ingresos", "ciudad", "email"]
pcts = [12.5, 40.0, 3.2, 0.0]

fig = missingness_rank_bar_figure(
    names,
    pcts,
    title="% de valores faltantes por columna",
)

# ingresos (40.0%) queda arriba; email (0.0%) abajo.
# El renderer del informe lo rasteriza; aquí solo persistimos para inspección.
fig.savefig("/tmp/missingness_rank.png")
```

## Cuando usarla

Úsala al abrir el capítulo de datos faltantes de un informe EDA para responder
"¿qué columnas están más incompletas?" de un vistazo. Pásale los nombres de
columna y el % de nulos de cada una (`(df.isnull().mean() * 100).round(1)`); la
función se encarga de ordenar de mayor a menor y poner la peor arriba. Es la
pareja "magnitud" del heatmap de co-ocurrencia: las barras dicen *cuánto* falta
en cada columna, el heatmap dice *si esas 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.
- **Espera porcentajes 0-100, no fracciones 0-1.** El eje X está fijado a
  `[0, 100]`. Si pasas fracciones (`0.4` en vez de `40.0`) las barras saldrán
  pegadas al origen. Multiplica por 100 antes de llamar.
- **Alto adaptativo.** La altura de la figura crece con el número de barras
  (hasta un tope) para que reports con muchas columnas sigan legibles; aun así,
  conviene filtrar a las columnas con algún nulo antes de llamar para no listar
  decenas de barras a 0%.
- **Defensiva, nunca lanza.** Listas vacías, longitudes desiguales, valores
  `None`/`NaN`/no numéricos o cualquier error inesperado se manejan sin propagar:
  en el peor caso devuelve una `Figure` con "sin datos faltantes" o con el texto
  del error. No envuelvas la llamada en try/except por miedo a un raise — no lo
  hay.
