Matplotlib-Plots effektiv annotieren

MatplotlibMatplotlibBeginner
Jetzt üben

This tutorial is from open-source community. Access the source code

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

In diesem Lab werden Sie durch die Annotation von Diagrammen in Matplotlib geführt. Sie werden lernen, wie Sie spezifische Punkte von Interesse hervorheben und verschiedene visuelle Werkzeuge verwenden, um auf diese Punkte aufmerksam zu machen. Annotation- und Textwerkzeuge sind essentiell, um Informationen zu vermitteln und Diagramme visuell ansprechender zu gestalten.

Tipps für die VM

Nachdem der VM-Start abgeschlossen ist, klicken Sie in der oberen linken Ecke, um zur Registerkarte Notebook zu wechseln und Jupyter Notebook für die Übung zu nutzen.

Manchmal müssen Sie einige Sekunden warten, bis Jupyter Notebook vollständig geladen ist. Die Validierung von Vorgängen kann aufgrund von Einschränkungen in Jupyter Notebook nicht automatisiert werden.

Wenn Sie bei der Lernphase Probleme haben, können Sie Labby gerne fragen. Geben Sie nach der Sitzung Feedback, und wir werden das Problem für Sie prompt beheben.

Angabe von Textpunkten und Annotationspunkten

Sie müssen einen Annotationspunkt xy=(x, y) angeben, um diesen Punkt zu annotieren. Darüber hinaus können Sie für die Position des Texts für diese Annotation einen Textpunkt xytext=(x, y) angeben. Optional können Sie das Koordinatensystem von xy und xytext mit einem der folgenden Strings für xycoords und textcoords angeben (Standard ist 'data'):

  • 'figure points' : Punkte vom unteren linken Eck des Diagramms
  • 'figure pixels' : Pixel vom unteren linken Eck des Diagramms
  • 'figure fraction' : (0, 0) ist das untere linke Eck des Diagramms und (1, 1) ist das obere rechte
  • 'axes points' : Punkte vom unteren linken Eck der Achsen
  • 'axes pixels' : Pixel vom unteren linken Eck der Achsen
  • 'axes fraction' : (0, 0) ist das untere linke Eck der Achsen und (1, 1) ist das obere rechte
  • 'offset points' : Geben Sie einen Offset (in Punkten) von dem xy-Wert an
  • 'offset pixels' : Geben Sie einen Offset (in Pixeln) von dem xy-Wert an
  • 'data' : Verwenden Sie das Achsendaten-Koordinatensystem

Hinweis: Für physikalische Koordinatensysteme (Punkte oder Pixel) ist der Ursprung der (untere, linke) Rand des Diagramms oder der Achsen.

Optional können Sie Pfeilarrow-Eigenschaften angeben, die einen Pfeil von dem Text zum annotierten Punkt zeichnen, indem Sie ein Wörterbuch mit Pfeilarrow-Eigenschaften angeben. Gültige Schlüssel sind:

  • width: die Breite des Pfeils in Punkten
  • frac: der Anteil der Pfeillänge, der vom Kopf eingenommen wird
  • headwidth: die Breite der Basis des Pfeilkopfes in Punkten
  • shrink: bewegen Sie die Spitze und die Basis um einen gewissen Prozentsatz von dem annotierten Punkt und dem Text weg
  • jeder Schlüssel für matplotlib.patches.polygon (z.B. facecolor)
import matplotlib.pyplot as plt
import numpy as np

from matplotlib.patches import Ellipse
from matplotlib.text import OffsetFrom

## Erstellen Sie unser Diagramm und die Daten, die wir zum Plotten verwenden
fig, ax = plt.subplots(figsize=(4, 4))

t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)

## Plotten Sie eine Linie und fügen Sie einige einfache Annotations hinzu
line, = ax.plot(t, s)
ax.annotate('figure pixels',
            xy=(10, 10), xycoords='figure pixels')
ax.annotate('figure points',
            xy=(107, 110), xycoords='figure points',
            fontsize=12)
ax.annotate('figure fraction',
            xy=(.025,.975), xycoords='figure fraction',
            horizontalalignment='left', verticalalignment='top',
            fontsize=20)

## Die folgenden Beispiele zeigen, wie diese Pfeile gezeichnet werden.

ax.annotate('point offset from data',
            xy=(3, 1), xycoords='data',
            xytext=(-10, 90), textcoords='offset points',
            arrowprops=dict(facecolor='black', shrink=0.05),
            horizontalalignment='center', verticalalignment='bottom')

ax.annotate('axes fraction',
            xy=(2, 1), xycoords='data',
            xytext=(0.36, 0.68), textcoords='axes fraction',
            arrowprops=dict(facecolor='black', shrink=0.05),
            horizontalalignment='right', verticalalignment='top')

