Ruta Tutorial #

Definición de rutas en su visualización de Matplotlib.

El objeto subyacente a todos los matplotlib.patchesobjetos es el Path, que admite el conjunto estándar de comandos moveto, lineto, curveto para dibujar contornos simples y compuestos que consisten en segmentos de línea y splines. El Pathse instancia con una matriz (N, 2) de vértices (x, y) y una matriz de códigos de ruta de longitud N. Por ejemplo, para dibujar el rectángulo unitario de (0, 0) a (1, 1), podríamos usar este código:

import matplotlib.pyplot as plt
from matplotlib.path import Path
import matplotlib.patches as patches

verts = [
   (0., 0.),  # left, bottom
   (0., 1.),  # left, top
   (1., 1.),  # right, top
   (1., 0.),  # right, bottom
   (0., 0.),  # ignored
]

codes = [
    Path.MOVETO,
    Path.LINETO,
    Path.LINETO,
    Path.LINETO,
    Path.CLOSEPOLY,
]

path = Path(verts, codes)

fig, ax = plt.subplots()
patch = patches.PathPatch(path, facecolor='orange', lw=2)
ax.add_patch(patch)
ax.set_xlim(-2, 2)
ax.set_ylim(-2, 2)
plt.show()
tutorial de ruta

Se reconocen los siguientes códigos de ruta

Código

vértices

Descripción

STOP

1 (ignorado)

Un marcador para el final de toda la ruta (actualmente no se requiere y se ignora).

MOVETO

1

Recoge el bolígrafo y muévete al vértice dado.

LINETO

1

Dibuja una línea desde la posición actual hasta el vértice dado.

CURVE3

2: 1 punto de control, 1 punto final

Dibuje una curva de Bézier cuadrática desde la posición actual, con el punto de control dado, hasta el punto final dado.

CURVE4

3: 2 puntos de control, 1 punto final

Dibuje una curva de Bézier cúbica desde la posición actual, con los puntos de control dados, hasta el punto final dado.

CLOSEPOLY

1 (el punto se ignora)

Dibuja un segmento de línea hasta el punto inicial de la polilínea actual.

Bézier ejemplo #

Algunos de los componentes de la ruta requieren múltiples vértices para especificarlos: por ejemplo, CURVA 3 es una curva bézier con un punto de control y un punto final, y CURVE4 tiene tres vértices para los dos puntos de control y el punto final. El siguiente ejemplo muestra una spline Bézier CURVE4: la curva Bézier estará contenida en el casco convexo del punto inicial, los dos puntos de control y el punto final.

verts = [
   (0., 0.),   # P0
   (0.2, 1.),  # P1
   (1., 0.8),  # P2
   (0.8, 0.),  # P3
]

codes = [
    Path.MOVETO,
    Path.CURVE4,
    Path.CURVE4,
    Path.CURVE4,
]

path = Path(verts, codes)

fig, ax = plt.subplots()
patch = patches.PathPatch(path, facecolor='none', lw=2)
ax.add_patch(patch)

xs, ys = zip(*verts)
ax.plot(xs, ys, 'x--', lw=2, color='black', ms=10)

ax.text(-0.05, -0.05, 'P0')
ax.text(0.15, 1.05, 'P1')
ax.text(1.05, 0.85, 'P2')
ax.text(0.85, -0.05, 'P3')

ax.set_xlim(-0.1, 1.1)
ax.set_ylim(-0.1, 1.1)
plt.show()
tutorial de ruta

Caminos compuestos #

Todas las primitivas de parche simple en matplotlib, Rectangle, Circle, Polygon, etc., se implementan con una ruta simple. Las funciones de trazado como hist()y bar(), que crean una serie de primitivas, por ejemplo, un grupo de rectángulos, generalmente se pueden implementar de manera más eficiente utilizando una ruta compuesta. La razón por la que barse crea una lista de rectángulos y no una ruta compuesta es en gran medida histórica: el Pathcódigo es comparativamente nuevo y bar anterior. Si bien podemos cambiarlo ahora, rompería el código antiguo, por lo que aquí cubriremos cómo crear rutas compuestas, reemplazando la funcionalidad en la barra, en caso de que necesite hacerlo en su propio código por razones de eficiencia, por ejemplo, está creando un gráfico de barras animadas.

