关于python 2.7:如何修复matplotlib检测错误的字体粗细?

How can I fix matplotlib detecting wrong font weights?

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

1
2
3
4
5
6
7
8
9
10
11
12
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', '\
'+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)

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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


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

在Mac上,我解决了我删除计算机上所有Fira Sans .ttf文件并通过Font Book重新安装initio的问题。原来,当我不知道自己在做什么时,我以前曾在其他字体目录中放置了多个Fira Sans字体文件(包括FiraSans-Regular)。随后,当我尝试使用Font Book安装Fira Sans时,regular字体无法正确安装,导致fontmanager选择了奇怪的字体。

tl; dr-如果在上面运行诊断程序,但在给定的权重旁边看不到预期的文件名,请检查字体是否正确安装在Font Book中。


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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语法中被称为" ultralight"。我将$ HOME / .cache / matplotlib / fontList.cache中的" AlegreyaSans-Regular.ttf"替换为" AlegreyaSans-Regin.ttf"以解决此问题。

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

enter image description here

感谢汤姆的任何帮助。