import pandas as pd, re, unicodedata, textwrap, math
import matplotlib.pyplot as plt
from pathlib import Path
# Load data
csv_path = Path(«/mnt/data/inscriptos totales.csv»)
df = pd.read_csv(csv_path)
def norm(s):
if pd.isna(s):
return «»
s = str(s).strip()
s = unicodedata.normalize(«NFKD», s).encode(«ascii», «ignore»).decode(«ascii»)
s = s.lower()
s = re.sub(r»\s+», » «, s).strip()
return s
country_map = {
«argentina»: «Argentina»,
«argentinas»: «Argentina»,
«uruguay»: «Uruguay»,
«uruguayo»: «Uruguay»,
«ecuador»: «Ecuador»,
«bolivia»: «Bolivia»,
«cuba»: «Cuba»,
«paraguay»: «Paraguay»,
«mexico»: «México»,
«colombia»: «Colombia»,
«peru»: «Perú»,
«chile»: «Chile»,
«brasil»: «Brasil»,
«venezuela»: «Venezuela»,
«republica dominicana»: «República Dominicana»,
«republica dominica»: «República Dominicana»,
«honduras»: «Honduras»,
«puerto rico»: «Puerto Rico»,
«panama»: «Panamá»,
«guatemala»: «Guatemala»,
«el salvador»: «El Salvador»,
«espana»: «España»,
«qatar»: «Catar»,
«catar»: «Catar»,
«comoras»: «Comoras»,
«granada»: «Granada»,
}
df[«Pais_norm»] = df[«País»].apply(lambda x: country_map.get(norm(x), str(x).strip() if pd.notna(x) else «»))
def spec_group(s):
n = norm(s)
if not n or n in {«na», «nan», «algo», «staff», «prog»}:
return «Sin dato / otras»
if «estudiante» in n or «internado» in n or «pregrado» in n:
return «Estudiantes / pregrado»
if «residente» in n:
return «Residentes»
if «hemat» in n or «oncohemat» in n or «hemoterapia» in n or «mieloma» in n:
return «Hematología y afines»
if «medicina interna» in n or «internista» in n or n == «interna»:
return «Medicina interna»
if «nefro» in n:
return «Nefrología»
if (
«medicina general» in n
or «medico general» in n
or «medicina gral» in n
or n == «general»
or «medicina familiar» in n
):
return «Medicina general / familiar»
if «clinica medica» in n or «clinica med» in n or n in {«clinica», «medicina», «medico»}:
return «Clínica médica / medicina general»
if «bioquim» in n or «laboratorio» in n or «patologia clinica» in n or «patologa clinica» in n:
return «Bioquímica / laboratorio»
if «oncolog» in n:
return «Oncología»
if «cardio» in n:
return «Cardiología»
if «genet» in n:
return «Genética»
if «pediatr» in n:
return «Pediatría»
if «emergencia» in n:
return «Emergencias»
return «Otras especialidades»
df[«spec_group»] = df[«Especialidad»].apply(spec_group)
df[«Lecciones_num»] = pd.to_numeric(df[«Lecciones Completadas»], errors=»coerce»).fillna(0).astype(int)
# Stats
total = len(df)
countries = df[«Pais_norm»].nunique()
top_countries = df[«Pais_norm»].value_counts()
top_specs = df[«spec_group»].value_counts()
at_least_one = int((df[«Lecciones_num»] >= 1).sum())
at_least_one_pct = at_least_one / total * 100
# Create charts
outdir = Path(«/mnt/data»)
# 1) Country bar chart
country_top = top_countries.head(10).sort_values()
fig = plt.figure(figsize=(10, 6))
ax = fig.add_subplot(111)
ax.barh(country_top.index, country_top.values)
ax.set_title(«Inscripciones por país»)
ax.set_xlabel(«Cantidad de inscriptos»)
for i, v in enumerate(country_top.values):
ax.text(v + max(country_top.values) * 0.01, i, str(v), va=»center», fontsize=10)
plt.tight_layout()
chart1 = outdir / «gelamm_grafico_paises.png»
fig.savefig(chart1, dpi=200, bbox_inches=»tight»)
plt.close(fig)
# 2) Specialties donut chart
spec_top = top_specs.copy()
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(111)
wedges, texts, autotexts = ax.pie(
spec_top.values,
labels=spec_top.index,
autopct=lambda p: f»{p:.1f}%» if p >= 3 else «»,
startangle=90,
wedgeprops=dict(width=0.45),
textprops=dict(fontsize=10),
)
ax.set_title(«Perfil general de especialidades declaradas»)
plt.tight_layout()
chart2 = outdir / «gelamm_grafico_especialidades.png»
fig.savefig(chart2, dpi=200, bbox_inches=»tight»)
plt.close(fig)
# 3) Participation chart
labels = [«Inscripciones totales», «Participaron en al menos 1 módulo», «Sin actividad registrada»]
values = [total, at_least_one, total – at_least_one]
fig = plt.figure(figsize=(10, 5.5))
ax = fig.add_subplot(111)
bars = ax.bar(labels, values)
ax.set_title(«Alcance general de participación»)
ax.set_ylabel(«Cantidad de personas»)
for bar, val in zip(bars, values):
ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + total*0.01, str(val),
ha=»center», va=»bottom», fontsize=11)
ax.text(1, at_least_one + total*0.08, f»{at_least_one_pct:.1f}% del total de inscriptos»,
ha=»center», fontsize=11)
plt.tight_layout()
chart3 = outdir / «gelamm_grafico_participacion.png»
fig.savefig(chart3, dpi=200, bbox_inches=»tight»)
plt.close(fig)
# Optional KPI banner image
fig = plt.figure(figsize=(12, 3.2))
ax = fig.add_subplot(111)
ax.axis(«off»)
kpi_text = (
f»{total} inscripciones totales\n»
f»{countries} países representados\n»
f»{at_least_one} participantes en al menos 1 módulo»
)
ax.text(0.5, 0.55, kpi_text, ha=»center», va=»center», fontsize=22)
ax.text(0.5, 0.15, «Curso de formación básica en gammapatías monoclonales – Edición 2025″,
ha=»center», va=»center», fontsize=13)
plt.tight_layout()
chart4 = outdir / «gelamm_kpis_curso_2025.png»
fig.savefig(chart4, dpi=200, bbox_inches=»tight»)
plt.close(fig)
# Build HTML article
top5_countries = top_countries.head(5)
top_specs_share = (top_specs / total * 100).round(1)
html = f»»»
Edición 2025: una experiencia de alcance regional
La edición 2025 del curso “Formación básica en gammapatías monoclonales: de la teoría a la práctica” cerró con una convocatoria muy significativa, consolidando a GELAMM como un espacio de referencia para la educación médica continua en Latinoamérica.
En total se registraron {total} inscripciones, provenientes de {countries} países. La convocatoria reflejó un interés amplio y sostenido por acceder a contenidos de actualización en gammapatías monoclonales, tanto desde la práctica clínica como desde etapas de formación.

