Creación de gráficos con eje roto en Python

MatplotlibMatplotlibBeginner
Practicar Ahora

This tutorial is from open-source community. Access the source code

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

La visualización de datos a menudo presenta desafíos cuando se trata de valores atípicos (outliers). Estos valores extremos pueden comprimir la mayoría de los puntos de datos, lo que dificulta la observación de patrones o detalles importantes. Un gráfico con eje roto ofrece una solución elegante al "romper" el eje para mostrar diferentes rangos de valores, lo que te permite centrarte tanto en la distribución principal de los datos como en los valores atípicos al mismo tiempo.

En este tutorial, aprenderemos cómo crear un gráfico con eje roto utilizando Matplotlib en Python. Esta técnica es especialmente útil cuando se visualizan conjuntos de datos con diferencias significativas en los valores, lo que permite una representación más clara tanto de los datos normales como de los valores extremos.

Consejos para la MV

Después de que la máquina virtual (VM) haya terminado de iniciarse, haz clic en la esquina superior izquierda para cambiar a la pestaña Notebook y acceder a Jupyter Notebook para practicar.

click-notebook

Es posible que debas esperar unos segundos para que Jupyter Notebook termine de cargarse. Debido a las limitaciones de Jupyter Notebook, la validación de las operaciones no se puede automatizar.

Si encuentras algún problema durante este laboratorio, no dudes en pedir ayuda a Labby. Por favor, brinda comentarios después de la sesión para que podamos abordar rápidamente cualquier problema que hayas experimentado.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL matplotlib(("Matplotlib")) -.-> matplotlib/BasicConceptsGroup(["Basic Concepts"]) matplotlib(("Matplotlib")) -.-> matplotlib/AdvancedPlottingGroup(["Advanced Plotting"]) matplotlib(("Matplotlib")) -.-> matplotlib/PlotCustomizationGroup(["Plot Customization"]) matplotlib/BasicConceptsGroup -.-> matplotlib/importing_matplotlib("Importing Matplotlib") matplotlib/BasicConceptsGroup -.-> matplotlib/figures_axes("Understanding Figures and Axes") matplotlib/AdvancedPlottingGroup -.-> matplotlib/subplots("Subplots") matplotlib/PlotCustomizationGroup -.-> matplotlib/titles_labels("Adding Titles and Labels") matplotlib/PlotCustomizationGroup -.-> matplotlib/axis_ticks("Axis Ticks Customization") matplotlib/PlotCustomizationGroup -.-> matplotlib/grid_config("Grid Configuration") subgraph Lab Skills matplotlib/importing_matplotlib -.-> lab-48592{{"Creación de gráficos con eje roto en Python"}} matplotlib/figures_axes -.-> lab-48592{{"Creación de gráficos con eje roto en Python"}} matplotlib/subplots -.-> lab-48592{{"Creación de gráficos con eje roto en Python"}} matplotlib/titles_labels -.-> lab-48592{{"Creación de gráficos con eje roto en Python"}} matplotlib/axis_ticks -.-> lab-48592{{"Creación de gráficos con eje roto en Python"}} matplotlib/grid_config -.-> lab-48592{{"Creación de gráficos con eje roto en Python"}} end

Preparando el entorno y creando datos

En este primer paso, configuraremos nuestro entorno de trabajo importando las bibliotecas necesarias y creando datos de muestra para nuestra visualización. Nos centraremos en generar datos que incluyan algunos valores atípicos (outliers), lo que demostrará el valor de utilizar un gráfico con eje roto.

Importar las bibliotecas requeridas

Comencemos importando las bibliotecas que necesitamos para este tutorial. Utilizaremos Matplotlib para crear nuestras visualizaciones y NumPy para generar y manipular datos numéricos.

Crea una nueva celda en tu Jupyter Notebook y escribe el siguiente código:

import matplotlib.pyplot as plt
import numpy as np

print(f"NumPy version: {np.__version__}")

Cuando ejecutes esta celda, deberías ver una salida similar a esta:

NumPy version: 2.0.0
numpy-version

Los números exactos de la versión pueden variar dependiendo de tu entorno, pero esto confirma que las bibliotecas están instaladas correctamente y listas para usar.

Generar datos de muestra con valores atípicos

Ahora, creemos un conjunto de datos de muestra que incluya algunos valores atípicos. Generaremos números aleatorios y luego agregaremos deliberadamente valores más grandes en ciertas posiciones para crear nuestros valores atípicos.

Crea una nueva celda y agrega el siguiente código:

## Establece una semilla aleatoria para reproducibilidad
np.random.seed(19680801)

## Genera 30 puntos aleatorios con valores entre 0 y 0.2
pts = np.random.rand(30) * 0.2

## Agrega 0.8 a dos puntos específicos para crear valores atípicos
pts[[3, 14]] += 0.8

