代码之家  ›  专栏  ›  技术社区  ›  Konrad Rudolph

Matplotlib PDF导出使用了错误的字体

  •  14
  • Konrad Rudolph  · 技术社区  · 15 年前

    我想为演示生成高质量的图表。我用蟒蛇的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(是的,i 安装两种字体)。

    当然,以下内容也没有帮助:

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

    最后,如果我替换后端,而不是使用本机查看器:

    matplotlib.use('MacOSX')
    

    获得正确显示的字体,但仅在查看器GUI中显示。PDF输出再次出错。

    我确信我 可以 设置其他字体,但只能设置其他类型的字体系列:我可以设置 serif 字体或 fantasy monospace . 但所有无衬线字体似乎默认为Helvetica。

    2 回复  |  直到 15 年前
        1
  •  3
  •   Jouni K. Seppänen    15 年前

    “族”参数和相应的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
  •  8
  •   Konrad Rudolph    15 年前

    基本上,@jounis是正确的答案,但由于我仍然有一些困难使它工作,下面是我的最终解决方案:

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