## Sie können auch negative Punkte oder Pixel verwenden, um von (rechts, oben) anzugeben.
## Beispielsweise ist (-10, 10) 10 Punkte links von der rechten Seite der Achsen und 10
## Punkte über der unteren Seite

ax.annotate('pixel offset from axes fraction',
            xy=(1, 0), xycoords='axes fraction',
            xytext=(-20, 20), textcoords='offset pixels',
            horizontalalignment='right',
            verticalalignment='bottom')

ax.set(xlim=(-1, 5), ylim=(-3, 5))

Verwendung mehrerer Koordinatensysteme und Achsenarten

Sie können die xypoint und das xytext an verschiedenen Positionen und in verschiedenen Koordinatensystemen angeben und optional eine verbindende Linie aktivieren und den Punkt mit einem Marker markieren. Annotations funktionieren auch auf polaren Achsen.

fig, ax = plt.subplots(subplot_kw=dict(projection='polar'), figsize=(3, 3))
r = np.arange(0, 1, 0.001)
theta = 2*2*np.pi*r
line, = ax.plot(theta, r)

ind = 800
thisr, thistheta = r[ind], theta[ind]
ax.plot([thistheta], [thisr], 'o')
ax.annotate('a polar annotation',
            xy=(thistheta, thisr),  ## theta, radius
            xytext=(0.05, 0.05),    ## fraction, fraction
            textcoords='figure fraction',
            arrowprops=dict(facecolor='black', shrink=0.05),
            horizontalalignment='left',
            verticalalignment='bottom')

Anpassen von Pfeil- und Blasenstilen

Der Pfeil zwischen xytext und dem Annotationspunkt sowie die Blase, die den Annotationstext umschließt, sind hoch anpassbar. Im Folgenden sind einige Parameteroptionen sowie deren resultierender Output aufgeführt.

fig, ax = plt.subplots(figsize=(8, 5))

t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = ax.plot(t, s, lw=3)

ax.annotate(
   'straight',
    xy=(0, 1), xycoords='data',
    xytext=(-50, 30), textcoords='offset points',
    arrowprops=dict(arrowstyle="->"))
ax.annotate(
    'arc3,\nrad 0.2',
    xy=(0.5, -1), xycoords='data',
    xytext=(-80, -60), textcoords='offset points',
    arrowprops=dict(arrowstyle="->",
                    connectionstyle="arc3,rad=.2"))
ax.annotate(
    'arc,\nangle 50',
    xy=(1., 1), xycoords='data',
    xytext=(-90, 50), textcoords='offset points',
    arrowprops=dict(arrowstyle="->",
                    connectionstyle="arc,angleA=0,armA=50,rad=10"))
ax.annotate(
    'arc,\narms',
    xy=(1.5, -1), xycoords='data',
    xytext=(-80, -60), textcoords='offset points',
    arrowprops=dict(
        arrowstyle="->",
        connectionstyle="arc,angleA=0,armA=40,angleB=-90,armB=30,rad=7"))
ax.annotate(
    'angle,\nangle 90',
    xy=(2., 1), xycoords='data',
    xytext=(-70, 30), textcoords='offset points',
    arrowprops=dict(arrowstyle="->",
                    connectionstyle="angle,angleA=0,angleB=90,rad=10"))
ax.annotate(
    'angle3,\nangle -90',
    xy=(2.5, -1), xycoords='data',
    xytext=(-80, -60), textcoords='offset points',
    arrowprops=dict(arrowstyle="->",
                    connectionstyle="angle3,angleA=0,angleB=-90"))
ax.annotate(
    'angle,\nround',
    xy=(3., 1), xycoords='data',
    xytext=(-60, 30), textcoords='offset points',
    bbox=dict(boxstyle="round", fc="0.8"),
    arrowprops=dict(arrowstyle="->",
                    connectionstyle="angle,angleA=0,angleB=90,rad=10"))
ax.annotate(
    'angle,\nround4',
    xy=(3.5, -1), xycoords='data',
    xytext=(-70, -80), textcoords='offset points',
    size=20,
    bbox=dict(boxstyle="round4,pad=.5", fc="0.8"),
    arrowprops=dict(arrowstyle="->",
                    connectionstyle="angle,angleA=0,angleB=-90,rad=10"))
ax.annotate(
    'angle,\nshrink',
    xy=(4., 1), xycoords='data',
    xytext=(-60, 30), textcoords='offset points',
    bbox=dict(boxstyle="round", fc="0.8"),
    arrowprops=dict(arrowstyle="->",
                    shrinkA=0, shrinkB=10,
                    connectionstyle="angle,angleA=0,angleB=90,rad=10"))
