Curso
Plotly no va solo de crear visualizaciones bonitas; va de sacar todo el partido a tus datos y destapar insights que, de otro modo, pasarían desapercibidos. Es el puente entre el lenguaje de los números y el lenguaje de las historias, y ayuda a personas y organizaciones a tomar decisiones informadas y generar un impacto real.
Así es como ChatGPT describe Plotly. Está claro: Plotly es una de las mejores librerías de visualización de datos que existen.

Crea gráficos muy interactivos y visualmente atractivos como el siguiente:
Hoy aprenderás los fundamentos para crear visualizaciones increíbles con Plotly.
Conceptos básicos de Plotly Express
Como en cualquier tutorial, empezamos instalando la librería con pip (o, si lo prefieres, con conda).
$ pip install --upgrade plotly
$ conda install -c conda-forge plotly
Plotly se actualiza con frecuencia, así que asegúrate de incluir la etiqueta --upgrade si ya la tenías instalada.
Este tutorial se centra en la API Express de Plotly, introducida en 2019, que ofrece muchas ventajas frente a las formas antiguas de interactuar con la librería principal de Plotly:
- Sintaxis sencilla (se lee casi como si fuera inglés)
- Amplia variedad de visualizaciones (o herramientas para crear las tuyas)
- Escalado automático de ejes y colores
- Integración con pandas (puedes usar Plotly como backend de gráficos para la función
.plotde pandas)
Esta es la anatomía de un gráfico básico en Plotly Express:
import plotly.express as px
fig = px.plotting_function(
dataframe,
x='column-for-xaxis',
y='column-for-yaxis',
title='Title For the Plot',
width=width_in_pixels,
height=height_in_pixels
)
fig.show()
Los distintos tipos de gráfico tienen su propio nombre, como histogram o scatter, dentro del módulo express, que cargamos como px. El primer argumento de cualquier función de graficado es el dataframe y los nombres de las columnas que se representarán en los ejes X e Y.
Como buena práctica, añade siempre un title informativo para que quien lo vea entienda de qué va el gráfico.
Cuando una función de graficado se ejecuta, devuelve un objeto Figure sobre el que llamas al método show para mostrar el gráfico en tu querido notebook.
Para empezar a crear gráficos, necesitamos un conjunto de datos. En este tutorial usamos el conjunto de datos Diamonds. Incluye una buena combinación de variables numéricas y categóricas: perfecto para lo que buscamos.
import pandas as pd
diamonds = pd.read_csv("data/diamonds.csv")
diamonds.head()

