Chemin Tutoriel #

Définir des chemins dans votre visualisation Matplotlib.

L'objet sous-jacent à tous les matplotlib.patchesobjets est le Path, qui prend en charge l'ensemble standard de commandes moveto, lineto, curveto pour dessiner des contours simples et composés constitués de segments de ligne et de splines. Le Pathest instancié avec un tableau (N, 2) de sommets (x, y) et un tableau de longueur N de codes de chemin. Par exemple pour dessiner le rectangle unitaire de (0, 0) à (1, 1), nous pourrions utiliser ce code :

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()
tutoriel de chemin

Les codes de chemin suivants sont reconnus

Code

Sommets

La description

STOP

1 (ignoré)

Un marqueur pour la fin du chemin complet (actuellement non requis et ignoré).

MOVETO

1

Prenez le stylo et déplacez-vous vers le sommet donné.

LINETO

1

Tracez une ligne de la position actuelle au sommet donné.

CURVE3

2 : 1 point de contrôle, 1 point final

Dessinez une courbe de Bézier quadratique à partir de la position actuelle, avec le point de contrôle donné, jusqu'au point final donné.

CURVE4

3 : 2 points de contrôle, 1 point final

Dessinez une courbe de Bézier cubique à partir de la position actuelle, avec les points de contrôle donnés, jusqu'au point final donné.

CLOSEPOLY

1 (le point est ignoré)

Dessinez un segment de ligne jusqu'au point de départ de la polyligne courante.

Exemple Bézier #

Certains des composants de chemin nécessitent plusieurs sommets pour les spécifier : par exemple, COURBE 3 est une courbe de Bézier avec un point de contrôle et un point final, et COURBE4 a trois sommets pour les deux points de contrôle et le point final. L'exemple ci-dessous montre une spline de Bézier COURBE4 -- la courbe de Bézier sera contenue dans l'enveloppe convexe du point de départ, des deux points de contrôle et du point 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()
tutoriel de chemin

Chemins composés #

Toutes les primitives de patch simples dans matplotlib, Rectangle, Circle, Polygon, etc., sont implémentées avec un chemin simple. Les fonctions de traçage telles que hist()et bar(), qui créent un certain nombre de primitives, par exemple un ensemble de rectangles, peuvent généralement être implémentées plus efficacement en utilisant un chemin composé. La raison pour laquelle barcrée une liste de rectangles et non un chemin composé est en grande partie historique : le Pathcode est relativement nouveau et bar antérieur. Bien que nous puissions le changer maintenant, cela casserait l'ancien code, donc ici nous verrons comment créer des chemins composés, en remplaçant la fonctionnalité dans la barre, au cas où vous auriez besoin de le faire dans votre propre code pour des raisons d'efficacité, par exemple, vous créez un graphique en barres animé.

Nous allons créer l'histogramme en créant une série de rectangles pour chaque barre d'histogramme : la largeur du rectangle est la largeur de la case et la hauteur du rectangle est le nombre de points de données dans cette case. Nous allons d'abord créer des données aléatoires normalement distribuées et calculer l'histogramme. Étant donné que numpy renvoie les bords du bac et non les centres, la longueur de binsest supérieure de 1 à la longueur de ndans l'exemple ci-dessous :

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

Nous allons maintenant extraire les coins des rectangles. Chacun des tableaux left, bottom, etc, ci-dessous est len(n), où nest le tableau des nombres pour chaque barre d'histogramme :

# 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

Nous devons maintenant construire notre chemin composé, qui consistera en une série de MOVETO, LINETOet CLOSEPOLYpour chaque rectangle. Pour chaque rectangle, nous avons besoin de 5 sommets : 1 pour le MOVETO, 3 pour le LINETOet 1 pour le CLOSEPOLY. Comme indiqué dans le tableau ci-dessus, le sommet du closepoly est ignoré mais nous en avons toujours besoin pour maintenir les codes alignés avec les sommets :

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

Il ne reste plus qu'à créer le chemin, à l'attacher à un PathPatch, et à l'ajouter à nos axes :

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()
tutoriel de chemin

Galerie générée par Sphinx-Gallery