## Muestra los primeros puntos de datos para entender nuestro conjunto de datos
print("First 10 data points:")
print(pts[:10])
print("\nData points containing outliers:")
print(pts[[3, 14]])

Cuando ejecutes esta celda, deberías ver una salida similar a:

First 10 data points:
[0.01182225 0.11765474 0.07404329 0.91088185 0.10502995 0.11190702
 0.14047499 0.01060192 0.15226977 0.06145634]

Data points containing outliers:
[0.91088185 0.97360754]

En esta salida, puedes ver claramente que los valores en los índices 3 y 14 son mucho más grandes que los otros valores. Estos son nuestros valores atípicos. La mayoría de nuestros puntos de datos están por debajo de 0.2, pero estos dos valores atípicos están por encima de 0.9, creando una disparidad significativa en nuestro conjunto de datos.

Este tipo de distribución de datos es perfecto para demostrar la utilidad de un gráfico con eje roto. En el siguiente paso, crearemos la estructura del gráfico y lo configuraremos para mostrar adecuadamente tanto los datos principales como los valores atípicos.

Creando y configurando el gráfico con eje roto

En este paso, crearemos la estructura real del gráfico con eje roto. Un gráfico con eje roto consiste en múltiples subgráficos que muestran diferentes rangos de los mismos datos. Configuraremos estos subgráficos para mostrar eficazmente nuestros datos principales y valores atípicos (outliers).

Crear los subgráficos

Primero, necesitamos crear dos subgráficos dispuestos verticalmente. El subgráfico superior mostrará nuestros valores atípicos, mientras que el subgráfico inferior mostrará la mayoría de nuestros puntos de datos.

Crea una nueva celda en tu cuaderno (notebook) y agrega el siguiente código:

## Crea dos subgráficos apilados verticalmente con eje x compartido
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True, figsize=(8, 6))

## Agrega un título principal a la figura
fig.suptitle('Broken Axis Plot Example', fontsize=16)

## Grafica los mismos datos en ambos ejes
ax1.plot(pts, 'o-', color='blue')
ax2.plot(pts, 'o-', color='blue')

## Muestra la figura para ver ambos subgráficos
plt.tight_layout()
plt.show()
broken-axis-plot

Cuando ejecutes esta celda, deberías ver una figura con dos subgráficos, ambos mostrando los mismos datos. Observa cómo los valores atípicos comprimen el resto de los datos en ambos gráficos, lo que dificulta ver los detalles de la mayoría de los puntos de datos. Este es exactamente el problema que intentamos resolver con un gráfico con eje roto.

Configurar los límites del eje Y

Ahora necesitamos configurar cada subgráfico para centrarse en un rango específico de valores en el eje y. El subgráfico superior se centrará en el rango de valores atípicos, mientras que el subgráfico inferior se centrará en el rango de los datos principales.

Crea una nueva celda y agrega el siguiente código:

## Crea dos subgráficos apilados verticalmente con eje x compartido
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True, figsize=(8, 6))

## Grafica los mismos datos en ambos ejes
ax1.plot(pts, 'o-', color='blue')
ax2.plot(pts, 'o-', color='blue')

## Establece los límites del eje y para cada subgráfico
ax1.set_ylim(0.78, 1.0)    ## El subgráfico superior muestra solo los valores atípicos
ax2.set_ylim(0, 0.22)      ## El subgráfico inferior muestra solo los datos principales

## Agrega un título a cada subgráfico
ax1.set_title('Outlier Region')
ax2.set_title('Main Data Region')

## Muestra la figura con los límites del eje y ajustados
plt.tight_layout()
plt.show()

Cuando ejecutes esta celda, deberías ver que cada subgráfico ahora se centra en un rango diferente de valores en el eje y. El gráfico superior muestra solo los valores atípicos, y el gráfico inferior muestra solo los datos principales. Esto ya mejora la visualización, pero para convertirlo en un gráfico con eje roto adecuado, necesitamos agregar algunas configuraciones más.

Ocultar las líneas de los ejes (spines) y ajustar las marcas (ticks)

Para crear la ilusión de un eje "roto", necesitamos ocultar las líneas de los ejes que conectan los dos subgráficos y ajustar la posición de las marcas.

Crea una nueva celda y agrega el siguiente código:

## Crea dos subgráficos apilados verticalmente con eje x compartido
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True, figsize=(8, 6))

## Grafica los mismos datos en ambos ejes
ax1.plot(pts, 'o-', color='blue')
ax2.plot(pts, 'o-', color='blue')

## Establece los límites del eje y para cada subgráfico
ax1.set_ylim(0.78, 1.0)    ## El subgráfico superior muestra solo los valores atípicos
ax2.set_ylim(0, 0.22)      ## El subgráfico inferior muestra solo los datos principales

