2010-05-09 19 views
14

我想爲演示文稿生成高質量的圖表。我正在使用Python的matplotlib來生成圖形。不幸的是,PDF導出似乎忽略了我的字體設置。Matplotlib PDF導出使用錯誤的字體

我嘗試通過將FontProperties對象傳遞給文本繪圖函數並全局設置選項來設置字體。爲了記錄在案,這裏是重現該問題的MWE:

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) 

在這兩種情況下,所產生的輸出是相同的,並使用黑體(是的,我做的安裝兩種字體)。

只是可以肯定,下面並沒有幫助:

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

最後,如果我更換後端,而是採用了原生瀏覽器:

matplotlib.use('MacOSX') 

GET顯示正確的字體 - 但只在查看器GUI中顯示。 PDF輸出再次出錯。

可以肯定 - 我可以集的字體 - 但只有其他類的字體家庭:我可以設置serif字體或fantasymonospace。但是所有的無襯線字體似乎默認爲Helvetica。

回答

3

「家族」參數和相應的rc參數 並不意味着指定字體名稱 實際上可以用這種方式。有一個(可以說巴洛克式的)類似CSS的字體選擇系統,可以幫助相同的腳本在不同的計算機上工作,選擇最接近的字體。通常推薦使用的方式,例如Gill Sans將其添加到rc參數font.sans-serif(請參閱sample rc file)的值的前面,然後將font.family設置爲sans-serif。

如果字體管理器決定Gill Sans不是您的規範最接近的匹配的一些晦澀的理由,這可能會很煩人。繞過字體選擇邏輯的一種方法是使用FontProperties(fname='/path/to/font.ttf')docstring)。

就你而言,我懷疑MacOSX後端通過操作系統的機制使用字體,因此自動支持各種字體,但pdf後端有自己的字體支持代碼,不支持您的Gill Sans版本。

+0

你說,「」家庭「的參數[是]不是要指定字體的名稱」 - 抱歉,但[文檔](http://matplotlib.sourceforge.net/api/font_manager_api.html# matplotlib.font_manager.FontProperties)用不同的方式表示:「項目**可能**包含通用字體系列名稱[...]。 **在這種情況下**,將使用實際使用的字體......「(強調我的)。此外,*它在GUI中起作用。無論如何,我會嘗試你提出的解決方案。謝謝。 – 2010-05-09 14:18:00

+1

通過使用'fname = ...',在調用'savefig'時,在'embedTTFType3'中得到了backend_pdf.py行776中的RuntimeError「TrueType字體缺失表」。我不在TTF和PDF中,但是我*已經通過其他路線在PDF中嵌入了Gill Sans,所以我不確定這裏有什麼不妥。 – 2010-05-09 15:08:37

+0

你是正確的使用真正的字體名稱作爲家庭參數。錯誤消息聽起來像一個錯誤。請在Sourceforge跟蹤器中提交它,提及確切的字體,matplotlib版本和完整的回溯。 – 2010-05-09 17:43:00

8

基本上,@ Jouni的是正確的答案,但因爲我還是遇到了一些麻煩得到它的工作,這是我的最終解決方案:

#!/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') 

注意字體中有使用fontproperties關鍵要明確設置。顯然,fname屬性沒有設置rc(至少我沒有找到它)。

font的實例化中給出一個family鍵在這裏不是必須的,它將被PDF後端忽略。

此代碼僅適用於cairo後端。使用MacOSX將不起作用。