Plotly es una biblioteca de Python de código abierto diseñada para crear visualizaciones de datos interactivas de calidad profesional. Desarrollada por Plotly Inc, el paquete plotly ha consolidado bajo un único distribuible las antiguas variantes plotly-express, plotly-py y chart-studio: hoy basta con pip install plotly para disponer de toda la API oficial, sin tener que instalar paquetes paralelos ni combinarlos manualmente. Los gráficos generados se renderizan encima de plotly.js y permiten hacer zoom, desplazarse, obtener tooltips al pasar el cursor y seleccionar puntos con herramientas de lazo.
Arquitectura interna: plotly.js, Plotly Express y Graph Objects
El ecosistema plotly.py se organiza en tres capas que cooperan entre sí. La capa más baja es el motor plotly.js (TypeScript + WebGL) que se ejecuta en el navegador. Encima se sitúan los Graph Objects (plotly.graph_objects), con las clases Figure, Scatter, Bar, Layout y Frame que modelan fielmente el esquema JSON del motor. Por último, Plotly Express (plotly.express) es la API declarativa sobre DataFrames que genera ese mismo Figure en una sola llamada.
flowchart TB
user[Código Python del usuario] --> px[plotly.express]
user --> go[plotly.graph_objects]
user --> ff[plotly.figure_factory]
px --> fig[Figure: data + layout + frames]
go --> fig
ff --> fig
fig -->|JSON serializable| js[plotly.js]
js -->|WebGL / SVG| browser[Navegador]
Plotly Express vs Graph Objects vs figure_factory
Las tres APIs producen un Figure equivalente pero difieren en nivel de abstracción. Plotly Express resuelve el 80 % de los casos con una línea y acepta un DataFrame. Graph Objects expone el esquema completo y es imprescindible para make_subplots, animaciones frame a frame o para mezclar varios tipos de traza. figure_factory cubre plantillas específicas (distplots legacy, gráficos de Gantt, tablas con formato) que aún no han sido reabsorbidas por Express.
flowchart LR
express[plotly.express] -->|una línea, DataFrame| fig[Figure]
go2[plotly.graph_objects] -->|control total del esquema| fig
ff2[plotly.figure_factory] -->|plantillas especializadas: Gantt, distplot| fig
fig --> out[fig.show / fig.to_html]
Anatomía de una figura: data, layout y frames
Una Figure es un diccionario JSON con tres claves principales: data (lista de trazas), layout (ejes, títulos, colores, leyenda, updatemenus, sliders) y frames (fotogramas para animaciones). Plotly Express rellena estos tres apartados automáticamente cuando se usa animation_frame; con Graph Objects hay que construirlos a mano y pasarlos a go.Figure(data=..., layout=..., frames=...).
flowchart TD
figure[Figure]
figure --> data[data: lista de trazas]
figure --> layout[layout: ejes, título, colores, sliders]
figure --> frames[frames: fotogramas para animaciones]
data --> tr1[Scatter / Bar / Choropleth / Surface]
layout --> xaxis[xaxis, yaxis]
layout --> updatemenus[updatemenus y sliders]
frames --> f1[frame 1: data para año N]
frames --> fN[frame N: data para año N+k]
Integración con Dash y Streamlit
Plotly se consume desde cualquier aplicación web Python, pero las dos integraciones oficiales son Dash (SPA reactiva construida sobre React con callbacks Python) y Streamlit (apps lineales donde cada rerun repinta los gráficos). En Dash, la figura se pasa al componente dcc.Graph y se reconstruye dentro de un callback; en Streamlit, st.plotly_chart(fig, use_container_width=True) basta.
flowchart LR
data[(DataFrame Pandas)] --> fig[Figure de Plotly]
fig --> dash[Dash · dcc.Graph + callbacks]
fig --> streamlit[Streamlit · st.plotly_chart]
fig --> html[fig.write_html - página estática]
dash --> servidor[Servidor WSGI/ASGI · Gunicorn]
streamlit --> streamlit_cloud[Streamlit Cloud]
html --> cdn[CDN o GitHub Pages]
Renderizado: SVG vs WebGL (Scattergl)
Cuando el número de puntos supera los pocos miles, el renderizado SVG por defecto se ralentiza. Plotly ofrece variantes sufijadas con gl (Scattergl, Scatter3d, Scatterpolargl, Choroplethmapbox) que delegan en WebGL y escalan a cientos de miles de puntos conservando interactividad. La contrapartida es que el DOM no contiene los nodos individuales, lo que limita algunas personalizaciones CSS.
flowchart LR
decision{Número de puntos}
decision -->|hasta miles| svg[Traza SVG · go.Scatter]
decision -->|decenas o cientos de miles| webgl[Traza WebGL · go.Scattergl]
svg --> pro1[Control CSS por nodo]
svg --> con1[Se ralentiza con volumen alto]
webgl --> pro2[Rendimiento alto, GPU]
webgl --> con2[Sin nodos DOM individuales]
Exportación: HTML, PNG, SVG y PDF
El formato nativo de Plotly es HTML interactivo (fig.write_html), que embebe el JSON de la figura más una referencia a plotly.js y se puede servir desde cualquier CDN o abrir localmente. Para imágenes estáticas, fig.write_image("grafico.png") delega en Kaleido (binario Chromium headless) que ha sustituido al antiguo plotly-orca; Kaleido produce PNG, SVG, PDF, JPEG y WebP sin requerir instalación de Node.
flowchart TB
fig[Figure]
fig --> html[fig.write_html - interactivo con plotly.js]
fig --> image[fig.write_image - Kaleido]
image --> png[PNG]
image --> svg[SVG]
image --> pdf[PDF]
image --> jpeg[JPEG / WebP]
fig --> json[fig.to_json - persistencia y versionado]
Ecosistema moderno (Plotly 6.x y Dash 3.x)
Las versiones recientes de Plotly 6.x han consolidado varios cambios importantes. El paquete plotly-express se ha integrado en plotly como submódulo plotly.express; las figuras exponen métodos fluidos fig.update_traces, fig.update_layout y fig.update_xaxes que evitan tener que reconstruir el diccionario; FigureWidget e ipywidgets siguen siendo la forma estándar de obtener interactividad en Jupyter, y los mapas mapbox se están migrando a proveedores basados en maplibre-gl y tiles abiertos para evitar la dependencia del token comercial. En el lado de Dash, las versiones 2.x y 3.x introducen el decorador @callback a nivel de módulo, el nuevo dash.Patch() para actualizaciones parciales sin reenviar el estado completo y el soporte nativo de componentes all_in_one.
Qué incluye este itinerario
- Introducción e instalación: qué es Plotly, comparativa con Matplotlib y Seaborn, instalación con
pip, primer gráfico e integración con Jupyter y JupyterLab. - Gráficos básicos: scatter, líneas, barras, circulares, histogramas, box plots y violin plots con Plotly Express.
- Gráficos avanzados: heatmaps, gráficos 3D, mapas geográficos (choropleth y scatter_mapbox/maplibre), sunburst, treemap y funnel.
- Personalización: layouts, ejes, anotaciones, colores, temas, templates y subplots con
make_subplots. - Interactividad: hover templates, eventos de clic, sliders, dropdowns, animaciones con
framesy rangeslider. - Dash: framework para aplicaciones web, callbacks, layouts, componentes, multi-página,
dash.Patchy despliegue. - Integraciones: Pandas, Plotly Express vs Graph Objects, exportación con Kaleido y visualización en Streamlit.
Público objetivo
- Científicos de datos que necesitan crear visualizaciones interactivas y exploratorias para análisis de datos.
- Analistas de negocio que buscan construir dashboards profesionales para comunicar métricas y resultados.
- Desarrolladores Python que quieren añadir visualizaciones interactivas a sus aplicaciones web con Dash.
- Investigadores que necesitan gráficos de calidad publicación con capacidades interactivas para presentaciones y artículos.
- Estudiantes de ciencia de datos que desean dominar herramientas modernas de visualización demandadas en el mercado laboral.
Prerrequisitos: conocimientos básicos de Python (variables, funciones, listas, diccionarios), familiaridad con Pandas para manipulación de datos y manejo básico de Jupyter Notebooks. No se requiere experiencia previa con Plotly ni con otras bibliotecas de visualización.