## Oculta las líneas de los ejes entre ax1 y ax2
ax1.spines.bottom.set_visible(False)
ax2.spines.top.set_visible(False)

## Ajusta la posición de las marcas
ax1.xaxis.tick_top()          ## Mueve las marcas del eje x hacia la parte superior
ax1.tick_params(labeltop=False)  ## Oculta las etiquetas de las marcas del eje x en la parte superior
ax2.xaxis.tick_bottom()       ## Mantiene las marcas del eje x en la parte inferior

## Agrega etiquetas al gráfico
ax2.set_xlabel('Data Point Index')
ax2.set_ylabel('Value')
ax1.set_ylabel('Value')

plt.tight_layout()
plt.show()

Cuando ejecutes esta celda, deberías ver que el gráfico ahora tiene las líneas de los ejes ocultas entre los dos subgráficos, lo que crea una apariencia más limpia. Las marcas del eje x ahora están posicionadas correctamente, con etiquetas solo en la parte inferior.

En este punto, hemos creado con éxito un gráfico con eje roto básico. En el siguiente paso, agregaremos toques finales para que quede claro para los espectadores que el eje está roto.

Añadiendo toques finales al gráfico con eje roto

En este último paso, añadiremos toques finales a nuestro gráfico con eje roto para dejar claro que el eje y está roto. Añadiremos líneas diagonales entre los subgráficos para indicar la ruptura y mejoraremos la apariencia general del gráfico con etiquetas adecuadas y una cuadrícula.

Añadir líneas diagonales de ruptura

Para indicar visualmente que el eje está roto, añadiremos líneas diagonales entre los dos subgráficos. Esta es una convención común que ayuda a los espectadores a entender que se ha omitido una parte del eje.

Crea una nueva celda y añade el siguiente código:

## Crea dos subgráficos apilados verticalmente con eje x compartido
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True, figsize=(8, 6))

## Grafica los mismos datos en ambos ejes
ax1.plot(pts, 'o-', color='blue')
ax2.plot(pts, 'o-', color='blue')

## Establece los límites del eje y para cada subgráfico
ax1.set_ylim(0.78, 1.0)    ## El subgráfico superior muestra solo los valores atípicos
ax2.set_ylim(0, 0.22)      ## El subgráfico inferior muestra solo los datos principales

## Oculta las líneas de los ejes entre ax1 y ax2
ax1.spines.bottom.set_visible(False)
ax2.spines.top.set_visible(False)

## Ajusta la posición de las marcas
ax1.xaxis.tick_top()          ## Mueve las marcas del eje x hacia la parte superior
ax1.tick_params(labeltop=False)  ## Oculta las etiquetas de las marcas del eje x en la parte superior
ax2.xaxis.tick_bottom()       ## Mantiene las marcas del eje x en la parte inferior

## Añade líneas diagonales de ruptura
d = 0.5  ## proporción de la extensión vertical a horizontal de la línea inclinada
kwargs = dict(marker=[(-1, -d), (1, d)], markersize=12,
              linestyle='none', color='k', mec='k', mew=1, clip_on=False)
ax1.plot([0, 1], [0, 0], transform=ax1.transAxes, **kwargs)
ax2.plot([0, 1], [1, 1], transform=ax2.transAxes, **kwargs)

## Añade etiquetas y un título
ax2.set_xlabel('Data Point Index')
ax2.set_ylabel('Value')
ax1.set_ylabel('Value')
fig.suptitle('Dataset with Outliers', fontsize=16)

## Añade una cuadrícula a ambos subgráficos para mayor legibilidad
ax1.grid(True, linestyle='--', alpha=0.7)
ax2.grid(True, linestyle='--', alpha=0.7)

plt.tight_layout()
plt.subplots_adjust(hspace=0.1)  ## Ajusta el espacio entre subgráficos
plt.show()

Cuando ejecutes esta celda, deberías ver el gráfico con eje roto completo con líneas diagonales que indican la ruptura en el eje y. El gráfico ahora tiene un título, etiquetas de ejes y líneas de cuadrícula para mejorar la legibilidad.

Entendiendo el gráfico con eje roto

Tomemos un momento para entender los componentes clave de nuestro gráfico con eje roto:

  1. Dos subgráficos: Creamos dos subgráficos separados, cada uno centrado en un rango diferente de valores en el eje y.
  2. Líneas de los ejes ocultas: Ocultamos las líneas de los ejes que conectan los subgráficos para crear una separación visual.
  3. Líneas diagonales de ruptura: Añadimos líneas diagonales para indicar que el eje está roto.
  4. Límites del eje y: Establecimos diferentes límites para el eje y en cada subgráfico para centrarnos en partes específicas de los datos.
  5. Líneas de cuadrícula: Añadimos líneas de cuadrícula para mejorar la legibilidad y facilitar la estimación de valores.

