Notiz
Klicken Sie hier , um den vollständigen Beispielcode herunterzuladen
Pfad-Tutorial #
Pfade in Ihrer Matplotlib-Visualisierung definieren.
Das Objekt, das allen matplotlib.patches
Objekten zugrunde liegt, ist das Path
, das die Standardbefehle moveto, lineto, curveto unterstützt, um einfache und zusammengesetzte Umrisse zu zeichnen, die aus Liniensegmenten und Splines bestehen. Das Path
wird mit einem (N, 2)-Array von (x, y)-Vertices und einem N-langen Array von Pfadcodes instanziiert. Um beispielsweise das Einheitsrechteck von (0, 0) nach (1, 1) zu zeichnen, könnten wir diesen Code verwenden:
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()
Die folgenden Pfadcodes werden erkannt
Code |
Eckpunkte |
Beschreibung |
---|---|---|
|
1 (ignoriert) |
Eine Markierung für das Ende des gesamten Pfads (derzeit nicht erforderlich und ignoriert). |
|
1 |
Nehmen Sie den Stift und bewegen Sie sich zum angegebenen Scheitelpunkt. |
|
1 |
Zeichnen Sie eine Linie von der aktuellen Position zum angegebenen Scheitelpunkt. |
|
2: 1 Kontrollpunkt, 1 Endpunkt |
Zeichnen Sie eine quadratische Bézier-Kurve von der aktuellen Position mit dem angegebenen Kontrollpunkt bis zum angegebenen Endpunkt. |
|
3: 2 Kontrollpunkte, 1 Endpunkt |
Zeichnen Sie eine kubische Bézier-Kurve von der aktuellen Position mit den angegebenen Kontrollpunkten bis zum angegebenen Endpunkt. |
|
1 (der Punkt wird ignoriert) |
Zeichnen Sie ein Liniensegment zum Startpunkt der aktuellen Polylinie. |
Bézier-Beispiel #
Einige der Pfadkomponenten erfordern mehrere Scheitelpunkte, um sie anzugeben: KURVE 3 ist beispielsweise eine Bézierkurve mit einem Kontrollpunkt und einem Endpunkt, und KURVE4 hat drei Scheitelpunkte für die beiden Kontrollpunkte und den Endpunkt. Das folgende Beispiel zeigt einen CURVE4 Bézier-Spline – die Bézier-Kurve wird in der konvexen Hülle des Startpunkts, der beiden Kontrollpunkte und des Endpunkts enthalten sein
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()
Zusammengesetzte Pfade #
Alle einfachen Patch-Grundelemente in Matplotlib, Rectangle, Circle, Polygon usw. werden mit einfachen Pfaden implementiert. Zeichenfunktionen wie hist()
und
bar()
, die eine Reihe von Grundelementen erstellen, z. B. eine Reihe von Rechtecken, können normalerweise effizienter mit einem zusammengesetzten Pfad implementiert werden. Der Grund dafür , dass bar
eine Liste von Rechtecken und kein zusammengesetzter Pfad erstellt wird, ist weitgehend historisch: Der
Path
Code ist vergleichsweise neu und bar
älter. Obwohl wir es jetzt ändern könnten, würde es alten Code kaputt machen, also werden wir hier behandeln, wie man zusammengesetzte Pfade erstellt und die Funktionalität in bar ersetzt, falls Sie dies aus Effizienzgründen in Ihrem eigenen Code tun müssen, z. B. Sie erstellen ein animiertes Balkendiagramm.
Wir erstellen das Histogrammdiagramm, indem wir eine Reihe von Rechtecken für jeden Histogrammbalken erstellen: Die Rechteckbreite ist die Bin-Breite und die Rechteckhöhe ist die Anzahl der Datenpunkte in diesem Bin. Zuerst erstellen wir einige zufällige normalverteilte Daten und berechnen das Histogramm. Da numpy die Behälterkanten und nicht die Mitten zurückgibt, bins
ist die Länge von im folgenden Beispiel um 1 größer als die Länge von n
:
# histogram our data with numpy
data = np.random.randn(1000)
n, bins = np.histogram(data, 100)
Wir werden jetzt die Ecken der Rechtecke extrahieren. Jedes der
left
, bottom
, usw. Arrays unten ist len(n)
, wobei n
das Array der Zählwerte für jeden Histogrammbalken ist:
Jetzt müssen wir unseren zusammengesetzten Pfad konstruieren, der aus einer Reihe von und MOVETO
für jedes Rechteck besteht. Für jedes Rechteck benötigen wir 5 Eckpunkte: 1 für das , 3 für das , und 1 für das . Wie in der obigen Tabelle angegeben, wird der Scheitelpunkt für das Closepoly ignoriert, aber wir brauchen ihn trotzdem, um die Codes an den Scheitelpunkten auszurichten:LINETO
CLOSEPOLY
MOVETO
LINETO
CLOSEPOLY
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
Alles, was bleibt, ist, den Pfad zu erstellen, ihn an eine anzuhängen
PathPatch
und zu unseren Achsen hinzuzufügen:
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()