Gráfico de dispersión de Matplotlib con gráficos de distribución (gráfico conjunto) - Tutorial y ejemplos

En este tutorial, veremos cómo trazar diagramas de dispersión con diagramas de distribución - Jointplots (diagramas conjuntos) en Python con Matplotlib, con ejemplos.

Introducción

Hay muchas bibliotecas de visualización de datos en Python, pero Matplotlib es la biblioteca más popular de todas. La popularidad de Matplotlib se debe a su confiabilidad y utilidad: es capaz de crear gráficos simples y complejos con poco código. También puede personalizar las tramas de varias formas.

En este tutorial, cubriremos cómo trazar un Joint Plot en Matplotlib que consiste en un Gráfico de dispersión y múltiples Gráficas de Distribución en la misma Figura.

Los gráficos conjuntos se utilizan para explorar las relaciones entre los datos bivariados, así como sus distribuciones al mismo tiempo.

Nota: Este tipo de tarea es mucho más adecuada para bibliotecas como Seaborn, que tiene una función jointplot() integrada. Con Matplotlib, construiremos un gráfico conjunto manualmente, utilizando GridSpec y varios objetos Axes, en lugar de que Seaborn lo haga por nosotros.

Importación de datos

Usaremos el famoso Conjunto de datos de iris, ya que podemos explorar la relación entre características como SepalWidthCm y SepalLengthCm a través de un Scatter Grafique, pero también explore las distribuciones entre la función ‘Especies’ teniendo en cuenta la longitud/anchura de su sépalo, a través de Diagramas de distribución al mismo tiempo.

Importemos el conjunto de datos y echemos un vistazo:

1
2
3
4
import pandas as pd

df = pd.read_csv('iris.csv')
print(df.head())

Esto resulta en:

1
2
3
4
5
6
   Id  SepalLengthCm  SepalWidthCm  PetalLengthCm  PetalWidthCm      Species
0   1            5.1           3.5            1.4           0.2  Iris-setosa
1   2            4.9           3.0            1.4           0.2  Iris-setosa
2   3            4.7           3.2            1.3           0.2  Iris-setosa
3   4            4.6           3.1            1.5           0.2  Iris-setosa
4   5            5.0           3.6            1.4           0.2  Iris-setosa

Exploraremos la relación bivariada entre las funciones SepalLengthCm y SepalWidthCm aquí, pero también sus distribuciones. Podemos abordar esto de dos maneras: con respecto a su ‘Especie’ o no.

Podemos ignorar por completo la función “Especies” y simplemente trazar histogramas de las distribuciones de cada instancia de flor. Por otro lado, podemos codificar por colores y trazar diagramas de distribución de cada instancia de flor, destacando también la diferencia en sus ‘Especies’.

Exploraremos ambas opciones aquí, comenzando con la más simple, ignorando las ‘Especies’ por completo.

Trace un gráfico conjunto en Matplotlib con histogramas de clase única

En el primer enfoque, simplemente cargaremos las instancias de flores y las trazaremos tal como están, sin tener en cuenta sus ‘Especies’.

