"""
Diagrama de flujo PRISMA 2020 (Semilleros 2026)
Reproduce fielmente la figura original: mismos textos, cifras y disposición.
Requisitos: pip install matplotlib
"""
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle, FancyBboxPatch


# ---------------------------------------------------------------- Configuración
W, H = 1750, 2100                 # lienzo en "píxeles" lógicos
DPI_SALIDA = 300                  # resolución del archivo final
AMARILLO, AZUL, NEGRO = "#FFC000", "#BDD7EE", "black"
from matplotlib import font_manager
_disp = {f.name for f in font_manager.fontManager.ttflist}
plt.rcParams["font.family"] = "Segoe UI" if "Segoe UI" in _disp else "DejaVu Sans"

# Segoe UI es más angosta que DejaVu Sans: se compensa el tamaño
FS, FS_TIT = (19, 22) if plt.rcParams["font.family"] == ["Segoe UI"] else (16.5, 20)

fig = plt.figure(figsize=(W / 100, H / 100), dpi=100, facecolor="white")
ax = fig.add_axes([0, 0, 1, 1])
ax.set_xlim(0, W)
ax.set_ylim(H, 0)                 # eje Y invertido: origen arriba-izquierda
ax.axis("off")

# ---------------------------------------------------------------- Utilidades
def caja(x0, y0, x1, y1):
    ax.add_patch(Rectangle((x0, y0), x1 - x0, y1 - y0, fill=False,
                           ec=NEGRO, lw=2))

def banda(x0, y0, x1, y1, color, texto, fs, rot=0, r=22):
    ax.add_patch(FancyBboxPatch((x0 + r, y0 + r), x1 - x0 - 2 * r, y1 - y0 - 2 * r,
                                boxstyle=f"round,pad={r}", fc=color, ec=NEGRO, lw=2))
    ax.text((x0 + x1) / 2, (y0 + y1) / 2, texto, ha="center", va="center",
            fontsize=fs, fontweight="bold", rotation=rot)

def txt(x, y, s, bold=False, italic=False):
    ax.text(x, y, s, ha="left", va="center", fontsize=FS,
            fontweight="bold" if bold else "normal",
            fontstyle="italic" if italic else "normal")

def flecha(x0, y0, x1, y1):
    ax.annotate("", xy=(x1, y1), xytext=(x0, y0),
                arrowprops=dict(arrowstyle="-|>,head_width=0.45,head_length=0.9",
                                color=NEGRO, lw=2, shrinkA=0, shrinkB=0))

# ---------------------------------------------------------------- Encabezado
banda(99, 99, 1648, 176, AMARILLO,
      "Identificación de estudios vía bases de datos y registros",
      FS_TIT, r=6)

# ---------------------------------------------------------------- Etiquetas laterales
banda(99, 227, 190, 588, AZUL, "Identificación", FS, rot=90)
banda(99, 671, 190, 1657, AZUL, "Cribado", FS, rot=90)
banda(99, 1741, 190, 2002, AZUL, "Inclusión", FS, rot=90)

# ---------------------------------------------------------------- Cajas
XL0, XL1, XR0, XR1 = 212, 826, 890, 1648
filas = [(227, 588), (671, 906), (996, 1231), (1321, 1657)]
for y0, y1 in filas:
    caja(XL0, y0, XL1, y1)
    caja(XR0, y0, XR1, y1)
caja(XL0, 1741, XL1, 2002)        # Inclusión (solo columna izquierda)

# ---------------------------------------------------------------- Textos: Identificación
txt(230, 273, "Registros identificados de:", bold=True)
txt(238, 325, "Bases de datos (n = 449)")
txt(243, 369, "•")
txt(271, 369, "Scopus (n = 291)")
txt(243, 411, "•")
txt(271, 411, "Web Of Science (n = 158)")
txt(238, 464, "Registros (n = 0)")

txt(908, 273, "Registros eliminados antes del cribado:", italic=True)
txt(924, 325, "Registros duplicados eliminados (n = 65)")
txt(924, 377, "Registros marcados como inelegibles por herramientas")
txt(924, 416, "de automatización (n = 0)")
txt(924, 468, "Registros eliminados por otras razones (n = 245)")

# ---------------------------------------------------------------- Textos: Cribado
txt(230, 709, "Registros cribados", bold=True)
txt(230, 754, "(n = 139)")
txt(908, 709, "Registros excluidos", bold=True)
txt(908, 754, "(n = 63)")

txt(230, 1034, "Informes buscados para recuperación", bold=True)
txt(230, 1080, "(n = 76)")
txt(908, 1034, "Informes no recuperados", bold=True)
txt(908, 1080, "(n = 0)")

txt(230, 1376, "Informes evaluados para elegibilidad", bold=True)
txt(230, 1421, "(n = 76)")
txt(908, 1376, "Informes excluidos:", bold=True)
txt(908, 1429, "Diferencia del tema  (n = 3)")

# ---------------------------------------------------------------- Texto: Inclusión
txt(230, 1883, "Informes de estudios incluidos", bold=True)
txt(230, 1929, "(n = 73)")

# ---------------------------------------------------------------- Flechas
XM = 520
for y0, y1 in [(588, 671), (906, 996), (1231, 1321), (1657, 1741)]:
    flecha(XM, y0, XM, y1)
for y in (405, 789, 1113, 1488):
    flecha(XL1, y, XR0 - 4, y)

# ---------------------------------------------------------------- Guardado
fig.savefig("PRISMA_SEMILLEROS_2026.png", dpi=DPI_SALIDA, facecolor="white")
fig.savefig("PRISMA_SEMILLEROS_2026.pdf", facecolor="white")  # vectorial
print("Listo: PRISMA_SEMILLEROS_2026.png y .pdf")

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: