Hinweis
Zum Ende springen, um den vollständigen Beispielcode herunterzuladen.
Text in Matplotlib#
Matplotlib bietet umfangreiche Textunterstützung, einschließlich Unterstützung für mathematische Ausdrücke, TrueType-Unterstützung für Raster- und Vektorausgaben, zeilenumbruchgetrennten Text mit beliebiger Rotation und Unicode-Unterstützung.
Da Schriften direkt in Ausgabedokumente, z. B. für PostScript oder PDF, eingebettet werden, sehen Sie auf dem Bildschirm das Gleiche wie auf dem Ausdruck. Die FreeType-Unterstützung erzeugt sehr schöne, geglättete Schriften, die auch bei kleinen Rastergrößen gut aussehen. Matplotlib enthält seinen eigenen matplotlib.font_manager (dank Paul Barrett), der einen plattformübergreifenden, W3C-konformen Algorithmus zur Schriftfinderung implementiert.
Der Benutzer hat mit sinnvollen Standardeinstellungen in der rc-Datei viel Kontrolle über Texteigenschaften (Schriftgröße, Schriftgewicht, Textposition und -farbe usw.). Und wichtig für alle, die sich für mathematische oder wissenschaftliche Grafiken interessieren: Matplotlib implementiert eine große Anzahl von TeX-Math-Symbolen und -Befehlen und unterstützt mathematische Ausdrücke überall in Ihrer Grafik.
Grundlegende Textbefehle#
Die folgenden Befehle werden zum Erstellen von Text in der impliziten und expliziten Schnittstelle verwendet (siehe Matplotlib Application Interfaces (APIs) für eine Erklärung der Kompromisse)
implizite API |
explizite API |
Beschreibung |
|---|---|---|
Fügt Text an einer beliebigen Stelle der |
||
Fügt eine Anmerkung mit einem optionalen Pfeil an einer beliebigen Stelle der |
||
Fügt eine Beschriftung zur x-Achse der |
||
Fügt eine Beschriftung zur y-Achse der |
||
Fügt einen Titel zu den |
||
Fügt Text an einer beliebigen Stelle der |
||
Fügt einen Titel zur |
Alle diese Funktionen erstellen und geben eine Text-Instanz zurück, die mit einer Vielzahl von Schrift- und anderen Eigenschaften konfiguriert werden kann. Das folgende Beispiel zeigt all diese Befehle in Aktion, und weitere Details finden Sie in den folgenden Abschnitten.
import matplotlib.pyplot as plt
import matplotlib
fig = plt.figure()
ax = fig.add_subplot()
fig.subplots_adjust(top=0.85)
# Set titles for the figure and the subplot respectively
fig.suptitle('bold figure suptitle', fontsize=14, fontweight='bold')
ax.set_title('axes title')
ax.set_xlabel('xlabel')
ax.set_ylabel('ylabel')
# Set both x- and y-axis limits to [0, 10] instead of default [0, 1]
ax.axis([0, 10, 0, 10])
ax.text(3, 8, 'boxed italics text in data coords', style='italic',
bbox={'facecolor': 'red', 'alpha': 0.5, 'pad': 10})
ax.text(2, 6, r'an equation: $E=mc^2$', fontsize=15)
ax.text(3, 2, 'Unicode: Institut für Festkörperphysik')
ax.text(0.95, 0.01, 'colored text in axes coords',
verticalalignment='bottom', horizontalalignment='right',
transform=ax.transAxes,
color='green', fontsize=15)
ax.plot([2], [1], 'o')
ax.annotate('annotate', xy=(2, 1), xytext=(3, 4),
arrowprops=dict(facecolor='black', shrink=0.05))
plt.show()

Beschriftungen für x- und y-Achse#
Das Festlegen der Beschriftungen für die x- und y-Achse ist einfach über die Methoden set_xlabel und set_ylabel möglich.
import matplotlib.pyplot as plt
import numpy as np
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1)
ax.set_xlabel('Time (s)')
ax.set_ylabel('Damped oscillation (V)')
plt.show()

Die x- und y-Beschriftungen werden automatisch so platziert, dass sie die x- und y-Tickbeschriftungen nicht verdecken. Vergleichen Sie die folgende Grafik mit der darüber und beachten Sie, dass sich die y-Beschriftung links von der oberen befindet.
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1*10000)
ax.set_xlabel('Time (s)')
ax.set_ylabel('Damped oscillation (V)')
plt.show()

Wenn Sie die Beschriftungen verschieben möchten, können Sie das Schlüsselwortargument *labelpad* angeben, wobei der Wert in Punkten angegeben wird (1/72 Zoll, die gleiche Einheit wie bei der Angabe von Schriftgrößen).
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1*10000)
ax.set_xlabel('Time (s)')
ax.set_ylabel('Damped oscillation (V)', labelpad=18)
plt.show()

Alternativ akzeptieren die Beschriftungen alle Text-Schlüsselwortargumente, einschließlich *position*, über das wir die Position der Beschriftungen manuell festlegen können. Hier platzieren wir die x-Beschriftung ganz links von der Achse. Beachten Sie, dass die y-Koordinate dieser Position keine Auswirkung hat – um die y-Position anzupassen, müssen wir das Schlüsselwortargument *labelpad* verwenden.
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1)
ax.set_xlabel('Time (s)', position=(0., 1e6), horizontalalignment='left')
ax.set_ylabel('Damped oscillation (V)')
plt.show()

Alle Beschriftungen in diesem Tutorial können durch Manipulation der Methode matplotlib.font_manager.FontProperties oder durch benannte Schlüsselwortargumente an set_xlabel geändert werden.
from matplotlib.font_manager import FontProperties
font = FontProperties(family='Times New Roman', style='italic')
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1)
ax.set_xlabel('Time (s)', fontsize='large', fontweight='bold')
ax.set_ylabel('Damped oscillation (V)', fontproperties=font)
plt.show()

Schließlich können wir native TeX-Renderings in allen Textobjekten verwenden und mehrzeilige Texte erstellen
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.2, left=0.2)
ax.plot(x1, np.cumsum(y1**2))
ax.set_xlabel('Time (s) \n This was a long experiment')
ax.set_ylabel(r'$\int\ Y^2\ dt\ \ (V^2 s)$')
plt.show()

Titel#
Unterplottitel werden ähnlich wie Beschriftungen gesetzt, aber es gibt das Schlüsselwortargument *loc*, das die Position und Ausrichtung ändern kann (der Standardwert ist "center").

Der vertikale Abstand für Titel wird über rcParams["axes.titlepad"] (Standard: 6.0) gesteuert. Das Einstellen auf einen anderen Wert verschiebt den Titel.
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(top=0.8)
ax.plot(x1, y1)
ax.set_title('Vertically offset title', pad=30)
plt.show()

Ticks und Tickbeschriftungen#
Das Platzieren von Ticks und Tickbeschriftungen ist ein sehr kniffliger Aspekt bei der Erstellung einer Grafik. Matplotlib tut sein Bestes, um die Aufgabe automatisch zu erledigen, bietet aber auch ein sehr flexibles Framework zur Bestimmung der Tickpositionen und deren Beschriftung.
Terminologie#
Achsen haben ein matplotlib.axis.Axis-Objekt für die ax.xaxis und ax.yaxis, die die Informationen über die Anordnung der Beschriftungen in der Achse enthalten.
Die Achsen-API wird im Detail in der Dokumentation zu axis erläutert.
Ein Achsenobjekt hat Haupt- und Neben-Ticks. Die Achse verfügt über die Methoden Axis.set_major_locator und Axis.set_minor_locator, die die zu plottenden Daten verwenden, um die Position von Haupt- und Neben-Ticks zu bestimmen. Es gibt auch die Methoden Axis.set_major_formatter und Axis.set_minor_formatter, die die Tickbeschriftungen formatieren.
Einfache Ticks#
Es ist oft praktisch, einfach die Tickwerte und manchmal die Tickbeschriftungen zu definieren und damit die Standard-Locator und -Formatter zu überschreiben. Dies wird jedoch nicht empfohlen, da es die interaktive Navigation des Plots unterbricht. Außerdem kann es die Achsenlimits zurücksetzen: Beachten Sie, dass die zweite Grafik die gewünschten Ticks enthält, einschließlich solcher, die weit außerhalb der automatischen Ansichtsgrenzen liegen.

Wir können dies natürlich nachträglich korrigieren, aber es unterstreicht eine Schwäche des Hardcodierens von Ticks. Dieses Beispiel ändert auch das Format der Ticks
fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
axs[0].plot(x1, y1)
axs[1].plot(x1, y1)
ticks = np.arange(0., 8.1, 2.)
# list comprehension to get all tick labels...
tickla = [f'{tick:1.2f}' for tick in ticks]
axs[1].xaxis.set_ticks(ticks)
axs[1].xaxis.set_ticklabels(tickla)
axs[1].set_xlim(axs[0].get_xlim())
plt.show()

Tick-Locator und -Formatter#
Anstatt eine Liste aller Tickbeschriftungen zu erstellen, hätten wir matplotlib.ticker.StrMethodFormatter (neuer Stil str.format() Format-String) oder matplotlib.ticker.FormatStrFormatter (alter Stil '%' Format-String) verwenden und an ax.xaxis übergeben können. Ein matplotlib.ticker.StrMethodFormatter kann auch durch Übergabe eines str erstellt werden, ohne den Formatter explizit erstellen zu müssen.

