Paquetes

  • numpy
  • matplotlib
  • seaborn
  • pandas
import numpy as np
import pandas as pd

¿Qué es la visualización de datos?

Es la representación gráfica de información y datos para consumo humano. Se usa para transformar conceptos abstractos como números, vectores, matrices... en gráficas de las cuales una persona puede observar patrones, tendencias, anomalías... y en generar extraer información sobre el elemento que se está intentando interpretar.

Algunos de los objetivos de la visualización son:

  • Presentar relaciones y estructuras en los datos
  • Resumir grandes cantidades de datos
  • Resolver preguntas específicas

Algunas gráficas

Top 2500 feelings, ↙ Junk Charts, ↗William Playfair, ↘A Tour Through the Visualization Zoo

  • Poco informativas: Poco claras, engañosas, innecesarias
  • Informativas: Concisas, simples, correctass
  • Atractivas: Innovadoras, coloridas, estéticas
  • No Atractivas: Sobrecargadas, aburridas, pobre estructura

⚠️ Nos vamos a enfocar en gráficas de información tabular bidimensionales

Layered Grammar of Graphics

Las gráficas pueden ser expresadas en términos de un "lenguaje gráfico". Este lenguaje nos ayuda no solo especificando cómo convertir datos a imágenes, sino que también ayuda a los lectores a a interpretar y extraer información de las gráficas. Podemos extraer un ejemplo de este lenguaje del libro Layered Grammar of Graphics por Hadley Wickham.

Partes de una gráfica

  • Stat es información estadística obtenida de los datos; esta información es representda visualmente con la intención de resumir los datos. El promedio, y la desviación estandar o un histograma son ejemplos de stats.

  • Mapping es una transformación de datos abstractos a un elemento visual; Toma un atributo de nuestros datos (puede ser inclusive un stat) y lo representa de forma visual usando una scale y guide para dotar de unidades a dicho atributo.

    • Scale especifica la transformación de los datos a valores visuales, por ejemplo, Escala de Richter al tamaño de un circulo en pantalla, o Altura de una persona a tamaño de una barra en la pantalla.

    • Guide especifica una referencia visual que le da sentido al mapping, nos dice cuál es la escala y el atributo que se está tratando de representar. Por ejemplo, las anotaciones en los ejes y las layendas que especifican qué significan los colores en una gráfica.

  • Geom es la representación geométrica de la información después de haber pasado por el mapping. Ejemplos son las líneas y puntos visibles en cada gráfica.

  • Coord es el sistema de coordenadas en el que se presenta la información; coordina cómo es que se muestran los geoms y las guides en nuestra gráfica.

  • Layer agrupa un conjunto de geoms, cada layer contienen un coord. Podemos apilar múltiples layers en un mismo sistema de coordenadas.

  • Facet agrupa un comjunto de layers, representa una "vista diferente" de un mismo conjunto de datos.

  • Figure agrupa un conjunto de facets

  • Título y leyenda cada figura estar acompañada de una explicación

Anatomía de una figura

Anatomy of a figure https://matplotlib.org/stable/gallery/showcase/anatomy.html

Matplotlib y Seaborn

matplotlib es la biblioteca en la cual se centra todo el contenido de ahora en adelante. Pero matplotlib es solo la herramienta; los conceptos deben trascender independientemente de qué herramienta termines utilizando.

Sobre Matplotlib

Es la piedra angular de múltiples paquetes de visualización existentes, es poderosa pero compleja; no se trata de decidir entre una y la otra muchas veces para lograr la visualización perfecta tenemos que usar algo como seaborn para el 90% de la gráfica y matplotlib para los detalles.

Adaptation of Jake VanderPlas graphic about the Python visualization landscape, by Nicolas P. Rougier

¿Mi recomendación?

Usa ambas, comienza las gráficas con matplotlib, créalas con la biblioteca de tu elección y terminalas con matplotlib.

Matplotlib tiene dos interfaces: una basada en estado (herencia de MATLAB) y la orientada a objetos. Vamos a usar la API orientada a objetos. Como siempre, la clave es la consistencia, elije una y úsala siempre.

import matplotlib.pyplot as plt
import seaborn as sns
np.random.seed(42)
x = np.arange(100)
y1 = (0.1 * x) ** 2 + np.random.uniform(-20, 20, size=(100,))
y2 = (0.05 * x) ** 2 + np.random.uniform(-20, 20, size=(100,))

