Diagrama de Caja y Bigotes

Python
code
Visualization
Author

Marco Aguirre

Published

September 15, 2025

El boxplot (o diagrama de caja y bigotes) es un método estandarizado para representar gráficamente una serie de datos numéricos a través de sus cuartiles. Este gráfico resume la distribución de los datos y permite identificar de manera rápida características esenciales de la variable estudiada.

0.1 Descripción

  • La línea central dentro de la caja representa la mediana.
  • Los extremos de la caja corresponden al primer cuartil (Q1) y al tercer cuartil (Q3).
  • Los llamados “bigotes” representan los valores máximo y mínimo, excluyendo los valores atípicos (outliers).
  • Los valores atípicos, cuando existen, se representan como puntos individuales fuera de los bigotes.

Ejemplo de Boxplot

0.2 Utilidad

  • Proporcionan una visión general de la simetría de la distribución de los datos. Si la mediana no está centrada en la caja, la distribución es asimétrica.
  • Son útiles para detectar la presencia de valores atípicos.
  • Forman parte de las herramientas de la estadística descriptiva, mostrando cómo se dispersan los datos con relación a la mediana, los percentiles 25 y 75, y los valores extremos.
  • Permiten condensar en una sola dimensión la información de un histograma, facilitando el análisis al evidenciar que el 50 % de los datos se concentra dentro de los límites de la caja.
  • Aunque los resultados suelen expresarse en términos de cuartiles, en la práctica se utilizan las bisagras de Tukey para la construcción del gráfico. En muestras grandes, ambos métodos producen resultados muy similares.

0.3 Errores comunes al interpretar un Boxplot

  1. El gráfico no muestra explícitamente el tamaño de la muestra; por lo tanto, puede ser útil complementarlo con anotaciones o variando el ancho de las cajas.
  2. El boxplot oculta la forma exacta de la distribución. Para conjuntos pequeños de datos puede complementarse con puntos dispersos (jitter), y en casos generales, con un gráfico tipo violin que muestre la densidad de los valores.
  3. No ordenar los boxplots por mediana al comparar varios grupos puede dificultar la interpretación de patrones.

1 Dataset: Precios Agroindustria de Cacao (2012 - 2025)

Archivo: MAG_PreciosAgroindustriaCacao_2025Junio.csv
Fuente: Ministerio de Agricultura y Ganadería (MAG), Ecuador
Última actualización: Junio 2025

import pandas as pd
import plotly.express as px
import plotly.io as pio
import numpy as np
pio.renderers.default = "notebook"
import pandas as pd
df = pd.read_csv("mag_preciosagroindustriacacao_2025junio.csv", sep=";")
print(df.head())
print(df.info())
   PACC_ANIO PACC_MES DPA_PROVINCIA DPA_CANTON        PACC_PRODUCTO  \
0       2012    Enero        El Oro  Arenillas  Cacao seco mezclado   
1       2012    Enero        El Oro  Arenillas  Cacao seco mezclado   
2       2012    Enero        El Oro   El Guabo  Cacao seco mezclado   
3       2012    Enero        El Oro   El Guabo  Cacao seco mezclado   
4       2012    Enero        El Oro    Machala  Cacao seco mezclado   

          PACC_PRESENTACION PACC_TIPO  PACC_PRECIO_USD  PACC_USD_KG  
0  Quintal de 100,00 libras    Compra            71.41         1.57  
1  Quintal de 100,00 libras     Venta            74.06         1.63  
2  Quintal de 100,00 libras    Compra            73.75         1.63  
3  Quintal de 100,00 libras     Venta            84.00         1.85  
4  Quintal de 100,00 libras    Compra            75.00         1.65  
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 26246 entries, 0 to 26245
Data columns (total 9 columns):
 #   Column             Non-Null Count  Dtype  
---  ------             --------------  -----  
 0   PACC_ANIO          26246 non-null  int64  
 1   PACC_MES           26246 non-null  object 
 2   DPA_PROVINCIA      26246 non-null  object 
 3   DPA_CANTON         26246 non-null  object 
 4   PACC_PRODUCTO      26246 non-null  object 
 5   PACC_PRESENTACION  26246 non-null  object 
 6   PACC_TIPO          26246 non-null  object 
 7   PACC_PRECIO_USD    26246 non-null  float64
 8   PACC_USD_KG        26246 non-null  float64
dtypes: float64(2), int64(1), object(6)
memory usage: 1.8+ MB
None

2 Iteración 1

import plotly.express as px

fig = px.box(
    df,
    x="PACC_PRECIO_USD",
    title="Boxplot de Precio USD Cacao",
    labels={"PACC_PRECIO_USD": "Precio en USD Cacao"},
    #points="all"  
)

fig.show()

3 Iteración 2

import plotly.express as px

fig = px.box(
    df,
    x="PACC_ANIO",             # agrupa por año
    y="PACC_PRECIO_USD",       # valores numéricos
    title="Boxplot de Precio USD Cacao por Año",
    labels={
        "PACC_ANIO": "Año",
        "PACC_PRECIO_USD": "Precio en USD Cacao"
    },
)

# Fondo blanco
fig.update_layout(
    plot_bgcolor="white",
    paper_bgcolor="white"
)

# Cambiar color de outliers
fig.update_traces(
    marker=dict(
        outliercolor="red",  # color para outliers
        line=dict(outliercolor="red", outlierwidth=2)
    ),
    boxpoints="outliers"
)

fig.show()

4 Iteracion 3

import plotly.express as px

fig = px.box(
    df,
    x="PACC_ANIO",             # agrupa por año
    y="PACC_PRECIO_USD",       # valores numéricos
    title="Boxplot de Precio USD Cacao por Año",
    labels={
        "PACC_ANIO": "Año",
        "PACC_PRECIO_USD": "Precio en USD Cacao"
    },
    color_discrete_sequence=["saddlebrown"]  # color café
)

# Fondo blanco
fig.update_layout(
    plot_bgcolor="white",
    paper_bgcolor="white",
    xaxis=dict(
        tickmode="linear",      # ticks regulares en eje X
        tickangle=0,            # mantiene horizontal
        showgrid=True,
        gridcolor="lightgray"
    ),
    yaxis=dict(
        tickformat=",.0f"       # formato con separador de miles
    )
)

# Cambiar color de outliers
fig.update_traces(
    marker=dict(
        outliercolor="saddlebrown",  # color café para outliers
        line=dict(outliercolor="saddlebrown", outlierwidth=2)
    ),
    boxpoints="outliers"
)

fig.show()