W3docs

Comprender los Diagramas de Dispersión en Python

Aprende a crear e interpretar diagramas de dispersión en Python con Matplotlib y Seaborn. Correlación, codificación de color, regresión y uso en ML.

Un diagrama de dispersión coloca un punto en cada par (x, y) de un conjunto de datos. La nube de puntos resultante revela si dos variables numéricas están relacionadas, con qué intensidad y en qué dirección, lo que hace que los diagramas de dispersión sean indispensables para el análisis exploratorio de datos y los flujos de trabajo de aprendizaje automático.

Este capítulo cubre:

  • Qué muestran los diagramas de dispersión y cómo leerlos
  • Crear diagramas de dispersión con Matplotlib y Seaborn
  • Personalizar colores, tamaños y transparencia
  • Codificar una tercera variable con color o tamaño (gráficos de burbujas)
  • Representar múltiples grupos con una leyenda
  • Añadir una línea de tendencia de regresión
  • Casos de uso comunes en aprendizaje automático

Qué Muestra un Diagrama de Dispersión

Cada punto representa una observación. El eje horizontal contiene una variable y el eje vertical contiene otra. La forma general de la nube indica la correlación entre las dos variables.

Interpretar el Patrón

PatrónSignificado
Los puntos ascienden de izquierda a derechaCorrelación positiva — cuando X aumenta, Y tiende a aumentar
Los puntos descienden de izquierda a derechaCorrelación negativa — cuando X aumenta, Y tiende a disminuir
Sin forma discernibleSin correlación lineal entre las variables
Banda estrecha y apretadaCorrelación fuerte
Nube amplia y difusaCorrelación débil
Puntos alejados de la nube principalValores atípicos — vale la pena investigarlos

El coeficiente de correlación de Pearson r resume este patrón como un único número de -1 (negativo perfecto) a +1 (positivo perfecto). Un valor cercano a 0 significa que no hay relación lineal. Los diagramas de dispersión permiten ver lo que r no puede mostrar; por ejemplo, dos conjuntos de datos pueden compartir el mismo r pero tener formas completamente distintas (véase el cuarteto de Anscombe).

Crear un Diagrama de Dispersión con Matplotlib

plt.scatter() de Matplotlib es la opción más flexible. Instala Matplotlib si aún no lo has hecho:

pip install matplotlib numpy

Ejemplo Básico

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(seed=42)

# Simulate hours studied vs exam score
hours = rng.uniform(1, 10, 40)
score = 5 * hours + rng.normal(scale=8, size=40)

plt.scatter(hours, score)
plt.xlabel('Hours Studied')
plt.ylabel('Exam Score')
plt.title('Hours Studied vs Exam Score')
plt.tight_layout()
plt.show()

La pendiente positiva en la nube resultante muestra que más horas de estudio se correlacionan con puntuaciones de examen más altas.

Personalizar el Color y el Tamaño de los Marcadores

Los tres parámetros más útiles de plt.scatter() son:

  • c — nombre de color, cadena hexadecimal o array de valores (mapeados a través de un mapa de colores)
  • s — tamaño del marcador en puntos al cuadrado (por defecto 20); acepta un escalar o un array
  • alpha — transparencia de 0 (invisible) a 1 (sólido); usa 0.4–0.7 para puntos superpuestos
import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(seed=7)

x = rng.normal(loc=5, scale=2, size=60)
y = rng.normal(loc=5, scale=2, size=60)

plt.scatter(x, y, c='steelblue', s=80, alpha=0.6, edgecolors='white', linewidths=0.5)
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Customized Scatter Plot')
plt.tight_layout()
plt.show()

edgecolors='white' con linewidths=0.5 añade un borde blanco fino alrededor de cada punto, lo que facilita distinguir los puntos individuales cuando se superponen.

Codificar una Tercera Variable con Color

Pasa un array a c para colorear cada punto según una tercera variable numérica. Añade plt.colorbar() para que los lectores sepan qué representan los colores:

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(seed=3)