API basada en estado

plt.figure(figsize=(10, 5), dpi=75)
# figzize (ancho, alto) en pulgadas
# dpi - dots-per-inch
plt.scatter(x, y1, label="Clase 1")
plt.scatter(x, y2, label="Clase 2")
plt.title("Datos artificiales")
plt.xlabel("Eje X")
plt.ylabel("Eje Y")
plt.legend()
<matplotlib.legend.Legend at 0x1242c25e0>

png

API orientada a objetos

fig = plt.figure(figsize=(10, 5), dpi=75)
ax = fig.gca()
ax.scatter(x, y1, label="Clase 1")
ax.scatter(x, y2, label="Clase 2")
ax.set_title("Datos artificiales")
ax.set_xlabel("Eje X")
ax.set_ylabel("Eje Y")
ax.legend()
<matplotlib.legend.Legend at 0x1243ea520>

png

Seaborn

fig = plt.figure(figsize=(10, 5), dpi=75)
ax = fig.gca()
sns.scatterplot(x=x, y=y1, label="Clase 1", ax=ax)
sns.scatterplot(x=x, y=y2, label="Clase 2", ax=ax)
ax.set_title("Datos artificiales")
ax.set_xlabel("Eje X")
ax.set_ylabel("Eje Y")
ax.legend()
<matplotlib.legend.Legend at 0x1244d8e20>

png

Gráficas en 2D

Las gráficas más efectivas son las que muestran pocas variables y las relaciones que existen entre ellas. Mira el ejemplo de arriba, existe una relación entre x e y1, y2. Para graficar la relación, la entrada a nuestra función para graficar son los vectores x e y1 y x e y2.

Usualmente, la variable independiente se coloca en el eje horizontal (el de las equis) mientras que la variable dependiente en el eje vertical (el de las yes).

x = np.array([1, 2, 3, 4])
y = np.array([5, 6, 7, 8])

Scatterplot

fig = plt.figure(figsize=(7, 3), dpi=75)
ax = fig.gca()
sns.scatterplot(x=x, y=y, ax=ax)
<AxesSubplot:>

png

De barras

fig = plt.figure(figsize=(7, 3), dpi=75)
ax = fig.gca()
ax.bar(x, y)
<BarContainer object of 4 artists>

png

Línea

fig = plt.figure(figsize=(7, 3), dpi=75)
ax = fig.gca()
sns.lineplot(x=x, y=y)
<AxesSubplot:>

png

Stats

Como ya vimos un stat es una forma de resumir la información presentada en una gráfica, entre estas operaciones tenemos:

  • Binning: consiste en cateogrizar datos en un conjunto de cubetas
  • Agregaciones estadísticas: promedio, mediana, desviación estandar...
  • Suavizado y regresión: trata de encontrar una función que se aproxime a representar nuestro dataset

Histogramas

x = np.random.normal(0, 1, 300)
bins = np.linspace(-3, 3, 20)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.hist(x, bins=bins)
ax.set_xlabel("Bin")
ax.set_ylabel("Count")
Text(0, 0.5, 'Count')

png

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
# sns.histplot(x = x, bins=bins, ax = ax, element="step", fill=False)
sns.histplot(x=x, bins=bins, ax=ax)
ax.set_xlabel("Bin")
ax.set_ylabel("Count")
Text(0, 0.5, 'Count')

png

Histogramas en 2D

Mi año en Spotify https://tacosdedatos.com/mas-data-viz-con-spotify-python

Calculating optimal number of bins in a histogram https://stats.stackexchange.com/a/862

Agregaciones estadísticas

flights = sns.load_dataset("flights")
flights.head()
year month passengers
0 1949 Jan 112
1 1949 Feb 118
2 1949 Mar 132
3 1949 Apr 129
4 1949 May 121
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
sns.lineplot(data=flights, x="year", y="passengers", ax=ax)
ax.set_xlabel("Año")
ax.set_ylabel("Pasajeros")
Text(0, 0.5, 'Pasajeros')

png

Box plot

Es una gráfica interesantísima y muy útil que muestra múltiples stats de un conjunto de datos, se presenta en forma de un solo dibujo (geom).

Los valores mostrados son:

  • Rango intercuartil, el rango entre los percentiles 25% y 75% del dataset
  • Mediana
  • Extremos, representanlos percentiles 2.5% y 97.5%
  • Outlier o anomalías