## Sie können einen leeren String übergeben, um nur die Annotationspfeile zu rendern
ax.annotate('', xy=(4., 1.), xycoords='data',
            xytext=(4.5, -1), textcoords='data',
            arrowprops=dict(arrowstyle="<->",
                            connectionstyle="bar",
                            ec="k",
                            shrinkA=5, shrinkB=5))

ax.set(xlim=(-1, 5), ylim=(-4, 3))

Weitere Beispiele für Koordinatensysteme

Im Folgenden werden wir einige weitere Beispiele für Koordinatensysteme zeigen und wie die Position von Annotations angegeben werden kann.

fig, (ax1, ax2) = plt.subplots(1, 2)

bbox_args = dict(boxstyle="round", fc="0.8")
arrow_args = dict(arrowstyle="->")

## Hier werden wir die Ausdehnungen des Koordinatensystems und wie
## wir annotierenden Text platzieren, demonstrieren.

ax1.annotate('figure fraction : 0, 0', xy=(0, 0), xycoords='figure fraction',
             xytext=(20, 20), textcoords='offset points',
             ha="left", va="bottom",
             bbox=bbox_args,
             arrowprops=arrow_args)

ax1.annotate('figure fraction : 1, 1', xy=(1, 1), xycoords='figure fraction',
             xytext=(-20, -20), textcoords='offset points',
             ha="right", va="top",
             bbox=bbox_args,
             arrowprops=arrow_args)

ax1.annotate('axes fraction : 0, 0', xy=(0, 0), xycoords='axes fraction',
             xytext=(20, 20), textcoords='offset points',
             ha="left", va="bottom",
             bbox=bbox_args,
             arrowprops=arrow_args)

ax1.annotate('axes fraction : 1, 1', xy=(1, 1), xycoords='axes fraction',
             xytext=(-20, -20), textcoords='offset points',
             ha="right", va="top",
             bbox=bbox_args,
             arrowprops=arrow_args)

## Es ist auch möglich, ziehbare Annotations zu generieren

an1 = ax1.annotate('Drag me 1', xy=(.5,.7), xycoords='data',
                   ha="center", va="center",
                   bbox=bbox_args)

an2 = ax1.annotate('Drag me 2', xy=(.5,.5), xycoords=an1,
                   xytext=(.5,.3), textcoords='axes fraction',
                   ha="center", va="center",
                   bbox=bbox_args,
                   arrowprops=dict(patchB=an1.get_bbox_patch(),
                                   connectionstyle="arc3,rad=0.2",
                                   **arrow_args))
an1.draggable()
an2.draggable()

an3 = ax1.annotate('', xy=(.5,.5), xycoords=an2,
                   xytext=(.5,.5), textcoords=an1,
                   ha="center", va="center",
                   bbox=bbox_args,
                   arrowprops=dict(patchA=an1.get_bbox_patch(),
                                   patchB=an2.get_bbox_patch(),
                                   connectionstyle="arc3,rad=0.2",
                                   **arrow_args))

## Schließlich werden wir einige komplexere Annotation und Platzierung zeigen

text = ax2.annotate('xy=(0, 1)\nxycoords=("data", "axes fraction")',
                    xy=(0, 1), xycoords=("data", 'axes fraction'),
                    xytext=(0, -20), textcoords='offset points',
                    ha="center", va="top",
                    bbox=bbox_args,
                    arrowprops=arrow_args)

ax2.annotate('xy=(0.5, 0)\nxycoords=artist',
             xy=(0.5, 0.), xycoords=text,
             xytext=(0, -20), textcoords='offset points',
             ha="center", va="top",
             bbox=bbox_args,
             arrowprops=arrow_args)

ax2.annotate('xy=(0.8, 0.5)\nxycoords=ax1.transData',
             xy=(0.8, 0.5), xycoords=ax1.transData,
             xytext=(10, 10),
             textcoords=OffsetFrom(ax2.bbox, (0, 0), "points"),
             ha="left", va="bottom",
             bbox=bbox_args,
             arrowprops=arrow_args)

ax2.set(xlim=[-2, 2], ylim=[-2, 2])

Zusammenfassung

In diesem Lab wurden die Grundlagen der Annotation von Plots in Matplotlib behandelt. Sie haben gelernt, wie Annotations- und Textpunkte angegeben werden, wie mehrere Koordinatensysteme und Achsenarten verwendet werden, wie Pfeil- und Blasenstile angepasst werden und weitere Beispiele für Koordinatensysteme. Diese Tools sind essentiell, um Plots visuell ansprechender zu gestalten und Informationen effektiv zu vermitteln.