Saltar al contenido

# manejo-de-datos-en-pandas

Manejo de datos en Pandas

Volver a la portada del curso
Lectura (Markdown)

Visualización de datos con Pandas

Sección 5 · Análisis de datos

Visualización de datos con Pandas

Una tabla de cinco filas se lee bien; una de doce meses o veinticinco combinaciones de categoría y ciudad, no tanto. Toda Series y todo DataFrame de pandas tienen un método .plot que dibuja el resultado en una línea, con Matplotlib por debajo. Esta lectura muestra los tipos de gráfica que ofrece, cómo se combinan con groupby y cuándo conviene pasar a Matplotlib directamente. Los ejemplos usan los pedidos limpios de PyShop y están completos en el notebook agrupar-y-graficar.

1. Cómo piensa .plot

En una Series, el índice va en un eje y los valores en el otro. El resultado de groupby(...)[col].sum() es justamente una Series con los grupos como índice, así que está listo para graficarse. En un DataFrame, cada columna se dibuja como una serie distinta, con su leyenda. El argumento kind elige el tipo:

kindRespondeEjemplo en PyShop
line¿cómo cambia en el tiempo?ingreso por mes
bar / barh¿quién tiene más?ingreso por categoría
hist¿cómo se reparten los valores?total por pedido
box¿cómo se compara la distribución entre grupos?total por categoría
pie¿qué parte del todo es cada grupo?pedidos por estado
scatter¿se relacionan dos variables?pedidos vs. ticket medio por ciudad

También existe la forma con punto: s.plot.barh() equivale a s.plot(kind="barh").

2. Ranking: barras horizontales

Sin cancelados, el ingreso por categoría va de 797,092 MXN (Electrónica) a 66,555 (Libros). Las barras horizontales dejan leer nombres largos sin girarlos. Un detalle: barh dibuja la primera fila abajo, así que para que la mayor quede arriba se ordena de menor a mayor.

import matplotlib.pyplot as plt

val = pedidos[pedidos["estado"] != "cancelado"]
por_cat = val.groupby("categoria")["total"].sum()

fig, ax = plt.subplots(figsize=(7, 3.5))
por_cat.sort_values().plot(kind="barh", ax=ax)
ax.set_title("Ingreso por categoría (sin cancelados)")
ax.set_xlabel("MXN")

.plot devuelve el Axes de Matplotlib (aquí se pasa con ax=), y sobre él se ponen título y etiquetas con set_title, set_xlabel y set_ylabel.

3. Tendencia: línea por mes

Con la fecha ya convertida a datetime64, .dt.month sirve como clave de agrupación y el resultado tiene 12 puntos:

por_mes = val.groupby(val["fecha"].dt.month)["total"].sum()
ax = por_mes.plot(kind="line", marker="o")
ax.set_ylim(0, None)

El ingreso mensual va de 71,553 MXN en mayo a 148,298 en febrero. Estos datos son sintéticos y no modelan estacionalidad: la gráfica muestra variación, no una temporada. Una gráfica no explica por qué sube o baja una línea; si no hay una causa en los datos, no la inventes. set_ylim(0, None) fija el piso en cero para que la variación no parezca mayor de lo que es.

4. Varias series: un DataFrame

Una pivot_table de categoría × ciudad es un DataFrame de 5 × 5. Al graficarlo con kind="bar", cada fila es un grupo de barras y cada columna una ciudad con su color y su entrada en la leyenda (25 barras). rot=0 deja horizontales los nombres del eje x.

tabla = val.pivot_table(index="categoria", columns="ciudad",
                        values="total", aggfunc="sum")
tabla.plot(kind="bar", rot=0, figsize=(9, 4))

5. Distribuciones y composición

  • val["total"].plot(kind="hist", bins=20) reparte los totales en 20 intervalos. La mitad de los pedidos no pasa de 899 MXN y unos pocos, con varios monitores, llegan a 13,196.
  • val.plot(kind="box", column="total", by="categoria") dibuja una caja por categoría: mediana, cuartiles y valores extremos.
  • pedidos["estado"].value_counts().plot(kind="pie", autopct="%1.1f%%") da 4 cuñas con su porcentaje. El pastel sirve con pocas categorías; con más de cinco, las barras se leen mejor.
  • scatter necesita un DataFrame y los nombres de dos columnas: por_ciudad.plot(kind="scatter", x="pedidos", y="ticket").

6. Varias gráficas en una figura con ax=

plt.subplots(1, 2) crea una figura con dos paneles, y ax=axs[0] indica dónde dibujar cada gráfica. Sin ax=, una Series dibuja sobre los ejes activos: dos .plot seguidos en la misma celda quedan encimados. fig.tight_layout() evita que los títulos se monten.

fig, axs = plt.subplots(1, 2, figsize=(11, 4))
por_cat.sort_values().plot(kind="barh", ax=axs[0])
por_mes.plot(kind="line", marker="o", ax=axs[1])
fig.tight_layout()

Trampas comunes

  • Graficar datos sin limpiar. Con las ciudades crudas, un barh tendría 16 barras para cinco ciudades.
  • Olvidar ordenar. Un ranking sin sort_values obliga a buscar la barra mayor.
  • Sumar donde se debe promediar. Para comparar ciudades de distinto tamaño, el ticket medio dice más que el ingreso total.
  • Pastel con muchas cuñas. Más de cinco partes se vuelven ilegibles.
  • Leer causas en la forma. Una línea que sube no prueba nada por sí sola.

Cuándo pasar a Matplotlib

.plot resuelve la exploración: ver rápido qué dicen los resultados de un groupby. Para un gráfico de presentación (formatos de montos, anotaciones, colores de resalte, tableros de varios paneles) se trabaja sobre el Axes con Matplotlib; el curso de Matplotlib de PyPro lo cubre a fondo. La regla práctica: agrupa con pandas, grafica con .plot y pule con Matplotlib solo lo que vas a mostrar.

Recursos