x = rng.random(50)
y = rng.random(50)
temperature = rng.uniform(15, 35, 50)   # third variable, e.g. temperature in °C

scatter = plt.scatter(x, y, c=temperature, cmap='coolwarm', s=80, alpha=0.8)
plt.colorbar(scatter, label='Temperature (°C)')
plt.xlabel('Longitude')
plt.ylabel('Latitude')
plt.title('Sensor Readings by Temperature')
plt.tight_layout()
plt.show()

Utiliza mapas de colores perceptualmente uniformes — 'viridis', 'plasma', 'cividis' o 'coolwarm' — en lugar de 'jet' o 'rainbow', que distorsionan la percepción y no son accesibles para personas con daltonismo.

Codificar una Tercera Variable con el Tamaño de las Burbujas

Pasa un array a s para que el área de cada marcador sea proporcional a una tercera variable; esto se denomina gráfico de burbujas:

import matplotlib.pyplot as plt
import numpy as np

countries = ['USA', 'China', 'Japan', 'Germany', 'UK']
gdp       = [25.5, 18.0, 4.2, 4.1, 3.1]          # trillion USD
life_exp  = [76.4, 77.1, 84.3, 80.6, 81.3]        # years
population = [334, 1412, 125, 84, 67]             # millions — encoded as size

# Scale population to a visible marker area range
sizes = [p * 1.5 for p in population]

plt.scatter(gdp, life_exp, s=sizes, alpha=0.6, edgecolors='black', linewidths=0.8)

for i, name in enumerate(countries):
    plt.annotate(name, (gdp[i], life_exp[i]), textcoords='offset points',
                 xytext=(6, 4), fontsize=9)

plt.xlabel('GDP (trillion USD)')
plt.ylabel('Life Expectancy (years)')
plt.title('GDP vs Life Expectancy (bubble size = population)')
plt.tight_layout()
plt.show()

Crear un Diagrama de Dispersión con Seaborn

sns.scatterplot() de Seaborn trabaja directamente con DataFrames de Pandas y añade funciones como la agrupación automática por una columna categórica y el parámetro integrado hue para la codificación de color.

Instala Seaborn primero:

pip install seaborn pandas

Diagrama de Dispersión Básico con Seaborn

import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt

data = pd.DataFrame({
    'hours':  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    'score':  [45, 50, 55, 60, 65, 70, 72, 80, 85, 92],
})

sns.scatterplot(data=data, x='hours', y='score')
plt.xlabel('Hours Studied')
plt.ylabel('Exam Score')
plt.title('Hours Studied vs Exam Score')
plt.tight_layout()
plt.show()

Codificar Grupos con Color usando hue

El parámetro hue asigna automáticamente un color diferente a cada categoría y añade una leyenda:

import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt

data = pd.DataFrame({
    'sepal_length': [5.1, 4.9, 6.3, 5.8, 7.0, 6.4, 6.3, 5.8, 7.1, 6.3],
    'sepal_width':  [3.5, 3.0, 2.9, 2.7, 3.2, 3.2, 3.3, 2.7, 3.0, 2.9],
    'species':      ['setosa', 'setosa', 'versicolor', 'versicolor',
                     'virginica', 'virginica', 'virginica', 'versicolor',
                     'virginica', 'virginica'],
})

sns.scatterplot(data=data, x='sepal_length', y='sepal_width', hue='species')
plt.title('Iris: Sepal Length vs Sepal Width')
plt.tight_layout()
plt.show()

Seaborn crea la leyenda automáticamente. Esto equivale a llamar a plt.scatter() varias veces con distintos colores.

Añadir una Línea de Regresión con sns.regplot()

sns.regplot() combina un diagrama de dispersión con una línea de regresión ajustada y una banda de confianza:

import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(seed=10)
x = np.linspace(1, 10, 30)
y = 3 * x + rng.normal(scale=4, size=30)

data = pd.DataFrame({'x': x, 'y': y})

sns.regplot(data=data, x='x', y='y', scatter_kws={'alpha': 0.6}, line_kws={'color': 'red'})
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Scatter Plot with Regression Line')
plt.tight_layout()
plt.show()

