ISOTYPE (International System of Typographic Picture Education) fue creado en los años 1920 por Otto Neurath.
También conocido como el método de Viena.
Propone comunicar información compleja mediante pictogramas e iconos, con el mínimo de texto.
Principio clave: “las palabras separan, las imágenes unen”.
0.1 Características
Uso de pictogramas simples y gráficos elementales.
Lenguaje visual universal, independiente de idiomas.
Inspirado en el funcionalismo gráfico de la Bauhaus y las vanguardias del siglo XX.
La comprensión se logra en tres pasos: captar lo esencial, lo secundario y los detalles.
Visualización de datos estadísticos: tablas y gráficos comparativos.
Educación y divulgación: explicar fenómenos sociales, económicos o históricos.
Diseño gráfico y editorial: base de la infografía moderna.
0.2 Errores a Evitar
Escalar pictogramas para “mostrar más” (tamaño ≠ cantidad); en Isotype se repiten iconos del mismo tamaño.
No definir la unidad visual: falta de leyenda “1 icono = N unidades”.
Iconografía inconsistente: cambiar de pictograma para la misma categoría.
Efectos decorativos (3D, degradados, sombras) que restan legibilidad.
Iconos culturalmente ambiguos: metáforas no universales.
1 Librería altair (Vega-Altair)
Logo de Altair
La librería altair es un paquete de Python diseñado para crear visualizaciones interactivas y declarativas basadas en la gramática de gráficos de Vega y Vega-Lite.
1.1 Usos principales
Exploración de datos de manera visual y rápida.
Creación de gráficos interactivos en notebooks, aplicaciones web y dashboards.
Informes y storytelling con datos, gracias a su integración con Jupyter, Streamlit, Panel y Quarto.
1.2 Características principales
Sintaxis declarativa y concisa: describes el gráfico indicando las columnas de tus datos y el tipo de marca (barras, puntos, líneas, etc.).
Admite interactividad integrada como zoom, selección y filtrado.
Compatible con pandas DataFrames y librerías de análisis como NumPy.
Exporta visualizaciones en formato JSON para reproducibilidad.
1.3 Instalación
Para instalar Altair y sus dependencias más comunes:
pip install "altair[all]"# Dataset: Base de Artículos Publicados 2015–2023**Fuente:**[Secretaría de Educación Superior, Ciencia, Tecnología e Innovación (SENESCYT)](https://cloud-pro.senescyt.gob.ec/index.php/s/qfDbtQxawojJ2CG?openfile=true)**Descripción:**Este dataset contiene la base estadística de artículos científicos publicados por las universidades y escuelas politécnicas de Ecuador en **revistas indexadas** durante el periodo **2015 – 2023**. ::: {#20c93db1 .cell execution_count=30}```{.python .cell-code}import pandas as pdfrom wordcloud import WordCloud, STOPWORDSimport matplotlib.pyplot as pltdf = pd.read_excel("Base_estadistica_articulos_UEP_15_23.xlsx", skiprows=12)
:::
import pandas as pdimport numpy as npimport altair as alt# ---- Filtrar y calcular top 10 ----df_filtered = df[df['NOMBRE UNIVERSIDAD'] =="UNIVERSIDAD SAN FRANCISCO DE QUITO"]["CAMPO DETALLADO"].dropna().astype(str)top = df_filtered.value_counts().head(10).reset_index()top.columns = ["CAMPO DETALLADO", "FRECUENCIA"]# ---- Parámetros del isotype ----UNIDAD =50# 1 ícono = 50 publicaciones# Emojis por categoría (puedes ajustar a gusto)emoji_map = {"FÍSICA": "🔭","MEDICINA": "💊","BIOLOGÍA": "🧬","MEDIO AMBIENTE": "🌱","ESTUDIOS SOCIALES Y CULTURALES": "📚","CONSTRUCCIÓN E INGENIERÍA CIVIL": "🏗️","BIOMEDICINA": "🧪","SALUD PÚBLICA": "🏥","COMPUTACIÓN": "💻","QUÍMICA": "⚗️"}# Calcular número de iconostop["ICONOS"] = np.maximum((top["FRECUENCIA"] // UNIDAD).astype(int), 1)# Expandir filas: una por íconorows = []for _, r in top.iterrows():for i inrange(int(r["ICONOS"])): rows.append({"CAMPO DETALLADO": r["CAMPO DETALLADO"],"y": i # eje vertical })source = pd.DataFrame(rows)# Gráfico verticalchart = ( alt.Chart(source) .mark_text(size=25, baseline='middle') .encode( alt.X('CAMPO DETALLADO:O', sort=top["CAMPO DETALLADO"].tolist()).axis(None), alt.Y('y:O').axis(None), alt.Text('emoji:N') ) .transform_calculate( emoji=f"{emoji_map}".replace("'", '"') +"[datum['CAMPO DETALLADO']]" ) .properties(width=650, height=500))# Pie con la equivalencianota = alt.Chart(pd.DataFrame({"t": [f"1 icono = {UNIDAD} publicaciones"]})).mark_text( align="left", dx=5, dy=15).encode(text="t:N")chart & nota
c:\Users\meagu\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``.
col = df[col_name].apply(to_list_if_array, convert_dtype=False)
c:\Users\meagu\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``.
col = df[col_name].apply(to_list_if_array, convert_dtype=False)
1.4 Iteración 2
import pandas as pdimport numpy as npimport altair as alt# ---- Filtrar y calcular top 10 ----df_filtered = df[df['NOMBRE UNIVERSIDAD'] =="UNIVERSIDAD SAN FRANCISCO DE QUITO"]["CAMPO DETALLADO"].dropna().astype(str)top = df_filtered.value_counts().head(10).reset_index()top.columns = ["CAMPO DETALLADO", "FRECUENCIA"]# ---- Parámetros del isotype ----UNIDAD =50# 1 ícono = 50 publicaciones# Emojis por categoríaemoji_map = {"FÍSICA": "🔭","MEDICINA": "💊","BIOLOGÍA": "🧬","MEDIO AMBIENTE": "🌱","ESTUDIOS SOCIALES Y CULTURALES": "📚","CONSTRUCCIÓN E INGENIERÍA CIVIL": "🏗️","BIOMEDICINA": "🧪","SALUD PÚBLICA": "🏥","COMPUTACIÓN": "💻","QUÍMICA": "⚗️"}# Calcular número de iconostop["ICONOS"] = np.maximum((top["FRECUENCIA"] // UNIDAD).astype(int), 1)# Expandir filas: una por íconorows = []for _, r in top.iterrows():for i inrange(int(r["ICONOS"])): rows.append({"CAMPO DETALLADO": r["CAMPO DETALLADO"],"x": i # eje horizontal })source = pd.DataFrame(rows)# Gráfico horizontal con eje Xchart = ( alt.Chart(source) .mark_text(size=25, baseline='middle') .encode( alt.X('x:O', axis=alt.Axis(title=f"Número de íconos (1 = {UNIDAD} publicaciones)")), alt.Y('CAMPO DETALLADO:O', sort=top["CAMPO DETALLADO"].tolist()), alt.Text('emoji:N') ) .transform_calculate( emoji=f"{emoji_map}".replace("'", '"') +"[datum['CAMPO DETALLADO']]" ) .properties(width=800, height=400))chart
c:\Users\meagu\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``.
col = df[col_name].apply(to_list_if_array, convert_dtype=False)
1.5 Iteración 3
# Gráfico horizontal SIN eje X y SIN líneaschart = ( alt.Chart(source) .mark_text(size=25, baseline='middle') .encode( alt.X('x:O', axis=None), # ❌ elimina por completo el eje X alt.Y('CAMPO DETALLADO:O', sort=top["CAMPO DETALLADO"].tolist(), axis=alt.Axis(ticks=False, domain=False, grid=False) ), alt.Text('emoji:N') ) .transform_calculate( emoji=f"{emoji_map}".replace("'", '"') +"[datum['CAMPO DETALLADO']]" ) .properties(width=800, height=400))chart
c:\Users\meagu\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``.
col = df[col_name].apply(to_list_if_array, convert_dtype=False)
# Gráfico horizontal SIN eje X y SIN nombre/líneas en el eje Ychart = ( alt.Chart(source) .mark_text(size=25, baseline='middle') .encode( alt.X('x:O', axis=None), # ❌ elimina el eje X completo alt.Y('CAMPO DETALLADO:O', sort=top["CAMPO DETALLADO"].tolist(), axis=alt.Axis( ticks=False, domain=False, grid=False, title=None# ❌ sin nombre del eje Y ) ), alt.Text('emoji:N') ) .transform_calculate( emoji=f"{emoji_map}".replace("'", '"') +"[datum['CAMPO DETALLADO']]" ) .properties(width=800, height=400))chart
c:\Users\meagu\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``.
col = df[col_name].apply(to_list_if_array, convert_dtype=False)