Percorso Tutorial #

Definizione di percorsi nella visualizzazione Matplotlib.

L'oggetto sottostante a tutti gli matplotlib.patchesoggetti è Path, che supporta l'insieme standard di comandi moveto, lineto, curveto per disegnare contorni semplici e composti costituiti da segmenti di linea e spline. Viene istanziato con un array ( PathN, 2) di vertici (x, y) e un array di codici di percorso di lunghezza N. Ad esempio per disegnare il rettangolo unitario da (0, 0) a (1, 1), potremmo usare questo codice:

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()
percorso didattico

Vengono riconosciuti i seguenti codici di percorso

Codice

Vertici

Descrizione

STOP

1 (ignorato)

Un indicatore per la fine dell'intero percorso (attualmente non richiesto e ignorato).

MOVETO

1

Prendi la penna e spostati sul vertice dato.

LINETO

1

Traccia una linea dalla posizione corrente al vertice dato.

CURVE3

2: 1 punto di controllo, 1 punto finale

Disegna una curva di Bézier quadratica dalla posizione corrente, con il dato punto di controllo, al dato punto finale.

CURVE4

3: 2 punti di controllo, 1 punto finale

Disegna una curva di Bézier cubica dalla posizione corrente, con i punti di controllo dati, al punto finale dato.

CLOSEPOLY

1 (il punto è ignorato)

Disegna un segmento di linea fino al punto iniziale della polilinea corrente.

Bézier esempio #

Alcuni dei componenti del percorso richiedono più vertici per specificarli: ad esempio CURVE 3 è una curva di Bézier con un punto di controllo e un punto finale e CURVE4 ha tre vertici per i due punti di controllo e il punto finale. L'esempio seguente mostra una spline di Bézier CURVE4 -- la curva di Bézier sarà contenuta nello scafo convesso del punto iniziale, i due punti di controllo e il punto finale

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()
percorso didattico

Percorsi composti #

Tutte le semplici primitive di patch in matplotlib, Rectangle, Circle, Polygon, ecc., sono implementate con percorso semplice. Funzioni di plottaggio come hist()e bar(), che creano un certo numero di primitive, ad esempio un gruppo di rettangoli, di solito possono essere implementate in modo più efficiente utilizzando un percorso composto. Il motivo per cui barviene creato un elenco di rettangoli e non un percorso composto è in gran parte storico: il Pathcodice è relativamente nuovo e bar lo precede. Mentre potremmo cambiarlo ora, romperebbe il vecchio codice, quindi qui tratteremo come creare percorsi composti, sostituendo la funzionalità in bar, nel caso in cui sia necessario farlo nel proprio codice per motivi di efficienza, ad esempio, si sta creando una trama da bar animata.

Realizzeremo il grafico dell'istogramma creando una serie di rettangoli per ogni barra dell'istogramma: la larghezza del rettangolo è la larghezza del contenitore e l'altezza del rettangolo è il numero di punti dati in quel contenitore. Per prima cosa creeremo alcuni dati casuali normalmente distribuiti e calcoleremo l'istogramma. Poiché numpy restituisce i bordi del contenitore e non i centri, la lunghezza di binsè 1 maggiore della lunghezza di nnell'esempio seguente:

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

Ora estrarremo gli angoli dei rettangoli. Ciascuno degli array left, bottom, ecc. di seguito è len(n), dove nè l'array di conteggi per ciascuna barra dell'istogramma:

# 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

Ora dobbiamo costruire il nostro percorso composto, che consisterà in una serie di MOVETO, LINETOe CLOSEPOLYper ogni rettangolo. Per ogni rettangolo, abbiamo bisogno di 5 vertici: 1 per MOVETO, 3 per LINETO, e 1 per CLOSEPOLY. Come indicato nella tabella sopra, il vertice per il closepoly viene ignorato ma ne abbiamo ancora bisogno per mantenere i codici allineati con i vertici:

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

Non resta che creare il percorso, collegarlo a un PathPatche aggiungerlo ai nostri assi:

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()
percorso didattico

Galleria generata da Sphinx-Gallery