Una convocatoria amplia y diversa
La mayor parte de las inscripciones provinieron de {top5_countries.index[0]}, {top5_countries.index[1]}, {top5_countries.index[2]}, {top5_countries.index[3]} y {top5_countries.index[4]}, lo que reafirma el alcance regional de la propuesta y su capacidad de convocatoria en distintos contextos de formación y ejercicio profesional.
También se observó una participación diversa en términos de perfiles profesionales. Predominaron las inscripciones vinculadas a {top_specs.index[0]}, seguidas por {top_specs.index[1]} y {top_specs.index[2]}, junto con otros perfiles clínicos, de laboratorio y formación de grado.

Participación e interés por los contenidos
Más allá del volumen de inscripciones, la edición 2025 mostró una amplia participación en al menos un módulo del curso. En total, {at_least_one} personas registraron actividad en contenidos del programa, lo que representa aproximadamente el {at_least_one_pct:.1f}% del total de inscriptos.
Este dato confirma no solo el interés inicial por la propuesta, sino también la capacidad del curso para movilizar participación efectiva en una temática de alta relevancia para la práctica médica actual.

Un perfil académico alineado con los objetivos del programa
El curso convocó principalmente a profesionales y personas en formación vinculadas a áreas especialmente afines al abordaje de las gammapatías monoclonales. Entre las especialidades declaradas se destacaron Hematología y afines, Medicina interna, Nefrología, Clínica médica / medicina general y Bioquímica / laboratorio, además de estudiantes y residentes.
Esta composición refuerza el valor del curso como una propuesta formativa pensada para acompañar trayectorias diversas, promover una mirada integral y fortalecer el intercambio regional entre colegas.

Una base sólida para la próxima edición
Los resultados de esta edición dejan una base muy valiosa para el futuro. La convocatoria alcanzada, la diversidad geográfica y la participación en los contenidos refuerzan la responsabilidad de seguir construyendo propuestas académicas accesibles, actualizadas y con impacto regional.
En este marco, la próxima edición prevista para 2027 se presenta como una nueva oportunidad para profundizar este camino, ampliar el alcance del programa y continuar fortaleciendo el compromiso de GELAMM con la formación médica en Latinoamérica.
«»»
html_path = outdir / «gelamm_nota_curso_2025_wordpress.html»
html_path.write_text(html, encoding=»utf-8″)
print(f»Creado: {html_path}»)
print(f»Creado: {chart1}»)
print(f»Creado: {chart2}»)
print(f»Creado: {chart3}»)
print(f»Creado: {chart4}»)

