import pandas as pd
import plotly.express as px
import plotly.io as pio
import numpy as np
pio.renderers.default = "notebook"Un gráfico de violín es una técnica de visualización de datos que combina elementos de un boxplot (o gráfico de caja y bigotes) con la representación de la densidad de probabilidad de los datos.
Mientras que el boxplot resume una distribución en cuartiles, mediana y valores extremos, el gráfico de violín añade la forma de la distribución mediante un estimador de densidad kernel, lo que permite observar si los datos presentan asimetrías, picos múltiples (modas) o distribuciones inusuales.
0.1 Descripción
- La anchura del “violín” en cada altura refleja la densidad de probabilidad de los datos en ese rango de valores.
- Incluye un boxplot interno que marca la mediana y los cuartiles.
- Puede mostrar también todos los puntos de datos individuales, si la muestra no es demasiado grande.
- Al colocar varios violines lado a lado, es posible comparar cómo cambia la distribución entre grupos o categorías.
0.2 Utilidad
- Permite visualizar la forma completa de la distribución en lugar de limitarse a medidas de resumen.
- Facilita la detección de asimetrías, concentraciones de datos y distribuciones multimodales.
- Es especialmente útil en grandes conjuntos de datos, donde graficar todas las observaciones es inviable.
- Combina la capacidad de síntesis del boxplot con la riqueza visual de un histograma suavizado.
0.3 Errores Comunes
- Pocos grupos: si solo se comparan dos o tres categorías, puede ser más adecuado un gráfico tipo ridgeline.
- Tamaños de muestra muy diferentes: conviene señalarlo explícitamente para evitar malas interpretaciones.
- No ordenar los violines por la mediana u otro criterio relevante puede dificultar la comparación entre categorías.
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
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
# Opción A — Un solo violín
fig = px.violin(
df,
y="PACC_PRECIO_USD", # la variable numérica va en 'y'
box=True, # muestra boxplot interno (mediana y cuartiles)
points="all", # muestra puntos individuales (opcional)
title="Violin Plot de Precio USD Cacao",
labels={"PACC_PRECIO_USD": "Precio en USD Cacao"}
)
fig.show()import plotly.express as px
# Opción A — Un solo violín
fig = px.violin(
df,
y="PACC_PRECIO_USD",
box=True,
title="Violin Plot de Precio USD Cacao",
labels={"PACC_PRECIO_USD": "Precio en USD Cacao"}
)
fig.show()3 Iteración 2
import plotly.express as px
fig = px.violin(
df,
x="PACC_ANIO", # agrupa por año
y="PACC_PRECIO_USD", # valores numéricos
box=True, # muestra boxplot interno
points="outliers", # solo muestra outliers
title="Violin Plot 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 puntos (outliers)
fig.update_traces(
marker=dict(
color="red", # color para los puntos (outliers)
line=dict(color="red", width=2)
)
)
fig.show()4 Iteracion 3
import plotly.express as px
fig = px.violin(
df,
x="PACC_ANIO", # agrupa por año
y="PACC_PRECIO_USD", # valores numéricos
box=True, # incluye boxplot interno
points="outliers", # muestra solo outliers
title="Violin Plot 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 y ejes
fig.update_layout(
plot_bgcolor="white",
paper_bgcolor="white",
xaxis=dict(
tickmode="linear", # ticks regulares en eje X
tickangle=0, # etiquetas horizontales
showgrid=True,
gridcolor="lightgray"
),
yaxis=dict(
tickformat=",.0f" # separador de miles en eje Y
)
)
# Cambiar color de outliers
fig.update_traces(
marker=dict(
color="saddlebrown", # puntos de outliers en café
line=dict(color="saddlebrown", width=2)
)
)
fig.show()