El dataset contiene más de 53.000 diamantes con 10 características físicas. Puedes explorar las estadísticas básicas a continuación.
diamonds.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 53940 entries, 0 to 53939
Data columns (total 10 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 carat 53940 non-null float64
1 cut 53940 non-null object
2 color 53940 non-null object
3 clarity 53940 non-null object
4 depth 53940 non-null float64
5 table 53940 non-null float64
6 price 53940 non-null int64
7 x 53940 non-null float64
8 y 53940 non-null float64
9 z 53940 non-null float64
dtypes: float64(6), int64(1), object(3)
memory usage: 4.1+ MB
diamonds.describe()
Una de las primeras tareas al hacer análisis exploratorio de datos (EDA) es explorar las distribuciones individuales.
Plotly ofrece muchos gráficos para ello: histogramas, diagramas de caja, violines, gráficos de barras, etc. Veamos algunos.
Histogramas en Plotly Express
El histograma suele ser el primer gráfico que aprendemos.
Ordena los valores de una distribución en intervalos (bins). Luego, usa barras para representar cuántos valores caen en cada intervalo:
import plotly.express as px
fig = px.histogram(
diamonds,
x="price",
title="Histograma de precios de diamantes",
width=600,
height=400,
)
fig.show()

Si pasas el ratón sobre cualquier barra, verás el rango del intervalo correspondiente. Plotly calcula automáticamente el número de intervalos, pero si quieres fijarlo tú, puedes usar el parámetro nbins.
Ahora bien, encontrar el número perfecto de intervalos para cada distribución es complicado. Por eso, una práctica común es fijar el número de intervalos igual a la raíz cuadrada de la longitud de la distribución:
# Calcula un número adecuado de intervalos (bins)
nbins = int(len(diamonds) ** (1 / 2))
fig = px.histogram(
diamonds,
x="price",
title="Histograma de precios de diamantes",
nbins=nbins,
width=600,
height=400,
)
fig.show()
Gráficos de barras en Plotly Express
Los histogramas analizan variables cuantitativas. Para analizar datos categóricos, recurrimos a los gráficos de barras. Por ejemplo, si pasamos la columna categórica cut a la función histogram, obtenemos un tipo de barra llamado countplot. Sí, lo has adivinado: cuenta el número de observaciones en cada categoría.
fig = px.histogram(diamonds, x="cut")
fig.show()

¡Pero no hemos puesto etiquetas! Vamos a solucionarlo con la función update_layout, que permite modificar muchos aspectos de una figura después de crearla.
fig.update_layout(
title="Número de diamantes por categoría de corte",
xaxis_title="",
yaxis_title="Recuento",
)

Ya sabes lo que hace title. Los parámetros xaxis_title y yaxis_title sustituyen las etiquetas de los ejes que Plotly genera por defecto (que son simplemente los nombres de las columnas).
Ahora veamos el precio medio por categoría de corte. Primero, usamos groupby de pandas:
mean_prices = (
diamonds.groupby("cut")["price"].mean().reset_index()
)
mean_prices

Encadenar reset_index al final de una operación groupby convierte la salida en un DataFrame, y a Plotly le encantan los DataFrames. Así que vamos a pasarlo a su función bar:
fig = px.bar(mean_prices, x="cut", y="price")
fig.update_layout(
title="Precio medio de los diamantes por categoría de corte",
xaxis_title="",
yaxis_title="Precio medio ($)",
)
fig.show()

bar recibe una variable categórica y otra numérica y crea una barra por cada fila del DataFrame pasado. El resultado es una comparación clara de precios por tipo de diamante.
Diagramas de caja en Plotly Express
Otro gráfico habitual para analizar distribuciones es el diagrama de caja, que en Plotly Express se crea con box:
fig = px.box(diamonds, x="clarity", y="carat")
fig.update_layout(
title="Distribución de quilates por categoría de claridad",
xaxis_title="Clarity",
yaxis_title="Carat",
)
fig.show()

En lugar de mostrar barras con el promedio de quilates, el diagrama de caja presenta varias estadísticas:

Puedes ver:
- Mínimo/máximo
- Mediana
- Percentil 25
- Percentil 75
- y valores atípicos
para cada categoría de claridad.
Gráficos de violín en Plotly Express
Otro gráfico muy útil para explorar distribuciones es el violín. Los violines son, básicamente, diagramas de caja con algunos añadidos:
fig = px.violin(diamonds, x="cut", y="price")
fig.show()

En lugar de mostrar una caja, representan una curva suave que indica la densidad de la variable. Para superponer un diagrama de caja, establece el atributo box a True:
fig = px.violin(diamonds, x="cut", y="price", box=True)
fig.show()

A diferencia de los diagramas de caja, que solo muestran estadísticas resumen, los violines también muestran la forma de la distribución.
Visualizar relaciones entre variables en Plotly Express
Cuando representas variables relacionadas, empiezan a aflorar nuevos patrones e insights. Por ejemplo, si asumimos que el quilataje (peso) del diamante es el factor principal que determina su precio, exploremos esa relación.
Gráficos de dispersión en Plotly Express
Podemos usar un diagrama de dispersión (px.scatter), que coloca todos los diamantes del dataset como puntos. La posición viene determinada por sus valores de precio y quilates:
fig = px.scatter(diamonds, x="price", y="carat")
fig.update_layout(
title="Precio vs. quilates",
xaxis_title="Precio ($)",
yaxis_title="Quilates",
)
fig.show()

Nos topamos con un claro caso de overplotting, que ocurre cuando hay demasiados datos en un único gráfico. En lugar de mostrar patrones y tendencias reales, el exceso de puntos los oculta.
Podemos solucionarlo representando ~10% del dataset, suficiente para revelar los patrones existentes:
fig = px.scatter(
diamonds.sample(5000), x="price", y="carat"
)
fig.update_layout(
title="Precio vs. quilates",
xaxis_title="Precio ($)",
yaxis_title="Quilates",
)
fig.show()

En la llamada a scatter pasamos solo 5.000 filas (.sample(5000)), lo que deja ver una ligera tendencia ascendente en la relación precio-quilates.
Mapas de calor en Plotly Express
Los mapas de calor son ideales para visualizar datasets complejos, como una matriz grande en la que es difícil detectar patrones entre montones de números.
Un mapa de calor asigna colores en función de la magnitud de cada celda de una matriz. Un caso de uso típico es visualizar la matriz de correlaciones de un dataset.
La correlación mide la relación lineal entre variables numéricas. Así, cada celda de la matriz representa la correlación entre un par de variables.
Puedes calcular la matriz de correlación de cualquier dataset con el método corr de pandas, que devuelve un DataFrame. Si lo pasas a la función imshow de Express, obtendrás un mapa de calor:
import plotly.express as px
# Crear mapa de calor con Plotly Express
fig = px.imshow(
diamonds.corr(),
color_continuous_scale="Inferno_r",
)
# Mostrar gráfico
fig.show()

La correlación va de -1 a 1. Los valores cercanos a los extremos indican una relación lineal positiva o negativa fuerte entre variables.
Hemos elegido la paleta Inferno invertida para el parámetro color_continuous_scale. Puedes elegir otras en la página de escalas de color de la documentación de Plotly.
Personalizar gráficos en Plotly Express
Una de las grandes ventajas de la API de Plotly Express es lo fácil que es personalizar los gráficos.
La función update_layout incluye muchos parámetros para modificar prácticamente cualquier aspecto de tus charts.
Según dónde vayas a mostrar los gráficos, es tu responsabilidad dejarlos listos para cualquier público, evento o medio.
Una de las primeras decisiones es el tema del gráfico. Los temas en Plotly son configuraciones por defecto que controlan prácticamente todos los componentes.
Puedes cambiarlo con el parámetro template de cualquier función de graficado:
sample = diamonds.sample(3000)
fig = px.scatter(
sample, x="price", y="carat", template="ggplot2"
)
fig.show()

Algunos populares son ggplot2, seaborn, plotly_dark y presentation. Puedes ver la lista completa llamando a plotly.io.templates.
Colores
Hasta ahora, nuestros diagramas de dispersión han sido bidimensionales. Pero podemos añadir más información mediante el color.
Por ejemplo, podemos colorear cada punto según la categoría a la que pertenezca el diamante. Para ello, basta con pasar cut al parámetro color:
sample = diamonds.sample(3000)
fig = px.scatter(sample, x="price", y="carat", color="cut")
fig.show()

El parámetro cut también fuerza la aparición de una leyenda con los colores de cada categoría.
Tamaño de los marcadores
Otra opción es mostrar una variable numérica mediante el tamaño de los puntos.
Si establecemos el parámetro size a carat, obtendremos puntos de distinto tamaño según los quilates del diamante:
fig = px.scatter(sample, x="price", y="x", size="carat")
fig.show()

¿Y si usamos color y tamaño a la vez? ¡Claro que sí!
fig = px.scatter(
sample, x="price", y="x", size="carat", color="cut"
)
fig.show()

Aun así, este gráfico no es muy informativo: contiene demasiada información para procesarla de un vistazo. Como regla general, evita meter más de tres variables en un solo gráfico.
Conclusión
¡Enhorabuena por llegar hasta el final! Con lo que has aprendido en este tutorial puedes seguir avanzando con estos recursos:
- Curso de introducción a la visualización de datos con Plotly en Python
- Tutorial de visualización de datos con Plotly en R
- Tutorial para crear histogramas en Plotly
También puedes aprender sobre la API de Graph Objects de Plotly para más opciones de personalización, control total de la interactividad y las animaciones, y compatibilidad con tipos de visualización avanzados.

