Schriftarten in Matplotlib #
Matplotlib benötigt Schriftarten, um mit seiner Text-Engine zu arbeiten, von denen einige zusammen mit der Installation ausgeliefert werden. Die Standardschriftart ist DejaVu Sans , die die meisten europäischen Schriftsysteme abdeckt. Benutzer können jedoch die Standardschriftarten konfigurieren und ihre eigenen benutzerdefinierten Schriftarten bereitstellen. Siehe Anpassen von Texteigenschaften für Details und Text mit nicht-lateinischen Glyphen , insbesondere für Glyphen, die nicht von DejaVu Sans unterstützt werden.
Matplotlib bietet auch eine Option zum Auslagern von Textrendering an eine TeX-Engine ( usetex=True
), siehe Textrendering mit LaTeX .
Schriftarten in PDF und PostScript #
Schriftarten haben eine lange (und manchmal inkompatible) Geschichte in der Computertechnik, was dazu führt, dass verschiedene Plattformen unterschiedliche Arten von Schriftarten unterstützen. In der Praxis gibt es 3 Arten von Schriftartspezifikationen, die Matplotlib unterstützt (zusätzlich zu den „Kernschriften“ in PDF, die später im Handbuch erläutert werden):
Typ 1 (PDF) |
Typ 3 (PDF/PS) |
TrueType (PDF) |
---|---|---|
Einer der ältesten Typen, eingeführt von Adobe |
Ähnlich wie Typ 1 in Bezug auf die Einführung |
Neuer als frühere Typen, die heute häufig verwendet werden und von Apple eingeführt wurden |
Eingeschränkte Teilmenge von PostScript, Zeichenketten sind in Bytecode |
Vollständige PostScript-Sprache, ermöglicht das Einbetten von beliebigem Code (theoretisch sogar Fraktale beim Rastern rendern!) |
Fügen Sie eine virtuelle Maschine hinzu, die Code ausführen kann! |
Diese Schriftarten unterstützen Schriftarthinweise |
Schrifthinweise werden nicht unterstützt |
Hinweis unterstützt (virtuelle Maschine verarbeitet die "Hinweise") |
Nicht untergliedert durch Matplotlib |
Subset über externes Modul ttconv |
Subset über externes Modul Fonttools |
HINWEIS: Adobe wird die Unterstützung für das Authoring mit Typ-1-Schriftarten im Januar 2023 deaktivieren. Lesen Sie hier mehr.
Andere Schriftartspezifikationen, die Matplotlib unterstützt:
Typ 42 Schriftarten (PS):
PostScript-Wrapper um TrueType-Schriftarten
Matplotlib verwendet eine externe Bibliothek namens Fonttools , um diese Schriftarten zu unterteilen
OpenType-Schriftarten:
OpenType ist ein neuer Standard für digitale Schriftarten, der gemeinsam von Adobe und Microsoft entwickelt wurde
enthalten im Allgemeinen einen viel größeren Zeichensatz!
Eingeschränkte Unterstützung mit Matplotlib
Schriftart-Untereinstellung #
Die Formate PDF und PostScript unterstützen das Einbetten von Schriftarten in Dateien, sodass das Anzeigeprogramm den Text korrekt wiedergeben kann, unabhängig davon, welche Schriftarten auf dem Computer des Betrachters installiert sind, und ohne dass der Text vorab gerastert werden muss. Dadurch wird sichergestellt, dass der Text nicht verpixelt wird, wenn die Ausgabe gezoomt oder in der Größe geändert wird. Das Einbetten vollständiger Schriftarten in die Datei kann jedoch zu großen Ausgabedateien führen, insbesondere bei Schriftarten mit vielen Glyphen, wie z. B. solchen, die CJK (Chinesisch/Japanisch/Koreanisch) unterstützen.
Die Lösung für dieses Problem besteht darin, die im Dokument verwendeten Schriftarten zu unterteilen und nur die tatsächlich verwendeten Glyphen einzubetten. Dies erhält sowohl Vektortext als auch kleine Dateigrößen. Das Berechnen der Teilmenge der erforderlichen Schriftart und das Schreiben der neuen (reduzierten) Schriftart sind beide ein komplexes Problem, und daher verlässt sich Matplotlib auf fontTools und einen von einem Anbieter angebotenen Fork von ttconv .
Derzeit sind Typ 3-, Typ 42- und TrueType-Schriftarten Teilsätze. Type 1-Fonts sind es nicht.
Core-Schriftarten #
Neben der Möglichkeit, Schriftarten einzubetten, gibt es als Teil der PostScript- und PDF-Spezifikation 14 Core-Schriftarten, die konforme Betrachter sicherstellen müssen, dass sie verfügbar sind. Wenn Sie Ihr Dokument nur auf diese Schriftarten beschränken, müssen Sie keine Schriftartinformationen in das Dokument einbetten, erhalten aber trotzdem Vektortext.
Dies ist besonders hilfreich, um wirklich leichte Dokumente zu erstellen.:
# trigger core fonts for PDF backend
plt.rcParams["pdf.use14corefonts"] = True
# trigger core fonts for PS backend
plt.rcParams["ps.useafm"] = True
chars = "AFM ftw!"
fig, ax = plt.subplots()
ax.text(0.5, 0.5, chars)
fig.savefig("AFM_PDF.pdf", format="pdf")
fig.savefig("AFM_PS.ps", format="ps)
Schriftarten in SVG #
Text kann auf zwei Arten in SVG ausgegeben werden, gesteuert durch rcParams["svg.fonttype"]
(Standard: 'path'
):
als Pfad (
'path'
) in der SVGals String im SVG mit Schriftstil auf dem Element (
'none'
)
Beim Speichern über 'path'
Matplotlib wird der Pfad der als Vektorpfade verwendeten Glyphen berechnet und in die Ausgabe geschrieben. Dies hat den Vorteil, dass das SVG auf allen Computern gleich aussieht, unabhängig davon, welche Schriftarten installiert sind. Der Text kann jedoch nachträglich nicht bearbeitet werden. Im Gegensatz dazu führt das Speichern mit 'none'
zu kleineren Dateien und der Text erscheint direkt im Markup. Das Erscheinungsbild kann jedoch je nach SVG-Viewer und den verfügbaren Schriftarten variieren.
Schriftarten in Agg #
Um Text über Agg in Rasterformate auszugeben, setzt Matplotlib auf FreeType . Da sich die genaue Wiedergabe der Glyphen zwischen FreeType-Versionen ändert, heften wir für unsere Bildvergleichstests an eine bestimmte Version.
Wie Matplotlib Schriftarten auswählt #
Die interne Verwendung einer Schriftart in Matplotlib ist ein dreistufiger Prozess:
ein
FontProperties
Objekt wird erstellt (explizit oder implizit)Basierend auf dem
FontProperties
Objekt, auf dem die MethodenFontManager
verwendet werden, wird die nächstgelegene "beste" Schriftart ausgewählt, die Matplotlib kennt (mit Ausnahme'none'
des SVG-Modus).Der Python-Proxy für das Schriftobjekt wird vom Backend-Code verwendet, um den Text zu rendern – die genauen Details hängen vom Backend über ab
font_manager.get_font
.
Der Algorithmus zur Auswahl der "besten" Schriftart ist eine modifizierte Version des Algorithmus, der von den CSS1-Spezifikationen angegeben wird, die von Webbrowsern verwendet werden. Dieser Algorithmus berücksichtigt den Namen der Schriftfamilie (z. B. "Arial", "Noto Sans CJK", "Hack", ...), die Größe, den Stil und die Stärke. Zusätzlich zu den Familiennamen, die direkt Schriften zugeordnet werden, gibt es fünf "generische Schriftfamiliennamen" (Serif, Monospace, Fantasy, Cursive und Sans-Serif), die intern einer Gruppe von Schriften zugeordnet werden.
Derzeit ist die öffentliche API für Schritt 2 FontManager.findfont
(und diese Methode auf der globalen FontManager
Instanz hat auf Modulebene den Aliasnamen
font_manager.findfont
), die nur eine einzige Schriftart findet und den absoluten Pfad zur Schriftart im Dateisystem zurückgibt.
Font-Fallback #
Es gibt keine Schriftart, die den gesamten Unicode-Bereich abdeckt, daher ist es möglich, dass die Benutzer eine Mischung von Glyphen benötigen, die von einer einzelnen Schriftart nicht erfüllt werden kann. Während es möglich war, mehrere Schriftarten innerhalb einer Figur zu verwenden,
Text
war es bisher nicht möglich, mehrere Schriftarten in derselben Text
Instanz zu verwenden (wie es ein Webbrowser tut). Ab Matplotlib 3.6 "fallen" die Agg-, SVG-, PDF- und PS-Backends durch mehrere Schriftarten in einer einzigen
Text
Instanz:
fig, ax = plt.subplots()
ax.text(
.5, .5, "There are 几个汉字 in between!",
family=['DejaVu Sans', 'WenQuanYi Zen Hei'],
ha='center'
)
Intern wird dies implementiert, indem die "Schriftfamilie" von
FontProperties
Objekten auf eine Liste von Schriftfamilien gesetzt wird. Eine (derzeit) private API extrahiert eine Liste mit Pfaden zu allen gefundenen Schriftarten und erstellt dann ein einzelnes ft2font.FT2Font
Objekt, das alle Schriftarten kennt. Jede Glyphe der Zeichenfolge wird mit der ersten Schriftart in der Liste gerendert, die diese Glyphe enthält.
Ein Großteil dieser Arbeit wurde von Aitik Gupta durchgeführt, unterstützt von Google Summer of Code 2021.