Usaremos un [GridSpec] (https://matplotlib.org/stable/tutorials/intermediate/gridspec.html) para personalizar el diseño de nuestra figura, para hacer espacio para tres gráficos diferentes e instancias de Axes .

Para invocar el constructor GridSpec, queremos importarlo junto con la instancia de PyPlot:

1
2
3
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec

Ahora, vamos a crear nuestra Figura y crear los objetos Axes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
df = pd.read_csv('iris.csv')

fig = plt.figure()
gs = GridSpec(4, 4)

ax_scatter = fig.add_subplot(gs[1:4, 0:3])
ax_hist_y = fig.add_subplot(gs[0,0:3])
ax_hist_x = fig.add_subplot(gs[1:4, 3])

plt.show()

Hemos creado 3 instancias de Axes, agregando subparcelas a la figura, usando nuestra instancia de GridSpec para posicionarlas. Esto da como resultado una ‘Figura’ con 3 instancias de ‘Ejes’ vacíos:

matplotlib gridspec for jointplot

Ahora que tenemos el diseño y el posicionamiento en su lugar, todo lo que tenemos que hacer es trazar los datos en nuestros ‘Ejes’. Actualicemos el script para trazar las funciones SepalLengthCm y SepalWidthCm a través de un diagrama de dispersión, en nuestros ejes ax_scatter, y cada una de estas funciones en los ejes ax_hist_y y ax_hist_x:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec

df = pd.read_csv('iris.csv')

fig = plt.figure()
gs = GridSpec(4, 4)

ax_scatter = fig.add_subplot(gs[1:4, 0:3])
ax_hist_x = fig.add_subplot(gs[0,0:3])
ax_hist_y = fig.add_subplot(gs[1:4, 3])

ax_scatter.scatter(df['SepalLengthCm'], df['SepalWidthCm'])

ax_hist_x.hist(df['SepalLengthCm'])
ax_hist_y.hist(df['SepalWidthCm'], orientation = 'horizontal')

plt.show()

Hemos establecido la orientación de ax_hist_y en horizontal para que se represente horizontalmente, en el lado derecho del gráfico de dispersión, en la misma orientación en la que hemos establecido nuestros ejes, usando GridSpec:

matplotlib gráfico conjunto simple con histograma de una clase

Esto da como resultado un gráfico conjunto de la relación entre las características ‘SepalLengthCm’ y ‘SepalWidthCm’, así como las distribuciones de las características respectivas.

Trace un gráfico conjunto en Matplotlib con histogramas de varias clases

Ahora, otro caso que podríamos querer explorar es la distribución de estas características, con respecto a la ‘Especies’ de la flor, ya que muy posiblemente podría afectar el rango de longitudes y anchos de los sépalos.

Para esto, no usaremos solo un histograma para cada eje, donde cada uno contiene todas las instancias de flores, sino que superpondremos un histograma para cada “Especie” en ambos ejes.

Para hacer esto, primero tendremos que diseccionar el DataFrame que hemos estado usando antes, por la flor Species:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec

df = pd.read_csv('iris.csv')

setosa = df[df['Species']=='Iris-setosa']
virginica = df[df['Species']=='Iris-virginica']
versicolor = df[df['Species']=='Iris-versicolor']
species = df['Species']
colors = {
    'Iris-setosa' : 'tab:blue', 
    'Iris-versicolor' : 'tab:red',
    'Iris-virginica' : 'tab:green'
    }

Aquí, acabamos de filtrar el DataFrame, por la función Species en tres conjuntos de datos separados. Los conjuntos de datos setosa, virginica y versicolor ahora contienen solo sus instancias respectivas.

También querremos colorear cada una de estas instancias con un color diferente, en función de sus ‘Especies’, tanto en el Diagrama de dispersión como en los Histogramas. Para eso, simplemente recortamos una ‘Serie’ de la función ‘Especies’ y creamos un diccionario de ‘colores’, que usaremos para ‘asignar()’ las ‘Especies’ de cada flor a una colorear más adelante.

Ahora, hagamos nuestras instancias de Figura, GridSpec y Axes:

1
2
3
4
5
6
fig = plt.figure()
gs = GridSpec(4, 4)

ax_scatter = fig.add_subplot(gs[1:4, 0:3])
ax_hist_y = fig.add_subplot(gs[0,0:3])
ax_hist_x = fig.add_subplot(gs[1:4, 3])

Finalmente, podemos trazar el diagrama de dispersión y los histogramas, configurando sus colores y orientaciones en consecuencia:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
ax_scatter.scatter(df['SepalLengthCm'], df['SepalWidthCm'], c=species.map(colors))

ax_hist_y.hist(versicolor['SepalLengthCm'], color='tab:red', alpha=0.4)
ax_hist_y.hist(virginica['SepalLengthCm'], color='tab:green', alpha=0.4)
ax_hist_y.hist(setosa['SepalLengthCm'], color='tab:blue', alpha=0.4)

ax_hist_x.hist(versicolor['SepalWidthCm'], orientation = 'horizontal', color='tab:red', alpha=0.4)
ax_hist_x.hist(virginica['SepalWidthCm'], orientation = 'horizontal', color='tab:green', alpha=0.4)
ax_hist_x.hist(setosa['SepalWidthCm'], orientation = 'horizontal', color='tab:blue', alpha=0.4)

plt.show()

La llamada map() da como resultado una Serie de colores:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
0       tab:blue
1       tab:blue
2       tab:blue
3       tab:blue
4       tab:blue
         ...
145    tab:green
146    tab:green
147    tab:green
148    tab:green
149    tab:green

Cuando se proporciona al argumento c de la función scatter(), aplica colores a las instancias en ese orden, coloreando efectivamente cada instancia con un color correspondiente a su especie.

Para los Histogramas, simplemente trazamos tres gráficos, uno para cada “Especie”, con sus respectivos colores. Puede optar por un histograma paso aquí, y modificar el valor alfa para crear distribuciones de aspecto diferente.

Ejecutar este código da como resultado:

matplotlib joint plot with multi-class histogram

Ahora, cada ‘Especie’ tiene su propio color y distribución, trazado por separado de otras flores. Además, están codificados por colores con el gráfico de dispersión, por lo que es un gráfico realmente intuitivo que se puede leer e interpretar fácilmente.

Nota: Si encuentra que los colores superpuestos, como el naranja que forma parte de los histogramas rojo y azul, lo distraen, al establecer histtype en step se eliminarán los colores rellenos:

matplotlib joint plot, step histogram

Conclusión

En esta guía, hemos analizado cómo trazar un Gráfico conjunto en Matplotlib: un gráfico de dispersión con gráficos de distribución (histogramas) que lo acompañan en ambos ejes del gráfico, para explorar la distribución de las variables que constituyen el Diagrama de dispersión en sí mismo.

Aunque esta tarea es más adecuada para bibliotecas como Seaborn, que tienen soporte integrado para gráficos conjuntos, Matplotlib es el motor subyacente que permite a Seaborn realizar estos gráficos sin esfuerzo.

Si está interesado en Visualización de datos y no sabe por dónde empezar, asegúrese de consultar nuestro paquete de libros en [Visualización de datos en Python](https://gum.co/data-visualization -en-paquete-de-libros-de-python):

Visualización de datos en Python Vuélvase peligroso con la visualización de datos ✅ Garantía de devolución de dinero de 30 días sin preguntas ✅ Principiante a Avanzado ✅ Actualizado periódicamente de forma gratuita (última actualización en abril de 2021) ✅ Actualizado con recursos y guías adicionales

Visualización de datos en Python con Matplotlib y Pandas es un libro diseñado para llevar a los principiantes absolutos a Pandas y Matplotlib, con conocimientos básicos de Python, y permitirles construir una base sólida para el trabajo avanzado con estas bibliotecas, desde gráficos simples. a gráficos 3D animados con botones interactivos.

Sirve como una guía detallada que le enseñará todo lo que necesita saber sobre Pandas y Matplotlib, incluido cómo construir tipos de gráficos que no están integrados en la propia biblioteca.

Visualización de datos en Python, un libro para desarrolladores principiantes e intermedios de Python, lo guía a través de la manipulación de datos simple con Pandas, cubre bibliotecas de trazado centrales como Matplotlib y Seaborn, y le muestra cómo aprovechar las bibliotecas declarativas y experimentales. como Altair. Más específicamente, a lo largo de 11 capítulos, este libro cubre 9 bibliotecas de Python: Pandas, Matplotlib, Seaborn, Bokeh, Altair, Plotly, GGPlot, GeoPandas y VisPy.

Sirve como una guía práctica única para la visualización de datos, en una plétora de herramientas que podría usar en su carrera.