Und natürlich hätten wir einen nicht standardmäßigen Locator verwenden können, um die Tickpositionen festzulegen. Beachten Sie, dass wir immer noch die Tickwerte übergeben, aber die oben verwendete x-Limit-Korrektur ist *nicht* erforderlich.

Der Standard-Formatter ist der matplotlib.ticker.MaxNLocator, aufgerufen als ticker.MaxNLocator(self, nbins='auto', steps=[1, 2, 2.5, 5, 10]). Das Argument steps enthält eine Liste von Vielfachen, die für Tickwerte verwendet werden können. In diesem Fall wären 2, 4, 6 akzeptable Ticks, ebenso wie 20, 40, 60 oder 0,2, 0,4, 0,6. 3, 6, 9 wären jedoch nicht akzeptabel, da 3 nicht in der Liste der Schritte vorkommt.
Die Einstellung von nbins=auto verwendet einen Algorithmus, um zu bestimmen, wie viele Ticks für die Achsenlänge akzeptabel sind. Die Schriftgröße der Tickbeschriftung wird berücksichtigt, die Länge des Tick-Strings jedoch nicht (da sie noch nicht bekannt ist). In der unteren Reihe sind die Tickbeschriftungen ziemlich groß, daher setzen wir nbins=4, damit die Beschriftungen in der rechten Grafik Platz finden.
fig, axs = plt.subplots(2, 2, figsize=(8, 5), tight_layout=True)
for n, ax in enumerate(axs.flat):
ax.plot(x1*10., y1)
formatter = matplotlib.ticker.FormatStrFormatter('%1.1f')
locator = matplotlib.ticker.MaxNLocator(nbins='auto', steps=[1, 4, 10])
axs[0, 1].xaxis.set_major_locator(locator)
axs[0, 1].xaxis.set_major_formatter(formatter)
formatter = matplotlib.ticker.FormatStrFormatter('%1.5f')
locator = matplotlib.ticker.AutoLocator()
axs[1, 0].xaxis.set_major_formatter(formatter)
axs[1, 0].xaxis.set_major_locator(locator)
formatter = matplotlib.ticker.FormatStrFormatter('%1.5f')
locator = matplotlib.ticker.MaxNLocator(nbins=4)
axs[1, 1].xaxis.set_major_formatter(formatter)
axs[1, 1].xaxis.set_major_locator(locator)
plt.show()

Schließlich können wir Funktionen für den Formatter mit matplotlib.ticker.FuncFormatter angeben. Darüber hinaus wird, wie bei matplotlib.ticker.StrMethodFormatter, durch Übergabe einer Funktion automatisch ein matplotlib.ticker.FuncFormatter erstellt.
def formatoddticks(x, pos):
"""Format odd tick positions."""
if x % 2:
return f'{x:1.2f}'
else:
return ''
fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
ax.plot(x1, y1)
locator = matplotlib.ticker.MaxNLocator(nbins=6)
ax.xaxis.set_major_formatter(formatoddticks)
ax.xaxis.set_major_locator(locator)
plt.show()

Datums-Ticks#
Matplotlib kann datetime.datetime und numpy.datetime64-Objekte als Plot-Argumente akzeptieren. Daten und Zeiten erfordern eine spezielle Formatierung, die oft von manuellen Eingriffen profitieren kann. Um zu helfen, haben Daten spezielle Locator und Formatter, die im Modul matplotlib.dates definiert sind.
Das folgende einfache Beispiel veranschaulicht dieses Konzept. Beachten Sie, wie wir die Tickbeschriftungen drehen, damit sie sich nicht überlappen.
import datetime
fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
base = datetime.datetime(2017, 1, 1, 0, 0, 1)
time = [base + datetime.timedelta(days=x) for x in range(len(x1))]
ax.plot(time, y1)
ax.tick_params(axis='x', rotation=70)
plt.show()

Wir können ein Format an matplotlib.dates.DateFormatter übergeben. Wenn zwei Tickbeschriftungen sehr nah beieinander liegen, können wir die Klasse dates.DayLocator verwenden, mit der wir eine Liste von Tagen des Monats angeben können, die verwendet werden sollen. Ähnliche Formatter sind im Modul matplotlib.dates aufgeführt.
import matplotlib.dates as mdates
locator = mdates.DayLocator(bymonthday=[1, 15])
formatter = mdates.DateFormatter('%b %d')
fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)
ax.plot(time, y1)
ax.tick_params(axis='x', rotation=70)
plt.show()

Legenden und Anmerkungen#
Gesamtlaufzeit des Skripts: (0 Minuten 5,399 Sekunden)