x = np.random.normal(0, 1, 100)
fig = plt.figure(figsize=(10, 5), dpi=150)
ax = fig.gca()
ax.boxplot(x, whis=[2.5, 97.5])
percentiles = np.percentile(x, [2.5, 25, 50, 75, 98.5])
min_x, max_x = np.min(x), np.max(x)


def annotate(y, text, left=False):
    offset = 80 if left else -130
    touch = 1.08 if left else 0.92
    ax.annotate(
        xy=(touch, y),
        text=text,
        xytext=(offset, 0),
        va="center",
        textcoords="offset points",
        arrowprops=dict(arrowstyle="->", color="C2", alpha=0.5),
    )


annotate(min_x, "Anomalía (mínimo)")
annotate(max_x, "Anomalía (máximo)")
annotate(percentiles[0], "Extremo menor", True)
annotate(percentiles[1], "Percentil 25%", True)
annotate(percentiles[2], "Mediana")
annotate(percentiles[3], "Percentil 75%", True)
annotate(percentiles[4], "Extremo mayor", True)
ax.set_xlabel("Valores")
ax.set_ylabel("Eje X")
ax.set_title("Box plot")
Text(0.5, 1.0, 'Box plot')

png

# Con seaborn
fig = plt.figure(figsize=(10, 5), dpi=150)
ax = fig.gca()
sns.boxplot(x="month", y="passengers", data=flights, ax=ax)
ax.set_xlabel("Mes")
ax.set_ylabel("Pasajeros")
ax.set_title("Vuelos")
Text(0.5, 1.0, 'Vuelos')

png

Violin plot

Son una extensión de las Box Plots que muestran la distribución de los datos de forma precisa usando una función llamada Kernel Density Estimate:

# Con seaborn
fig = plt.figure(figsize=(10, 5), dpi=150)
ax = fig.gca()
sns.violinplot(x="month", y="passengers", data=flights, ax=ax)
ax.set_xlabel("Mes")
ax.set_ylabel("Pasajeros")
ax.set_title("Vuelos")
Text(0.5, 1.0, 'Vuelos')

png

Regresión

La regresión es una operación que involucra el encontrar una función que pueda representar nuestros datos.

tips = sns.load_dataset("tips")
plt.figure(figsize=(10, 5), dpi=75)
ax = sns.regplot(x="total_bill", y="tip", data=tips)
ax.set_xlabel("Total cuenta")
ax.set_ylabel("Propina")
Text(0, 0.5, 'Propina')

png

Smoothing

De manera similar, el suavizado encuentra una versión simplificada para representar nuestros datos.

Geoms

Marcadores o Markers

Los markers son un ejemplo de geom que podemos usar para representar puntos en la gráfica. Los podemos usar para dotar de información a nuestra gráfica:

seasons = {
    "Invierno": ["Dec", "Jan", "Feb"],
    "Primavera": ["Mar", "Apr", "May"],
    "Verano": ["Jun", "Jul", "Aug"],
    "Otoño": ["Sep", "Oct", "Nov"],
}
seasons_months = {
    season: month for month, seasons in seasons.items() for season in seasons
}
flights["season"] = flights["month"].map(seasons_months)
agg_flights = flights.groupby(["year", "season"])["passengers"].sum().reset_index()
vuelos = {
    season: agg_flights.query(f"season == '{season}'") for season in seasons.keys()
}
fig = plt.figure(figsize=(10, 5), dpi=150)
ax = fig.gca()
ax.scatter(
    vuelos["Invierno"]["year"],
    vuelos["Invierno"]["passengers"],
    label="Invierno",
    marker="+",
    color="black",
)
ax.scatter(
    vuelos["Primavera"]["year"],
    vuelos["Primavera"]["passengers"],
    label="Primavera",
    marker="X",
    color="black",
)
ax.scatter(
    vuelos["Verano"]["year"],
    vuelos["Verano"]["passengers"],
    label="Verano",
    marker="*",
    color="black",
)
ax.scatter(
    vuelos["Otoño"]["year"],
    vuelos["Otoño"]["passengers"],
    label="Otoño",
    marker="$❄$",
    color="black",
)
ax.legend()
ax.set_title("Pasajeros por temporada")
ax.set_xlabel("Año")
ax.set_ylabel("Pasajeros")
Text(0, 0.5, 'Pasajeros')

