matplotlib 绘图样式中的字体属性由字体管理器类并用a指定字体属性班级。
为了获取这些字体属性,matplotlib 在内部使用 FontManager 类的实例来调用findfont()
函数,用于搜索字体并返回本地或系统字体路径中与 FontProperties 实例中的字体规范相匹配的最佳 TrueType (TTF) 字体文件。规范中的默认后备字体是 DejaVu Sans。字体系列可以设置为以下参数之一:“serif”、“sans-serif”、“cursive”、“fantasy”或“monospace”。可以找到任何字体系列的 TTF 文件位置,如下所示:
In [1]: from matplotlib.font_manager import findfont, FontProperties
In [2]: font = findfont(FontProperties(family=['sans-serif']))
In [3]: font
Out[3]: 'C:\\Users\\xxxxxx\\Anaconda3\\envs\\py3.7.4\\lib\\site-packages\\matplotlib\\mpl-data\\fonts\\ttf\\DejaVuSans.ttf'
“等宽”系列的另一个例子:
In [7]: font = findfont(FontProperties(family=['monospace']))
In [8]: font
Out[8]: 'C:\\Users\\xxxxxx\\Anaconda3\\envs\\py3.7.4\\lib\\site-packages\\matplotlib\\mpl-data\\fonts\\ttf\\DejaVuSansMono.ttf'
正如你所看到的,上面的 sans-serif 系列指向默认的 DejaVuSans TTF 文件,因为我还没有设置FONTNAME
诸如“Lato”字体之类的其他字体也属于无衬线字体家族。
之前,我改变了FONTNAME
,首先了解字体搜索是如何发生的很重要。
现在,字体搜索是一项昂贵的任务,为了使后续请求高效,字体信息缓存在 JSON 文件中。您可以在以下内容中找到证据源代码为了FontManager
班级。对于 Windows,该文件位于:%userprofile%\.matplotlib。欲了解更多详细信息,请参阅注释部分FontManager
类文档:
这将执行最近邻搜索。每个字体都有一个
与目标字体属性的相似度得分。第一个字体带有
返回最高分。如果没有低于某个阈值的匹配项
找到后,将返回默认字体(通常是 DejaVu Sans)。
结果被缓存,因此后续查找不必执行
O(n) 最近邻搜索。
在我的计算机(Windows 10)上,我有两个缓存文件:字体列表-v300 & 字体列表-v310。如果您检查任何这些文件的内容,它会显示字体及其属性的列表,例如 TTF 文件位置、样式、粗细等。观察默认的系列键:
"defaultFamily": {
"ttf": "DejaVu Sans",
"afm": "Helvetica"
}
此时,我们了解到该字体将以 DejaVu Sans 格式显示。这在情节标题中最为明显:
In [1]: import matplotlib as mpl
...: mpl.rcParams['font.family'] = 'sans-serif'
...: import matplotlib.pyplot as plt
...: plt.plot(range(0,50,10))
...: plt.title('Font test', size=32)
...: plt.show()
绘图(默认字体):
![default font fallback](https://i.stack.imgur.com/OCcQX.png)
The findfont()
函数将始终查找缓存文件(如果不存在则创建一个),如果我在计算机上安装一种新字体,更新此缓存文件很重要,否则它将继续显示后备字体(与默认值相同)。在继续下一步之前,请确保 Lato 字体是安装正确。该字体应该在控制面板的字体下可用。
现在正确安装了 Lato 字体,删除缓存文件并将 sans-serif 字体设置为 Lato:
In [4]: import matplotlib as mpl^M
...: mpl.rcParams['font.family'] = 'sans-serif'
...: mpl.rcParams['font.sans-serif'] = 'Lato'
...: import matplotlib.pyplot as plt
...: plt.plot(range(0,50,10))
...: plt.title('Font test', size=32)
...: plt.show()
情节(Lato无衬线字体):
![enter image description here](https://i.stack.imgur.com/FfuCk.png)
您还将观察到已创建一个新的缓存文件。上面的代码片段重新构建了缓存文件,该文件现在还包含 Lato 字体的信息。同样,您可以在文本编辑器中打开此缓存文件以验证其存在。现在让我们验证 sans-serif 系列的 TTF 文件路径:
In [4]: from matplotlib.font_manager import findfont, FontProperties
In [5]: font = findfont(FontProperties(family=['sans-serif']))
In [6]: font
Out[6]: 'C:\\Users\\xxxxx\\AppData\\Local\\Microsoft\\Windows\\Fonts\\Lato-Thin.ttf'
正如您所看到的,sans-serif 系列现在指向 Lato-Thin TTF 文件。
将字体样式更改为italic还要求先删除缓存文件:
In [3]: In [4]: import matplotlib as mpl
...: ...: mpl.rcParams['font.family'] = 'sans-serif'
...: ...: mpl.rcParams['font.sans-serif'] = 'Lato'
...: ...: mpl.rcParams['font.style'] = 'italic'
...: ...: import matplotlib.pyplot as plt
...: ...: plt.plot(range(0,50,10))
...: ...: plt.title('Font test', size=32)
...: ...: plt.show()
In [4]: from matplotlib.font_manager import findfont, FontProperties
In [5]: font = findfont(FontProperties(family=['sans-serif']))
In [6]: font
Out[6]: 'C:\\Users\\xxxxxx\\AppData\\Local\\Microsoft\\Windows\\Fonts\\Lato-HairlineItalic.ttf'
Plot:
![enter image description here](https://i.stack.imgur.com/5TCLr.png)
Note:所有步骤均在 IPython 控制台上执行,可能需要重新启动 IPython 会话才能使更改生效。