16

我想为演示文稿生成高质量的图表。我正在使用 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字体或fantasymonospace。但所有无衬线字体似乎都默认为 Helvetica。

4

3 回答 3

8

基本上,@Jouni's 是正确的答案,但由于我仍然无法让它工作,这是我的最终解决方案:

#!/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将不起作用。

于 2010-05-09T18:53:45.613 回答
3

"family" 参数和相应的 rc 参数并不意味着指定字体的名称,实际上可以这样使用。有一个(可以说是巴洛克式的)类似 CSS 的字体选择系统,可以帮助相同的脚本在不同的计算机上工作,选择最接近的可用字体。通常推荐使用 Gill Sans 的方法是将其添加到 rc 参数 font.sans-serif 的值的前面(参见示例 rc 文件),然后将 font.family 设置为 sans-serif。

如果字体管理器出于某种晦涩的原因决定 Gill Sans 不是最符合您的规范的匹配项,这可能会很烦人。绕过字体选择逻辑的一种方法是使用FontProperties(fname='/path/to/font.ttf')( docstring )。

在您的情况下,我怀疑 MacOSX 后端通过操作系统机制使用字体,因此自动支持各种字体,但 pdf 后端有自己的字体支持代码,不支持您的 Gill Sans 版本。

于 2010-05-09T13:45:33.510 回答
0

如果您来这里是为了非开罗后端,这是对上述答案的补充。

matplotlib 的 pdf-backend 还不支持真正的字体集合(保存为 .ttc 文件)。看到这个问题

当前建议的解决方法是从 .ttc 文件中提取感兴趣的字体并将其保存为 .ttf 文件。然后按照 Konrad Rudolph 描述的方式使用该字体。

您可以使用 python-package fonttools来实现这一点:

font = TTFont("/System/Library/Fonts/Helvetica.ttc", fontNumber=0)
font.save("Helvetica-regular.ttf")

.ttf据我所知,通过将这个新文件的路径传递给rc来使这个设置“全局”是不可能的。如果您真的很绝望,您可以尝试将 a 中的所有字体提取.ttc到单独.ttf的文件中,卸载.ttc并单独安装ttfs。要将提取的字体与 中的原始字体并排放置.ttc,您需要使用FontForge等工具更改字体名称。不过,我还没有测试过。

于 2020-05-11T17:22:40.743 回答