Transforme los aburridos gráficos de líneas predeterminados de Matplotlib en impresionantes visualizaciones personalizadas
Cualquiera que haya usado Matplotlib sabe lo feos que son los gráficos predeterminados. En esta serie de artículos, compartiré algunos consejos para hacer que sus visualizaciones se destaquen y reflejen su estilo individual.
Comenzaremos con un gráfico lineal simple y ampliamente utilizado. Lo más destacado será agregar un relleno degradado debajo del camino, una tarea que no es del todo sencilla.
¡Así que profundicemos y repasemos todos los pasos clave de esta transformación!
Primero hagamos todas las importaciones necesarias.
import pandas as pd
import numpy as np
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
from matplotlib import rcParams
from matplotlib.path import Path
from matplotlib.patches import PathPatchnp.random.seed(38)
Ahora necesitamos generar datos de muestra para nuestra visualización. Vamos a crear algo similar a cómo se ven los precios de las acciones.
dates = pd.date_range(start='2024-02-01', periods=100, freq='D')
initial_rate = 75
drift = 0.003
volatility = 0.1
returns = np.random.normal(drift, volatility, len(dates))
rates = initial_rate * np.cumprod(1 + returns)x, y = dates, rates
Veamos cómo se ve con la configuración predeterminada de Matplotlib.
fix, ax = plt.subplots(figsize=(8, 4))
ax.plot(dates, rates)
ax.xaxis.set_major_locator(mdates.DayLocator(interval=30))
plt.show()
Realmente no es una fascinación, ¿verdad? Pero poco a poco lo haremos lucir mejor.
- establecer título
- definir los parámetros generales del gráfico: tamaño y fuente
- coloque marcas de verificación Y a la derecha
- cambiar el color, estilo y ancho de la línea principal
# General parameters
fig, ax = plt.subplots(figsize=(10, 6))
plt.title("Daily visitors", fontsize=18, color="black")
rcParams['font.family'] = 'DejaVu Sans'
rcParams['font.size'] = 14# Axis Y to the right
ax.yaxis.tick_right()
ax.yaxis.set_label_position("right")
# Plotting main line
ax.plot(dates, rates, color='#268358', linewidth=2)
Muy bien, ahora se ve un poco más limpio.
Ahora nos gustaría agregar una cuadrícula minimalista al fondo, eliminar los bordes para una apariencia más limpia y eliminar las marcas de verificación del eje Y.
# Grid
ax.grid(color="gray", linestyle=(0, (10, 10)), linewidth=0.5, alpha=0.6)
ax.tick_params(axis="x", colors="black")
ax.tick_params(axis="y", left=False, labelleft=False) # Borders
ax.spines["top"].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines["bottom"].set_color("black")
ax.spines['left'].set_color('white')
ax.spines['left'].set_linewidth(1)
# Remove ticks from axis Y
ax.tick_params(axis='y', length=0)
Ahora agregamos un pequeño detalle estético: el año cerca de la primera marca en el eje X. También aclaramos el color de fuente de las etiquetas de marca.
# Add year to the first date on the axis
def custom_date_formatter(t, pos, dates, x_interval):
date = dates[pos*x_interval]
if pos == 0:
return date.strftime('%d %b \'%y')
else:
return date.strftime('%d %b')
ax.xaxis.set_major_formatter(ticker.FuncFormatter((lambda x, pos: custom_date_formatter(x, pos, dates=dates, x_interval=x_interval))))# Ticks label color
[t.set_color('#808079') for t in ax.yaxis.get_ticklabels()]
[t.set_color('#808079') for t in ax.xaxis.get_ticklabels()]
Y nos acercamos a la parte más complicada: cómo crear un degradado debajo de la curva. En realidad esta opción no existe en Matplotlib, pero podemos simularla creando una imagen degradada y luego recortándola con el gráfico.
# Gradient
numeric_x = np.array([i for i in range(len(x))])
numeric_x_patch = np.append(numeric_x, max(numeric_x))
numeric_x_patch = np.append(numeric_x_patch[0], numeric_x_patch)
y_patch = np.append(y, 0)
y_patch = np.append(0, y_patch)path = Path(np.array([numeric_x_patch, y_patch]).transpose())
patch = PathPatch(path, facecolor='none')
plt.gca().add_patch(patch)
ax.imshow(numeric_x.reshape(len(numeric_x), 1), interpolation="bicubic",
cmap=plt.cm.Greens,
origin='lower',
alpha=0.3,
extent=[min(numeric_x), max(numeric_x), min(y_patch), max(y_patch) * 1.2],
aspect="auto", clip_path=patch, clip_on=True)
Ahora se ve bonito y limpio. Sólo necesitamos agregar varios detalles usando cualquier editor (prefiero Google Slides): título, esquinas redondeadas y algunos indicadores numéricos.
El código completo para reproducir la visualización se encuentra a continuación: