我想为演示文稿生成高质量的图表。我正在使用Python的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)
在这两种情况下,生成的输出都是相同的并使用Helvetica(是的,我做安装了两种字体)。
可以肯定的是,以下内容也无济于事:
matplotlib.rc('font', family = 'Gill Sans')
最后,如果我替换后端,而是使用本机查看器:
matplotlib.use('MacOSX')
我做显示正确的字体 - 但仅限于查看器GUI。 PDF输出再次出错。
可以肯定 - 我可以设置其他字体 - 但只能设置其他类型的字体系列:我可以设置serif
字体或fantasy
或monospace
。但是所有sans-serif字体似乎都默认为Helvetica。
答案 0 :(得分: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
键明确设置字体。显然,rc
属性没有fname
设置(至少我没有找到它)。
在family
的实例化中给出font
密钥在这里并不是绝对必要的,它将被PDF后端忽略。
此代码仅适用于cairo
后端。使用MacOSX
将无效。
答案 1 :(得分:3)
“family”参数和相应的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版本。
答案 2 :(得分:0)
如果您是来这里访问非开罗后端的,这是对以上答案的补充。
matplotlib的pdf后端尚不支持真实类型的字体集合(另存为.ttc文件)。参见this issue。
当前建议的解决方法是从.ttc文件中提取感兴趣的字体并将其保存为.ttf文件。然后以Konrad Rudolph所描述的方式使用该字体。
您可以使用python-package fonttools实现此目的:
font = TTFont("/System/Library/Fonts/Helvetica.ttc", fontNumber=0)
font.save("Helvetica-regular.ttf")
据我所知,不可能通过将此新.ttf
文件的路径传递到rc来使此设置为“全局”。如果您真的很绝望,则可以尝试将.ttc
中的所有字体提取到单独的.ttf
文件中,卸载.ttc
并分别安装ttf
。要使提取的字体与.ttc
中的原始字体并排放置,您需要使用FontForge之类的工具来更改字体名称。我还没有测试过。