Pfad-Tutorial #

Pfade in Ihrer Matplotlib-Visualisierung definieren.

Das Objekt, das allen matplotlib.patchesObjekten 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 Pathwird 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()
Pfad-Tutorial

Die folgenden Pfadcodes werden erkannt

Code

Eckpunkte

Beschreibung

STOP

1 (ignoriert)

Eine Markierung für das Ende des gesamten Pfads (derzeit nicht erforderlich und ignoriert).

MOVETO

1

Nehmen Sie den Stift und bewegen Sie sich zum angegebenen Scheitelpunkt.

LINETO

1

Zeichnen Sie eine Linie von der aktuellen Position zum angegebenen Scheitelpunkt.

CURVE3

2: 1 Kontrollpunkt, 1 Endpunkt

Zeichnen Sie eine quadratische Bézier-Kurve von der aktuellen Position mit dem angegebenen Kontrollpunkt bis zum angegebenen Endpunkt.

CURVE4

3: 2 Kontrollpunkte, 1 Endpunkt

Zeichnen Sie eine kubische Bézier-Kurve von der aktuellen Position mit den angegebenen Kontrollpunkten bis zum angegebenen Endpunkt.

CLOSEPOLY

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()
Pfad-Tutorial

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 bareine Liste von Rechtecken und kein zusammengesetzter Pfad erstellt wird, ist weitgehend historisch: Der PathCode 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, binsist 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 ndas Array der Zählwerte für jeden Histogrammbalken ist:

# 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

Jetzt müssen wir unseren zusammengesetzten Pfad konstruieren, der aus einer Reihe von und MOVETOfü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:LINETOCLOSEPOLYMOVETOLINETOCLOSEPOLY

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 PathPatchund 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()
Pfad-Tutorial

Galerie generiert von Sphinx-Gallery