Esta técnica es especialmente útil cuando tienes valores atípicos en tus datos que de otro modo comprimirían la visualización de la mayoría de tus puntos de datos. Al "romper" el eje, puedes mostrar tanto los valores atípicos como la distribución principal de los datos de manera clara en una sola figura.

Experimentar con el gráfico

Ahora que entiendes cómo crear un gráfico con eje roto, puedes experimentar con diferentes configuraciones. Intenta cambiar los límites del eje y, añadir más características al gráfico o aplicar esta técnica a tus propios datos.

Por ejemplo, puedes modificar el código anterior para incluir una leyenda, cambiar el esquema de colores o ajustar los estilos de los marcadores:

## Crea dos subgráficos apilados verticalmente con eje x compartido
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True, figsize=(8, 6))

## Grafica los mismos datos en ambos ejes con diferentes estilos
ax1.plot(pts, 'o-', color='darkblue', label='Data Points', linewidth=2)
ax2.plot(pts, 'o-', color='darkblue', linewidth=2)

## Marca los valores atípicos con un color diferente
outlier_indices = [3, 14]
ax1.plot(outlier_indices, pts[outlier_indices], 'ro', markersize=8, label='Outliers')

## Establece los límites del eje y para cada subgráfico
ax1.set_ylim(0.78, 1.0)    ## El subgráfico superior muestra solo los valores atípicos
ax2.set_ylim(0, 0.22)      ## El subgráfico inferior muestra solo los datos principales

## Oculta las líneas de los ejes entre ax1 y ax2
ax1.spines.bottom.set_visible(False)
ax2.spines.top.set_visible(False)

## Ajusta la posición de las marcas
ax1.xaxis.tick_top()          ## Mueve las marcas del eje x hacia la parte superior
ax1.tick_params(labeltop=False)  ## Oculta las etiquetas de las marcas del eje x en la parte superior
ax2.xaxis.tick_bottom()       ## Mantiene las marcas del eje x en la parte inferior

## Añade líneas diagonales de ruptura
d = 0.5  ## proporción de la extensión vertical a horizontal de la línea inclinada
kwargs = dict(marker=[(-1, -d), (1, d)], markersize=12,
              linestyle='none', color='k', mec='k', mew=1, clip_on=False)
ax1.plot([0, 1], [0, 0], transform=ax1.transAxes, **kwargs)
ax2.plot([0, 1], [1, 1], transform=ax2.transAxes, **kwargs)

## Añade etiquetas y un título
ax2.set_xlabel('Data Point Index')
ax2.set_ylabel('Value')
ax1.set_ylabel('Value')
fig.suptitle('Dataset with Outliers - Enhanced Visualization', fontsize=16)

## Añade una cuadrícula a ambos subgráficos para mayor legibilidad
ax1.grid(True, linestyle='--', alpha=0.7)
ax2.grid(True, linestyle='--', alpha=0.7)

## Añade una leyenda al subgráfico
ax1.legend(loc='upper right')

plt.tight_layout()
plt.subplots_adjust(hspace=0.1)  ## Ajusta el espacio entre subgráficos
plt.show()

Cuando ejecutes este código mejorado, deberías ver una visualización mejorada con los valores atípicos marcados y una leyenda que explica los puntos de datos.

¡Felicidades! Has creado con éxito un gráfico con eje roto en Python utilizando Matplotlib. Esta técnica te ayudará a crear visualizaciones más efectivas cuando trabajes con datos que contengan valores atípicos.

Resumen

En este tutorial, has aprendido cómo crear un gráfico con eje roto utilizando Matplotlib en Python. Esta técnica de visualización es valiosa cuando se trabaja con datos que contienen valores atípicos (outliers), ya que te permite mostrar tanto la distribución principal de los datos como los valores atípicos de manera clara en una sola figura.

A continuación, un resumen de lo que has logrado:

  1. Configuración del entorno y creación de datos: Has importado las bibliotecas necesarias y creado datos de muestra que contienen valores atípicos para demostrar el concepto.

  2. Creación de la estructura básica del gráfico: Has creado dos subgráficos con diferentes límites en el eje y para centrarte en diferentes rangos de valores y has configurado la apariencia de los ejes.

  3. Mejora de la visualización: Has añadido líneas diagonales de ruptura para indicar el eje roto, mejorado la apariencia del gráfico con etiquetas y una cuadrícula, y has aprendido cómo personalizar aún más la visualización.

La técnica del eje roto resuelve un problema común de visualización de datos al permitir a los espectadores ver tanto la estructura general como los detalles de un conjunto de datos simultáneamente, incluso cuando los valores atípicos normalmente comprimirían la visualización de la mayoría de los puntos de datos.

Puedes aplicar esta técnica a tus propias tareas de análisis y visualización de datos siempre que necesites representar datos con rangos de valores significativamente diferentes de manera clara y efectiva.