png

Revisa la documentación de matplotlib sobre los marcadores disponibles: Marker reference.

fig = plt.figure(figsize=(10, 5), dpi=150)
ax = fig.gca()
ax.scatter(
    vuelos["Invierno"]["year"],
    vuelos["Invierno"]["passengers"],
    label="Invierno",
    marker="+",
    color="blue",
)
ax.scatter(
    vuelos["Primavera"]["year"],
    vuelos["Primavera"]["passengers"],
    label="Primavera",
    marker="X",
    color="green",
)
ax.scatter(
    vuelos["Verano"]["year"],
    vuelos["Verano"]["passengers"],
    label="Verano",
    marker="*",
    color="orange",
)
ax.scatter(
    vuelos["Otoño"]["year"],
    vuelos["Otoño"]["passengers"],
    label="Otoño",
    marker="$❄$",
    color="brown",
)
ax.legend()
ax.set_title("Pasajeros por temporada")
ax.set_xlabel("Año")
ax.set_ylabel("Pasajeros")
Text(0, 0.5, 'Pasajeros')

png

Usando marcadores para mostrar más variables

Terremotos en México

(Tal vez no es el mejor ejemplo, pero vamos a tratar de sacarle jugo) Te invito a ver otra visualización que hice con este mismo dataset en Tacos De Datos.

terremotos = pd.read_csv(
    "assets/04/SSNMX_catalogo_20170101_20180101.csv",
    engine="python",
    skiprows=4,
    skipfooter=7,
)
terremotos = terremotos[["Latitud", "Longitud", "Magnitud", "Profundidad"]]
terremotos = terremotos.query("Magnitud > 2.0")
terremotos = terremotos.query("Latitud < 22.0")
terremotos.head()
Latitud Longitud Magnitud Profundidad
0 15.2218 -93.1245 3.5 81.5
1 16.9610 -99.5348 3.2 36.7
2 16.5082 -98.5332 3.4 18.3
3 14.5250 -92.5765 3.7 54.8
4 16.3272 -98.2833 3.5 8.6
fig = plt.figure(figsize=(7, 6), dpi=150)
ax = fig.add_subplot(1, 1, 1)
ax.scatter(terremotos["Longitud"], terremotos["Latitud"])
ax.set_title("Terremotos en México")
ax.set_xlabel("Longitud")
ax.set_ylabel("Latitud")
Text(0, 0.5, 'Latitud')

png

def add_magnitud_legend(ax, etiquetas, magnitudes_reales):
    ls = []
    for scale in magnitudes_reales:
        l = ax.scatter([], [], s=scale, edgecolors="none", facecolors="C0")
        ls.append(l)
    leg = ax.legend(
        ls,
        etiquetas,
        ncol=len(etiquetas),
        frameon=True,
        fontsize=12,
        handlelength=2,
        loc=8,
        borderpad=1,
        handletextpad=1,
        title="Magnitud",
        scatterpoints=1,
    )
fig = plt.figure(figsize=(8, 6), dpi=150)
ax = fig.add_subplot(1, 1, 1)

magnitudes = np.linspace(4, 7, 4)
magnitudes_reales = (magnitudes[:-1] - 3) * 30
etiquetas = [f">{number:.2f}" for number in magnitudes[:-1]]


puntos = ax.scatter(
    terremotos["Longitud"],
    terremotos["Latitud"],
    s=(terremotos["Magnitud"] - 3) * 30,
    alpha=0.2,
)

ax.set_title("Terremotos en México")
ax.set_xlabel("Longitud")
ax.set_ylabel("Latitud")
ax.set_ylim((terremotos["Latitud"].min() - 2, terremotos["Latitud"].max() + 0.5))

add_magnitud_legend(ax, etiquetas, magnitudes_reales)
/Users/antonioferegrino/.local/share/virtualenvs/df-JhqtXTwc/lib/python3.8/site-packages/matplotlib/collections.py:1003: RuntimeWarning: invalid value encountered in sqrt
  scale = np.sqrt(self._sizes) * dpi / 72.0 * self._factor

png

fig = plt.figure(figsize=(8, 6), dpi=150)
ax = fig.add_subplot(1, 1, 1)

magnitudes = np.linspace(4, 7, 4)
magnitudes_reales = (magnitudes[:-1] - 3) * 30
etiquetas = [f">{number:.2f}" for number in magnitudes[:-1]]


