
De matplotlib a Plotly: visualización interactiva
“Una imagen vale más que mil filas en una tabla.”
La Dual Coding Theory (Paivio, 1971) propone que combinar representaciones verbal y visual activa canales cognitivos independientes, potenciando la retención. Estudios posteriores cuantifican este efecto: la retención a 72h sube de ~10% (solo audio) a ~65% cuando se añade imagen (Medina, 2008).
Una buena visualización revela patrones ocultos en los datos
Las visualizaciones interactivas permiten explorar y contar historias
Para hacer una figura, necesitamos conocer una figura.
Cada figura en matplotlib tiene una estructura jerárquica:
fig, ax = plt.subplots()
fig → Figure (lienzo completo)
ax → Axes (área de graficación)
├── ax.set_title() → Title
├── ax.xaxis / ax.yaxis → Ejes
│ ├── ax.set_xlabel() → Label
│ ├── ax.set_xticks() → Ticks
│ └── ax.set_xticklabels() → Tick Labels
├── ax.spines → Spines (bordes)
├── ax.legend() → Legend
└── ax.plot() / ax.bar() → Plot data












| Característica | matplotlib | Plotly |
|---|---|---|
| Interactividad | Estático (imagen) | Nativa (hover, zoom, pan) |
| Web | Requiere backend | HTML nativo |
| Hover/tooltips | Manual y limitado | Automático |
| Exportación | PNG, SVG, PDF | HTML, PNG, SVG, PDF |
| Curva de aprendizaje | Moderada | Baja con plotly.express |
| Integración Quarto | Como imagen | Como widget interactivo |

import plotly.express as px
gapminder = px.data.gapminder()
gapminder_2007 = df.query("year == 2007")
fig = px.scatter(
gapminder_2007,
x="gdpPercap",
y="lifeExp",
size="pop",
color="continent",
hover_name="country",
log_x=True,
size_max=60,
title="Esperanza de vida vs PIB per cápita (2007)",
labels={"gdpPercap": "PIB per cápita (USD)",
"lifeExp": "Esperanza de vida (años)",
"pop": "Población"}
)
fig.show()| country | continent | year | lifeExp | pop | gdpPercap | iso_alpha | iso_num | |
|---|---|---|---|---|---|---|---|---|
| 0 | Afghanistan | Asia | 1952 | 28.801 | 8425333 | 779.445314 | AFG | 4 |
| 1 | Afghanistan | Asia | 1957 | 30.332 | 9240934 | 820.853030 | AFG | 4 |
| 2 | Afghanistan | Asia | 1962 | 31.997 | 10267083 | 853.100710 | AFG | 4 |
| 3 | Afghanistan | Asia | 1967 | 34.020 | 11537966 | 836.197138 | AFG | 4 |
| 4 | Afghanistan | Asia | 1972 | 36.088 | 13079460 | 739.981106 | AFG | 4 |
| 5 | Afghanistan | Asia | 1977 | 38.438 | 14880372 | 786.113360 | AFG | 4 |
| 6 | Afghanistan | Asia | 1982 | 39.854 | 12881816 | 978.011439 | AFG | 4 |
| 7 | Afghanistan | Asia | 1987 | 40.822 | 13867957 | 852.395945 | AFG | 4 |
| country | continent | year | lifeExp | pop | gdpPercap | iso_alpha | iso_num | |
|---|---|---|---|---|---|---|---|---|
| 11 | Afghanistan | Asia | 2007 | 43.828 | 31889923 | 974.580338 | AFG | 4 |
| 23 | Albania | Europe | 2007 | 76.423 | 3600523 | 5937.029526 | ALB | 8 |
| 35 | Algeria | Africa | 2007 | 72.301 | 33333216 | 6223.367465 | DZA | 12 |
| 47 | Angola | Africa | 2007 | 42.731 | 12420476 | 4797.231267 | AGO | 24 |
| 59 | Argentina | Americas | 2007 | 75.320 | 40301927 | 12779.379640 | ARG | 32 |
| 71 | Australia | Oceania | 2007 | 81.235 | 20434176 | 34435.367440 | AUS | 36 |
| 83 | Austria | Europe | 2007 | 79.829 | 8199783 | 36126.492700 | AUT | 40 |
| 95 | Bahrain | Asia | 2007 | 75.635 | 708573 | 29796.048340 | BHR | 48 |
Esta presentación es la prueba:
La mejor forma de aprender Plotly es copiar y adaptar desde la galería oficial:
Important
Lo más importante no es memorizar, sino entender qué estructura de datos necesita cada gráfico.
La mayoría de gráficos en plotly.express esperan datos en formato long (tidy):
| país | 2020 | 2021 | 2022 |
|---|---|---|---|
| MX | 10 | 12 | 15 |
| CO | 8 | 9 | 11 |
→
| país | año | valor |
|---|---|---|
| MX | 2020 | 10 |
| MX | 2021 | 12 |
| MX | 2022 | 15 |
| CO | 2020 | 8 |
| CO | 2021 | 9 |
| CO | 2022 | 11 |
La Agenda 2030 de Naciones Unidas define 17 Objetivos de Desarrollo Sostenible.
Vamos a trabajar con el indicador ODS 3.2.1:
Tasa de mortalidad de menores de 5 años (por cada 1,000 nacidos vivos)
Fuentes de datos abiertos:
Dimensiones: (84, 5)
Países: 12
Período: 1990 - 2020
Columnas: ['pais', 'iso_alpha', 'año', 'mortalidad_menores_5', 'region']
| pais | iso_alpha | año | mortalidad_menores_5 | region | |
|---|---|---|---|---|---|
| 0 | Argentina | ARG | 1990 | 28.7 | América del Sur |
| 1 | Argentina | ARG | 1995 | 23.5 | América del Sur |
| 2 | Argentina | ARG | 2000 | 20.2 | América del Sur |
| 3 | Argentina | ARG | 2005 | 16.7 | América del Sur |
| 4 | Argentina | ARG | 2010 | 14.1 | América del Sur |
| 5 | Argentina | ARG | 2015 | 11.1 | América del Sur |
| 6 | Argentina | ARG | 2020 | 8.7 | América del Sur |
| 7 | Bolivia | BOL | 1990 | 122.5 | América del Sur |
| 8 | Bolivia | BOL | 1995 | 99.8 | América del Sur |
| 9 | Bolivia | BOL | 2000 | 80.4 | América del Sur |
Note
Los datos ya están en formato long — exactamente lo que Plotly Express necesita.
| Recurso | URL |
|---|---|
| Galería Plotly | plotly.com/python/ |
| Plotly Express API | plotly.com/python-api-reference/ |
| Quarto + Plotly | quarto.org/docs/interactive/ |
| API ODS (ONU) | unstats.un.org/sdgapi/ |
| Banco Mundial | data.worldbank.org |
| Código de esta sesión | Este repositorio |
Note
La clave no es memorizar funciones, sino entender qué estructura de datos necesita cada gráfico y saber buscar en la galería.
Explora, copia, adapta, y cuenta tu historia con datos.