from plotnine import (
ggplot, aes, geom_text, geom_point, geom_segment, annotate,
lims, scale_y_reverse, theme_void, theme
)
# --- Filtrar y agrupar ---
df = df[df['PACC_ANIO'].isin([2015, 2025])].dropna(subset=['PACC_PRECIO_USD'])
df_group = (
df.groupby(["PACC_ANIO", "DPA_PROVINCIA"], as_index=False)["PACC_PRECIO_USD"]
.mean()
.round(2)
)
# --- Eliminar provincias que no tienen ambos años ---
valid_provincias = (
df_group.groupby("DPA_PROVINCIA")["PACC_ANIO"]
.nunique()
.reset_index()
)
valid_provincias = valid_provincias[valid_provincias["PACC_ANIO"] == 2]["DPA_PROVINCIA"]
df_group = df_group[df_group["DPA_PROVINCIA"].isin(valid_provincias)]
# --- Calcular ranking por año ---
df_group['Rank'] = df_group.groupby("PACC_ANIO")["PACC_PRECIO_USD"].rank(
method="first", ascending=False
)
# --- Pivotear a formato wide ---
df_wide = df_group.pivot(
index="DPA_PROVINCIA",
columns="PACC_ANIO",
values="Rank"
).reset_index()
# Renombrar columnas
df_wide = df_wide.rename(columns={2015: "rank2015", 2025: "rank2025"})
# Colores para etiquetas
black1 = "#252525"
black2 = "#222222"
# --- Gráfico slopegraph ---
plot = (
ggplot(df_wide)
# Etiquetas izquierda (2015)
+ geom_text(
aes(x=1, y="rank2015", label="DPA_PROVINCIA", color="DPA_PROVINCIA"),
nudge_x=-0.05,
ha="right",
size=8,
)
# Etiquetas derecha (2025)
+ geom_text(
aes(x=2, y="rank2025", label="DPA_PROVINCIA", color="DPA_PROVINCIA"),
nudge_x=0.05,
ha="left",
size=8,
)
# Puntos en 2015
+ geom_point(aes(x=1, y="rank2015", color="DPA_PROVINCIA"), size=2.5, alpha=0.8)
# Puntos en 2025
+ geom_point(aes(x=2, y="rank2025", color="DPA_PROVINCIA"), size=2.5, alpha=0.8)
# Segmentos que conectan
+ geom_segment(
aes(x=1, y="rank2015", xend=2, yend="rank2025", color="DPA_PROVINCIA"),
alpha=0.7
)
# Títulos de columnas
+ annotate(
"text", x=1, y=0, label="2015",
fontweight="bold", ha="right", size=10, color=black2
)
+ annotate(
"text", x=2, y=0, label="2025",
fontweight="bold", ha="left", size=10, color=black2
)
# Margen horizontal
+ lims(x=(0.35, 2.65))
# Invertir ranking (mejor arriba)
+ scale_y_reverse()
# Quitar decoraciones
+ theme_void()
# Ajustes finales
+ theme(figure_size=(8, 11), legend_position="none")
+ labs(title=" Ranking porvincias del Ecuadro del precio del Cacao")
)
# Mostrar gráfico en notebook
plot.draw()