puntos = ax.scatter(
    terremotos["Longitud"],
    terremotos["Latitud"],
    s=(terremotos["Magnitud"] - 3) * 30,
    c=terremotos["Profundidad"],
)

ax.set_facecolor("black")
ax.set_title("Terremotos en México")
ax.set_xlabel("Longitud")
ax.set_ylabel("Latitud")
ax.set_ylim((terremotos["Latitud"].min() - 2, terremotos["Latitud"].max() + 0.5))
cb = fig.colorbar(puntos)
cb.set_label("Kilómetros")

add_magnitud_legend(ax, etiquetas, magnitudes_reales)

png

Mapas de colores

Enlace a las gráficas https://matplotlib.org/2.0.2/examples/color/colormaps_reference.html

Más colores

Uno puede definir sus propios mapas de colores, esta página te pude servir como inspiración para crear tus propias paletas https://colorbrewer2.org.

fig = plt.figure(figsize=(8, 6), dpi=150)
ax = fig.add_subplot(1, 1, 1)

magnitudes = np.linspace(4, 7, 4)
magnitudes_reales = (magnitudes[:-1] - 3) * 30
etiquetas = [f">{number:.2f}" for number in magnitudes[:-1]]


puntos = ax.scatter(
    terremotos["Longitud"],
    terremotos["Latitud"],
    s=(terremotos["Magnitud"] - 3) * 30,
    c=terremotos["Profundidad"],
    cmap="YlOrRd",
)

ax.set_facecolor("black")
ax.set_title("Terremotos en México")
ax.set_xlabel("Longitud")
ax.set_ylabel("Latitud")
ax.set_ylim((terremotos["Latitud"].min() - 2, terremotos["Latitud"].max() + 0.5))
cb = fig.colorbar(puntos)
cb.set_label("Kilómetros")

add_magnitud_legend(ax, etiquetas, magnitudes_reales)

png

Uso de colores

🚨 Ten en cuenta que a veces las gráficas que hagas pueden ser impresas en escala de grises o blanco y negro.

🚨 Ten en cuenta hay personas con alguna deficiencia en la percepción de colores: es decir, a veces los colores no lo son todo en las gráficas.

Líneas

Son otra forma de geoms que unen puntos. Usamos líneas cuando queremos representar que hay algo entre dos puntos (una relación, por ejemplo).

Diferentes estilos de líneas

Podemos usar el grosor (linewidth) y color (color) de una línea para diferenciar entre distintas variables:

fig = plt.figure(figsize=(10, 5), dpi=150)
ax = fig.gca()
ax.plot(
    vuelos["Invierno"]["year"],
    vuelos["Invierno"]["passengers"],
    label="Invierno",
    marker="+",
    color="blue",
    linewidth=0.5,
)
ax.plot(
    vuelos["Primavera"]["year"],
    vuelos["Primavera"]["passengers"],
    label="Primavera",
    marker="X",
    color="green",
    linewidth=1,
)
ax.plot(
    vuelos["Verano"]["year"],
    vuelos["Verano"]["passengers"],
    label="Verano",
    marker="*",
    color="orange",
    linewidth=2,
)
ax.plot(
    vuelos["Otoño"]["year"],
    vuelos["Otoño"]["passengers"],
    label="Otoño",
    marker="x",
    color="brown",
    linewidth=4,
)
ax.legend()
ax.set_title("Pasajeros por temporada")
ax.set_xlabel("Año")
ax.set_ylabel("Pasajeros")
Text(0, 0.5, 'Pasajeros')

png

Podemos usar distintos estilos de líneas (linestyle):

fig = plt.figure(figsize=(10, 5), dpi=100)
ax = fig.gca()

ax.plot(
    vuelos["Invierno"]["year"],
    vuelos["Invierno"]["passengers"],
    label="Invierno",
    marker="+",
    color="blue",
    linestyle="--",
    linewidth=2,
)

ax.plot(
    vuelos["Primavera"]["year"],
    vuelos["Primavera"]["passengers"],
    label="Primavera",
    marker="X",
    color="green",
    linestyle=":",
    linewidth=2,
)
ax.plot(
    vuelos["Verano"]["year"],
    vuelos["Verano"]["passengers"],
    label="Verano",
    marker="*",
    color="orange",
    linestyle="-",
    linewidth=2,
)
ax.plot(
    vuelos["Otoño"]["year"],
    vuelos["Otoño"]["passengers"],
    label="Otoño",
    marker="$❄$",
    color="brown",
    linestyle="-.",
    linewidth=2,
)
ax.legend()
ax.set_title("Pasajeros por temporada")
ax.set_xlabel("Año")
ax.set_ylabel("Pasajeros")
Text(0, 0.5, 'Pasajeros')