El área sombreada alrededor de la línea es un intervalo de confianza del 95%. Usa ci=None para eliminarlo.

Representar Múltiples Grupos

Con Matplotlib

Llama a plt.scatter() una vez por grupo y establece label= en cada llamada:

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(seed=0)

groups = {
    'Group A': (2, 3),
    'Group B': (6, 6),
    'Group C': (9, 2),
}

for name, (cx, cy) in groups.items():
    x = rng.normal(loc=cx, scale=0.6, size=30)
    y = rng.normal(loc=cy, scale=0.6, size=30)
    plt.scatter(x, y, s=50, alpha=0.7, label=name)

plt.legend()
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Three Distinct Clusters')
plt.tight_layout()
plt.show()

Cada llamada a scatter() selecciona automáticamente el siguiente color del ciclo de colores predeterminado de Matplotlib.

Con Seaborn

Pasa un DataFrame y usa hue= y opcionalmente style= para diferenciar los grupos:

import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(seed=1)

rows = []
for group, (cx, cy) in [('A', (2, 3)), ('B', (6, 6)), ('C', (9, 2))]:
    for _ in range(25):
        rows.append({'x': rng.normal(cx, 0.6), 'y': rng.normal(cy, 0.6), 'group': group})

df = pd.DataFrame(rows)

sns.scatterplot(data=df, x='x', y='y', hue='group', style='group')
plt.title('Three Clusters — Seaborn Multi-Group')
plt.tight_layout()
plt.show()

style='group' asigna una forma de marcador distinta a cada grupo además del color, lo que ayuda a los lectores que imprimen en blanco y negro.

Diagramas de Dispersión en Aprendizaje Automático

Los diagramas de dispersión no son solo para la exploración; forman parte del flujo de trabajo central del aprendizaje automático.

1. Comprobar Relaciones Lineales Antes de la Regresión

Antes de entrenar un modelo de regresión lineal, representa las características de entrada frente al objetivo. Una dispersión aproximadamente lineal indica que la regresión lineal es apropiada:

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(seed=5)
house_size  = rng.uniform(50, 300, 60)            # square metres
house_price = 2000 * house_size + rng.normal(scale=40000, size=60)  # EUR

plt.scatter(house_size, house_price, alpha=0.6, s=50)
plt.xlabel('House Size (m²)')
plt.ylabel('Price (EUR)')
plt.title('House Size vs Price — linear pattern suggests linear regression')
plt.tight_layout()
plt.show()

Si la dispersión muestra una curva en lugar de una línea, puede que necesites características polinómicas o un modelo diferente.

2. Visualizar Clústeres Tras K-Means

Después de ejecutar un algoritmo de agrupamiento como k-means, colorea cada punto según su etiqueta de clúster para confirmar la separación:

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(seed=8)

# Simulate cluster assignments from k-means
centers = [(1, 1), (5, 5), (9, 1)]
X, labels = [], []
for i, (cx, cy) in enumerate(centers):
    X.extend(zip(rng.normal(cx, 0.7, 30), rng.normal(cy, 0.7, 30)))
    labels.extend([i] * 30)

X = np.array(X)
labels = np.array(labels)

colors = ['tab:blue', 'tab:orange', 'tab:green']
for k in range(3):
    mask = labels == k
    plt.scatter(X[mask, 0], X[mask, 1], c=colors[k], s=50, alpha=0.7, label=f'Cluster {k}')

plt.legend()
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title('K-Means Cluster Assignments')
plt.tight_layout()
plt.show()

Las nubes bien separadas confirman que el algoritmo encontró agrupaciones con sentido.

3. Evaluar las Predicciones de un Modelo de Regresión

Representa los valores reales frente a los predichos después de entrenar un modelo. Un modelo perfecto produce puntos a lo largo de la diagonal y = x:

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(seed=2)

# Simulate actual and predicted values from a trained model
actual    = rng.uniform(10, 100, 50)
predicted = actual + rng.normal(scale=8, size=50)   # model with some noise

