2010-05-09 11 views
14

Ich möchte qualitativ hochwertige Diagramme für eine Präsentation erstellen. Ich verwende Pythons Matplotlib, um die Grafiken zu generieren. Leider scheint der PDF-Export meine Schrifteinstellungen zu ignorieren.Matplotlib PDF-Export verwendet falsche Schriftart

Ich habe versucht, die Schriftart sowohl durch die Übergabe eines Objekts FontProperties an die Textzeichnungsfunktionen und durch die globale Einstellung der Option. Für die Aufzeichnung hier ein MWE ist, das Problem zu reproduzieren:

import scipy 
import matplotlib 
matplotlib.use('cairo') 
import matplotlib.pylab as pylab 
import matplotlib.font_manager as fm 

data = scipy.arange(5) 

for font in ['Helvetica', 'Gill Sans']: 
    fig = pylab.figure() 
    ax = fig.add_subplot(111) 
    ax.bar(data, data) 
    ax.set_xticks(data) 
    ax.set_xticklabels(data, fontproperties = fm.FontProperties(family = font)) 
    pylab.savefig('foo-%s.pdf' % font) 

In beiden Fällen ist die erzeugte Ausgabe ist identisch und verwendet Helvetica (und ja, ich beide Schriften installiert tun haben).

Nur um sicherzugehen, wird die folgende nicht helfen, entweder:

matplotlib.rc('font', family = 'Gill Sans') 

Schließlich, wenn ich das Backend ersetzen, anstatt die native Viewer:

matplotlib.use('MacOSX') 

I Bekomme die richtige Schriftart angezeigt - aber nur in der Viewer-GUI. Die PDF-Ausgabe ist wieder falsch.

Um sicher zu sein - ich kann gesetzt andere Schriftarten - aber nur andere Klassen von Schriftfamilien: Ich serif Schriftarten oder fantasy oder monospace einstellen. Aber alle Sans-Serif-Fonts scheinen auf Helvetica zurückzugreifen.

Antwort

3

Das "family" -Argument und der entsprechende rc-Parameter sind nicht dazu gedacht, den Namen der Schriftart anzugeben, die tatsächlich auf diese Weise verwendet werden kann. Es gibt ein (wohl barockes) CSS-ähnliches Auswahlsystem für Schriftarten, mit dem das gleiche Skript auf verschiedenen Computern ausgeführt werden kann, wobei die engste verfügbare Schriftart ausgewählt wird. Die normalerweise empfohlene Art, z.B. Gill Sans soll es an den Anfang des Werts des RC-Parameters font.sans-serif (siehe sample rc file) hinzufügen und dann font.family auf sans-serif setzen.

Dies kann ärgerlich sein, wenn der Font-Manager aus einem obskuren Grund entscheidet, dass Gill Sans Ihrer Spezifikation nicht am nächsten kommt. Eine Möglichkeit, die Schriftartauswahllogik zu umgehen, ist die Verwendung von FontProperties(fname='/path/to/font.ttf') (docstring).

In meinem Fall vermute ich, dass das MacOSX-Backend Schriftarten über die Mechanismen des Betriebssystems verwendet und automatisch alle Arten von Schriftarten unterstützt, aber das PDF-Backend hat seinen eigenen Font-Support-Code, der Ihre Version von Gill Sans nicht unterstützt . Grundsätzlich

+0

Sie sagte: „Die‚Familie‘Argument [ist] nicht den Namen der Schriftart angeben gemeint“ - sorry, aber [die Dokumentation] (http://matplotlib.sourceforge.net/api/font_manager_api.html# matplotlib.font_manager.FontProperties) sagt anders: "Die Items ** können ** einen generischen Font-Familiennamen enthalten [...]. ** In diesem Fall ** wird die zu verwendende Schriftart nachgeschlagen ... "(Hervorhebung von mir). Außerdem * funktioniert es * in der GUI. Wie auch immer, ich werde Ihre vorgeschlagenen Lösungen versuchen. Vielen Dank. –

+1

Mit 'fname = ...' bekomme ich in Zeile 776 von backend_pdf.py in 'embedTTFType3' einen RuntimeError" TrueType-Font fehlt Tabelle "beim Aufruf von' savefig'. Ich bin nicht zu Hause mit TTF und PDF, aber ich habe Gill Sans bereits in PDFs über andere Routen eingebettet, so dass ich mir nicht sicher bin, was hier falsch ist. –

+0

Sie haben Recht, echte Schriftnamen als Familienargumente zu verwenden. Die Fehlermeldung klingt wie ein Fehler. Bitte füge es beim Sourceforge-Tracker ein und erwähne die genaue Schriftart, die matplotlib-Version und das vollständige Traceback. –

8

, @ Jouni ist die richtige Antwort ist, aber da ich noch einige Probleme hatte immer daran zu arbeiten, hier ist meine letzte Lösung:

#!/usr/bin/env python2.6 

import scipy 
import matplotlib 
matplotlib.use('cairo') 
import matplotlib.pylab as pylab 
import matplotlib.font_manager as fm 

font = fm.FontProperties(
     family = 'Gill Sans', fname = '/Library/Fonts/GillSans.ttc') 

data = scipy.arange(5) 
fig = pylab.figure() 
ax = fig.add_subplot(111) 
ax.bar(data, data) 
ax.set_yticklabels(ax.get_yticks(), fontproperties = font) 
ax.set_xticklabels(ax.get_xticks(), fontproperties = font) 
pylab.savefig('foo.pdf') 

Beachten Sie, dass die Schriftart gesetzt werden muss explizit mit den fontproperties Schlüsseln. Offenbar gibt es keine rc Einstellung für die fname Eigenschaft (zumindest habe ich es nicht gefunden).

Geben Sie einen family Schlüssel in der Instantiierung von font ist hier nicht unbedingt erforderlich, wird es vom PDF-Back-End ignoriert.

Dieser Code funktioniert nur mit dem Backend cairo. Die Verwendung von MacOSX funktioniert nicht.

Verwandte Themen