png

fig = plt.figure(figsize=(10, 5), dpi=100)
ax = fig.gca()

sns.lineplot(
    x="year",
    y="passengers",
    data=flights,
    estimator=np.sum,
    ci=None,
    hue="season",
    ax=ax,
)

ax.legend()
ax.set_title("Pasajeros por temporada")
ax.set_xlabel("Año")
ax.set_ylabel("Pasajeros")
Text(0, 0.5, 'Pasajeros')

png

Podemos usar transparencia alpha para resaltar elementos que merezcan llamar la atención:

fig = plt.figure(figsize=(10, 5), dpi=100)
ax = fig.gca()

mean = pd.DataFrame(
    {season: vuelos[season]["passengers"].reset_index(drop=True) for season in seasons}
).mean(axis=1)

ax.plot(
    vuelos["Otoño"]["year"],
    mean,
    label="Promedio",
    marker="$o$",
    color="black",
    linestyle="-",
    linewidth=2,
)

ax.plot(
    vuelos["Invierno"]["year"],
    vuelos["Invierno"]["passengers"],
    label="Invierno",
    marker="+",
    color="blue",
    linestyle="--",
    linewidth=2,
    alpha=0.2,
)
ax.plot(
    vuelos["Primavera"]["year"],
    vuelos["Primavera"]["passengers"],
    label="Primavera",
    marker="X",
    color="green",
    linestyle=":",
    linewidth=2,
    alpha=0.2,
)
ax.plot(
    vuelos["Verano"]["year"],
    vuelos["Verano"]["passengers"],
    label="Verano",
    marker="*",
    color="orange",
    linestyle="-",
    linewidth=2,
    alpha=0.2,
)
ax.plot(
    vuelos["Otoño"]["year"],
    vuelos["Otoño"]["passengers"],
    label="Otoño",
    marker="$❄$",
    color="brown",
    linestyle="-.",
    linewidth=2,
    alpha=0.2,
)

ax.legend()
ax.set_title("Pasajeros por temporada")
ax.set_xlabel("Año")
ax.set_ylabel("Pasajeros")
Text(0, 0.5, 'Pasajeros')

png

Gráficas de barras

fig = plt.figure(figsize=(10, 5), dpi=100)
ax = fig.gca()

sns.barplot(
    x="year",
    y="passengers",
    data=flights,
    estimator=np.sum,
    hue="season",
    ci=None,
    ax=ax,
)

ax.legend()
ax.set_title("Pasajeros por temporada")
ax.set_xlabel("Año")
ax.set_ylabel("Pasajeros")
Text(0, 0.5, 'Pasajeros')

png

Coords

La forma de visualizar las coords en una gráfica hecha con matplotlib o alguna de sus derivadas, es a través de los ejes o axes.

Estos ejes especifican un rango en unidades usadas para medir nuestras variables dentro del dataset (número de pasajeros) y lo presentan en un rango determinado en unidades visuales (pulgadas).

Ya hemos visto cómo es que podemos configurar el tamaño de nuestras gráficas, e indirectamente, los valores de conversión de nuestros ejes

Cambio de tamaño

Gráfica 🚼

fig = plt.figure(figsize=(4, 2), dpi=100)
ax = fig.gca()

sns.lineplot(
    x="year",
    y="passengers",
    data=flights,
    estimator=np.sum,
    ci=None,
    hue="season",
    ax=ax,
)

ax.legend()
ax.set_title("Pasajeros por temporada")
ax.set_xlabel("Año")
ax.set_ylabel("Pasajeros")
Text(0, 0.5, 'Pasajeros')

png

Gráfica grande

fig = plt.figure(figsize=(10, 7), dpi=300)
ax = fig.gca()

sns.lineplot(
    x="year",
    y="passengers",
    data=flights,
    estimator=np.sum,
    ci=None,
    hue="season",
    ax=ax,
)

ax.legend()
ax.set_title("Pasajeros por temporada")
ax.set_xlabel("Año")
ax.set_ylabel("Pasajeros")
Text(0, 0.5, 'Pasajeros')