plt.scatter(actual, predicted, alpha=0.6, s=60, edgecolors='black', linewidths=0.5)
# Draw the ideal y = x line
lim = [min(actual.min(), predicted.min()) - 5, max(actual.max(), predicted.max()) + 5]
plt.plot(lim, lim, 'r--', linewidth=1.5, label='Perfect prediction')
plt.xlim(lim)
plt.ylim(lim)
plt.xlabel('Actual Values')
plt.ylabel('Predicted Values')
plt.title('Actual vs Predicted — regression model evaluation')
plt.legend()
plt.tight_layout()
plt.show()

Los puntos distribuidos aleatoriamente alrededor de la diagonal (sin forma de arco o abanico sistemática) indican que los errores del modelo son imparciales.

4. Visualizar la Reducción de Dimensionalidad (PCA / t-SNE)

Tras reducir datos de alta dimensión a dos dimensiones con PCA o t-SNE, un diagrama de dispersión es la forma natural de mostrar el resultado. Cada punto es una observación; el color indica su etiqueta de clase:

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(seed=20)

# Simulate 2-D PCA output for three classes
class_data = {
    'Class 0': ((-3, 0), 0.8),
    'Class 1': ((0, 3), 0.8),
    'Class 2': ((3, 0), 0.8),
}

for label, ((cx, cy), spread) in class_data.items():
    x = rng.normal(cx, spread, 40)
    y = rng.normal(cy, spread, 40)
    plt.scatter(x, y, s=30, alpha=0.7, label=label)

plt.legend()
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.title('PCA Projection — 2D visualization of high-dimensional data')
plt.tight_layout()
plt.show()

Los clústeres que se separan claramente tras la reducción sugieren que las clases son genuinamente distinguibles por las características originales.

Guardar Diagramas de Dispersión en un Archivo

Usa plt.savefig() antes de plt.show() — llamar a show() primero borra la figura:

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(seed=99)
x = rng.random(50)
y = rng.random(50)

plt.scatter(x, y, alpha=0.7, s=60)
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Scatter Plot')
plt.tight_layout()

plt.savefig('scatter.png', dpi=150)    # raster — good for web
plt.savefig('scatter.pdf')              # vector — best for publications
plt.show()

Usa dpi=300 para imágenes PNG de calidad de impresión.

Cuándo Usar Cada Biblioteca

SituaciónHerramienta recomendada
Gráfico rápido con arrays de NumPymatplotlib.pyplot.scatter()
Trabajar con DataFrames de Pandasseaborn.scatterplot()
Necesitar codificación de color o tamaño por puntomatplotlib.pyplot.scatter()
Querer agrupación automática por columnaseaborn.scatterplot(hue=...)
Querer una línea de regresión integradaseaborn.regplot()
Personalización profunda de Matplotlibfig, ax = plt.subplots() y luego ax.scatter()

Para un análisis completo de los parámetros de diagramas de dispersión de Matplotlib — incluyendo escalas logarítmicas, anotaciones, formas de marcadores y comparaciones entre scatter() y plot() — consulta el capítulo Matplotlib Scatter Plots.

Errores Comunes

Variable no definida. Cada fragmento de código de este capítulo es independiente. Si combinas fragmentos, asegúrate de que x e y estén definidos en el mismo script antes de llamar a plt.scatter().

Figura no limpiada entre gráficos. Después de plt.show(), Matplotlib borra la figura. Si ejecutas fragmentos en un cuaderno de Jupyter, cada celda crea una figura nueva automáticamente. En un script Python normal, llama a plt.figure() para iniciar un nuevo gráfico si deseas varios diagramas separados.

Superposición de puntos. Con muchos puntos apilados unos encima de otros, el gráfico parece una mancha rellena. Soluciona esto con alpha=0.3 para mostrar la densidad, o cambia a plt.hexbin() para el agrupamiento en histograma 2D.

Sin barra de color. Si pasas un array a c, añade siempre plt.colorbar() — sin ella, los lectores no pueden descifrar la escala de colores.

Capítulos Relacionados

Was this page helpful?