【问题标题】:How can I fix matplotlib detecting wrong font weights?如何修复 matplotlib 检测到错误的字体粗细?
【发布时间】:2018-08-25 03:07:19
【问题描述】:

我从 Google 字体 下载了我想用于我的论文和所有绘图的字体,即 Alegreya 字体系列。将字体安装到 $HOME/.fonts 后,我删除了 .cache/matplotlib/fontList.cache 并在 rcParams 中使用新的 font.family = 'Alegreya Sans' 创建了一个绘图。不幸的是,matplotlib 将 Alegreya Sans 的 Thin 字体检测为 Regular 字体。以下最小示例说明了错误检测:

import matplotlib.font_manager

weights = ['ultralight', 'light', 'normal', 'regular', 'book', 'medium', 
           'roman', 'semibold', 'demibold', 'demi', 'bold', 'heavy', 
           'extra bold', 'black']

print 'weight'+6*' ', 'file name', '\n'+70*'-'
for weight in weights:
    fprops = matplotlib.font_manager.FontProperties(family='Alegreya Sans', 
                                                    weight=weight)
    print weight+(12-len(weight))*' ', matplotlib.font_manager.findfont(fprops)

输出:

weight       file name 
----------------------------------------------------------------------
ultralight   /hmi/kme/.fonts/Alegreya_Sans/AlegreyaSans-Light.ttf
light        /hmi/kme/.fonts/Alegreya_Sans/AlegreyaSans-Light.ttf
normal       /hmi/kme/.fonts/Alegreya_Sans/AlegreyaSans-Thin.ttf
regular      /hmi/kme/.fonts/Alegreya_Sans/AlegreyaSans-Thin.ttf
book         /hmi/kme/.fonts/Alegreya_Sans/AlegreyaSans-Thin.ttf
medium       /hmi/kme/.fonts/Alegreya_Sans/AlegreyaSans-Medium.ttf
roman        /hmi/kme/.fonts/Alegreya_Sans/AlegreyaSans-Medium.ttf
semibold     /hmi/kme/.fonts/Alegreya_Sans/AlegreyaSans-ExtraBold.ttf
demibold     /hmi/kme/.fonts/Alegreya_Sans/AlegreyaSans-ExtraBold.ttf
demi         /hmi/kme/.fonts/Alegreya_Sans/AlegreyaSans-ExtraBold.ttf
bold         /hmi/kme/.fonts/Alegreya_Sans/AlegreyaSans-ExtraBold.ttf
heavy        /hmi/kme/.fonts/Alegreya_Sans/AlegreyaSans-ExtraBold.ttf
extra bold   /hmi/kme/.fonts/Alegreya_Sans/AlegreyaSans-ExtraBold.ttf
black        /hmi/kme/.fonts/Alegreya_Sans/AlegreyaSans-Black.ttf

如何解决这个问题?为什么会这样?提前致谢!

编辑:

当然,文件夹/hmi/kme/.fonts/Alegreya_Sans/里还有更多文件

完整列表

  • AlegreyaSans-BlackItalic.ttf
  • AlegreyaSans-BoldItalic.ttf
  • AlegreyaSans-ExtraBoldItalic.ttf
  • AlegreyaSans-Italic.ttf
  • AlegreyaSans-Light.ttf
  • AlegreyaSans-Medium.ttf
  • AlegreyaSans-ThinItalic.ttf
  • AlegreyaSans-Black.ttf
  • AlegreyaSans-Bold.ttf
  • AlegreyaSans-ExtraBold.ttf
  • AlegreyaSans-LightItalic.ttf
  • AlegreyaSans-MediumItalic.ttf
  • AlegreyaSans-Regular.ttf
  • AlegreyaSans-Thin.ttf

我的系统

  • OpenSuse 13.1
  • python 2.7
  • matplotlib 1.4.3 版