Haremos el gráfico de histograma creando una serie de rectángulos para cada barra de histograma: el ancho del rectángulo es el ancho del contenedor y la altura del rectángulo es la cantidad de puntos de datos en ese contenedor. Primero, crearemos algunos datos aleatorios normalmente distribuidos y calcularemos el histograma. Debido a que numpy devuelve los bordes del contenedor y no los centros, la longitud de binses 1 mayor que la longitud de nen el siguiente ejemplo:

# histogram our data with numpy
data = np.random.randn(1000)
n, bins = np.histogram(data, 100)

Ahora extraeremos las esquinas de los rectángulos. Cada una de las matrices siguientes es left, bottom, etc., len(n)donde nestá la matriz de conteos para cada barra de histograma:

# get the corners of the rectangles for the histogram
left = np.array(bins[:-1])
right = np.array(bins[1:])
bottom = np.zeros(len(left))
top = bottom + n

Ahora tenemos que construir nuestro camino compuesto, que consistirá en una serie de MOVETOy LINETOpara CLOSEPOLYcada rectángulo. Para cada rectángulo, necesitamos 5 vértices: 1 para MOVETO, 3 para LINETOy 1 para CLOSEPOLY. Como se indica en la tabla anterior, se ignora el vértice para el closepoly pero aún lo necesitamos para mantener los códigos alineados con los vértices:

nverts = nrects*(1+3+1)
verts = np.zeros((nverts, 2))
codes = np.ones(nverts, int) * path.Path.LINETO
codes[0::5] = path.Path.MOVETO
codes[4::5] = path.Path.CLOSEPOLY
verts[0::5, 0] = left
verts[0::5, 1] = bottom
verts[1::5, 0] = left
verts[1::5, 1] = top
verts[2::5, 0] = right
verts[2::5, 1] = top
verts[3::5, 0] = right
verts[3::5, 1] = bottom

Todo lo que queda es crear la ruta, adjuntarla a un PathPatchy agregarla a nuestros ejes:

barpath = path.Path(verts, codes)
patch = patches.PathPatch(barpath, facecolor='green',
  edgecolor='yellow', alpha=0.5)
ax.add_patch(patch)
import numpy as np
import matplotlib.patches as patches
import matplotlib.path as path

fig, ax = plt.subplots()
# Fixing random state for reproducibility
np.random.seed(19680801)

# histogram our data with numpy
data = np.random.randn(1000)
n, bins = np.histogram(data, 100)

# get the corners of the rectangles for the histogram
left = np.array(bins[:-1])
right = np.array(bins[1:])
bottom = np.zeros(len(left))
top = bottom + n
nrects = len(left)

nverts = nrects*(1+3+1)
verts = np.zeros((nverts, 2))
codes = np.ones(nverts, int) * path.Path.LINETO
codes[0::5] = path.Path.MOVETO
codes[4::5] = path.Path.CLOSEPOLY
verts[0::5, 0] = left
verts[0::5, 1] = bottom
verts[1::5, 0] = left
verts[1::5, 1] = top
verts[2::5, 0] = right
verts[2::5, 1] = top
verts[3::5, 0] = right
verts[3::5, 1] = bottom

barpath = path.Path(verts, codes)
patch = patches.PathPatch(barpath, facecolor='green',
                          edgecolor='yellow', alpha=0.5)
ax.add_patch(patch)

ax.set_xlim(left[0], right[-1])
ax.set_ylim(bottom.min(), top.max())

plt.show()
tutorial de ruta

Galería generada por Sphinx-Gallery