Nota
Haga clic aquí para descargar el código de ejemplo completo
Ruta Tutorial #
Definición de rutas en su visualización de Matplotlib.
El objeto subyacente a todos los matplotlib.patches
objetos 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 Path
se 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](/stable/_images/sphx_glr_path_tutorial_001.png)
Se reconocen los siguientes códigos de ruta
Código |
vértices |
Descripción |
---|---|---|
|
1 (ignorado) |
Un marcador para el final de toda la ruta (actualmente no se requiere y se ignora). |
|
1 |
Recoge el bolígrafo y muévete al vértice dado. |
|
1 |
Dibuja una línea desde la posición actual hasta el vértice dado. |
|
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. |
|
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. |
|
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](/stable/_images/sphx_glr_path_tutorial_002.png)
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 bar
se crea una lista de rectángulos y no una ruta compuesta es en gran medida histórica: el
Path
có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 bins
es 1 mayor que la longitud de n
en 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 n
está la matriz de conteos para cada barra de histograma:
Ahora tenemos que construir nuestro camino compuesto, que consistirá en una serie de MOVETO
y LINETO
para CLOSEPOLY
cada rectángulo. Para cada rectángulo, necesitamos 5 vértices: 1 para MOVETO
, 3 para LINETO
y 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
PathPatch
y 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](/stable/_images/sphx_glr_path_tutorial_003.png)