【问题讨论】:

  • 使用相同版本的 matplotlib 和 python,但在 mac (10.10.5) 上,我得到不同的结果。你得到AlegreyaSans-Thin.ttf,我得到AlegreyaSans-Regular.ttf,你得到AlegreyaSans-ExtraBold.ttf,我得到AlegreyaSans-Bold.ttf。其他一切都是一样的。不确定这是否有帮助,但它至少添加了一个数据点!
  • 嗯,实际上,这很奇怪。如果字体直接在$HOME/.fonts 中,我在上面评论中的结果是正确的。如果我将它们移动到子目录$HOME/.fonts/Alegreya_Sans,就像你一样,我会得到和你一样的结果
  • @tom 这听起来很奇怪。怎么会这样?我想知道 matplotlib 使用什么来检测字体粗细。显然他们没有解析文件名:) 遗憾的是我不理解 fontList.cache 中的语法,所以即使手动修复也无法完成。还有什么想法吗?
  • @tom 我现在使用 .fonts 中没有子目录的所有 .ttf 文件检查了它。这更奇怪:我现在得到与你相同的输出,即 Thin 替换为 Regular 等等,但它仍然使用输出 pdf 中的 Thin-font。任何帮助表示赞赏。
  • 您是否再次清除字体缓存?抱歉,我不太了解 font_manager 是如何工作的,但希望很快会有更多知识渊博的人出现 :)

标签: python-2.7 matplotlib


【解决方案1】:

我通过变通方法手动修复了该问题。无论如何,这似乎是一个错误。正如汤姆所说,我将所有字体复制到 $HOME/.fonts 没有子目录。这改变了我在问题中给出的脚本的输出。为了找出问题所在,我尝试按以下方式打印 Alegreya 和 Alegreya Sans 的 weightstyle 的所有组合:

import matplotlib
matplotlib.use('Qt4Agg')
print matplotlib.get_backend()
import matplotlib.pyplot as plt

alignment = {'horizontalalignment':'center', 'verticalalignment':'baseline'}
alegreya_weights = { 'Alegreya': ['regular', 'bold', 'black'],
                     'Alegreya Sans': ['ultralight', 'light', 'regular', 
                                       'medium', 'bold', 'extra bold', 
                                       'black'] }
styles = ['normal', 'italic']

combinations = []
for family in alegreya_weights.keys():
    for style in styles:
        for weight in alegreya_weights[family]:
            combinations.append((family, weight, style))
N = len(combinations)

def textPlot(ax, i, N, family, weight, style):
    y = 1.-(1./float(N)) -float(i)/(float(N)+1)
    ax.text(0.5, y, family+' '+weight+' '+style, 
            family=family, weight=weight, style = style, 
            fontsize = 30, **alignment)

fig = plt.figure(figsize=(8, .7*N), frameon=False)
ax = plt.gca()
ax.axis('off')
plt.xlim((0.,1.))
plt.ylim((0.,1.))

for i,c in enumerate(combinations):
    textPlot(ax, i, N, c[0], c[1], c[2])

plt.show()

原来只有 AlegreyaSans-Regular.ttf 被 AlegreyaSans-Thin.ttf 取代。我不知道这是否是由于“Thin”这个词,它在 matplotlib-syntax 中被称为“ultralight”。我在 $HOME/.cache/matplotlib/fontList.cache 中将“AlegreyaSans-Thin.ttf”替换为“AlegreyaSans-Regular.ttf”以解决问题。

现在下面的图片来自上面的脚本。 未检测到薄(超轻)

感谢汤姆的帮助。

【讨论】:

  • Matplotlib 目前有一个open issue on this subject。不幸的是,在向 matplotlib 添加字体时,您必须删除所有“瘦”文件!
【解决方案2】:

感谢您发布此消息 - 我在尝试安装 Fira Sans 字体以使用 matplotlib 时遇到了类似的问题,无法显示正确的字体粗细。您将字体粗细与文件名相关联的诊断非常有帮助。

在 Mac 上,我解决了我的问题,即删除计算机上的所有 Fira Sans .ttf 文件并通过 Font Book 从头开始​​重新安装。原来我之前在不知道自己在做什么的时候,把几个Fira Sans字体文件(包括FiraSans-Regular)放在了其他字体目录下。随后,当我尝试使用 Font Book 安装 Fira Sans 时,regular 字体未能正确安装,导致 fontmanager 选择奇怪的字体。

tl;dr - 如果您运行上述诊断程序,但在给定粗细旁边没有看到您期望的文件名,请检查字体是否正确安装在 Font Book 中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-20
    • 2015-11-14
    • 2019-12-10
    • 1970-01-01
    • 2011-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多