png

Cambio de rangos

Podemos elegir el rango de datos que se muestra en nuestra gráfica, podemos usar set_ylims y set_xlim (recuerda que debes utilizar los valores correspondientes al rango en tu dataset):

fig = plt.figure(figsize=(10, 7), dpi=100)
ax = fig.gca()
sns.lineplot(
    x="year",
    y="passengers",
    data=flights,
    estimator=np.sum,
    ci=None,
    hue="season",
    ax=ax,
)

ax.set_xlim((1950, 1952))  # de 1950 a 1952
ax.set_ylim((300, 800))  # de 300 a 800 pasajeros

ax.legend()
ax.set_title("Pasajeros por temporada")
ax.set_xlabel("Año")
ax.set_ylabel("Pasajeros")
Text(0, 0.5, 'Pasajeros')

png

Relación de aspecto

Podemos usar set_aspect para especificar un número llamado ratio el cual determinará la siguiente operación \(altura = ratio \times anchura\).

# Un círculo
angle = np.linspace(-np.pi, np.pi, 100)
x, y = np.cos(angle), -np.sin(angle)

fig, axs = plt.subplots(1, 3, figsize=(12, 3))

fig = plt.figure(figsize=(12, 3))
axs[0].plot(x, y)
axs[0].set_title("Relación de aspecto por default")

axs[1].plot(x, y)
axs[1].set_aspect(0.5)
axs[1].set_title("Relación incorrecta")


axs[2].plot(x, y)
axs[2].set_aspect(1.0)
axs[2].set_title("¡Correcta!")
Text(0.5, 1.0, '¡Correcta!')

png

<Figure size 864x216 with 0 Axes>

Layers

Ya hemos estado haciendo uso de layers a lo largo de este notebook. Cada vez que agregamos una nueva colección de geoms a un axes, estamos agregando una nueva capa:

fig = plt.figure(figsize=(10, 5), dpi=150)
ax = fig.gca()
ax.plot(
    vuelos["Invierno"]["year"],
    vuelos["Invierno"]["passengers"],
    label="Invierno",
    marker="+",
    color="blue",
    linewidth=0.5,
)
ax.plot(
    vuelos["Primavera"]["year"],
    vuelos["Primavera"]["passengers"],
    label="Primavera",
    marker="X",
    color="green",
    linewidth=1,
)
ax.plot(
    vuelos["Verano"]["year"],
    vuelos["Verano"]["passengers"],
    label="Verano",
    marker="*",
    color="orange",
    linewidth=2,
)
ax.plot(
    vuelos["Otoño"]["year"],
    vuelos["Otoño"]["passengers"],
    label="Otoño",
    marker="$❄$",
    color="brown",
    linewidth=4,
)
ax.legend()
ax.set_title("Pasajeros por temporada")
ax.set_xlabel("Año")
ax.set_ylabel("Pasajeros")
Text(0, 0.5, 'Pasajeros')

png

Facets

Podemos además usar facets para mostrar difetentes layers dentro de una misma figura, la siguiente es solo una forma de crear distintos facets, en matplotlib se les conoce como subplots:

fig, axs = plt.subplots(1, 2, figsize=(12, 5))

sns.barplot(
    x="year",
    y="passengers",
    data=flights,
    estimator=np.sum,
    hue="season",
    ci=None,
    ax=axs[0],
)

axs[0].legend()
axs[0].set_title("Pasajeros por temporada")
axs[0].set_xlabel("Año")
axs[0].set_ylabel("Pasajeros")


sns.lineplot(
    x="year",
    y="passengers",
    data=flights,
    estimator=np.sum,
    hue="season",
    ci=None,
    ax=axs[1],
)
axs[1].legend()
axs[1].set_title("Pasajeros por temporada")
axs[1].set_xlabel("Año")
axs[1].set_ylabel("Pasajeros")
Text(0, 0.5, 'Pasajeros')

png

Échale un ojo a la documentación de matplotlib para encontrar más código e inspiración https://matplotlib.org/stable/tutorials/intermediate/gridspec.html

Hacicéndo una buena gráfica

Es tu momento para brillar, encuentra un dataset (o usa alguno de los que están en este Notebook) y crea una gráfica. Mándamela por Twitter o al Discord para revisarla y compartirla 😁

Referencias

Libros

Videos

Sitios web