无法在 matplotlib 中使用自定义字体

2023-12-08

我在 Windows 上的 Python 3.7.3 上获取与 Matplotlib(版本 3.1.1)一起使用的自定义字体时遇到问题。标准方式使用

import matplotlib as mpl
mpl.rcParams['font.family'] = 'sans-serif'
mpl.rcParams['font.sans-serif'] = [FONTNAME] 

适用于系统上预安装的一系列字体。我最近手动安装了 Lato 系列字体。但是,当我使用“Lato”作为 FONTNAME 时,Matplotlib 默认返回 Deja Vu Sans,甚至不会抛出任何错误。我还使用重建字体缓存

mpl.font_manager._rebuild()

当我运行时,现在会出现几种名为“Lato”的字体

mpl.font_manager.fontManager.ttflist

such as

 <Font 'Lato' (Lato-Semibold.ttf) normal normal semibold normal>,
 <Font 'Lato' (Lato-Thin.ttf) normal normal 400 normal>,
...

然而这些情节看起来仍然像是使用 Deja Vu Sans 一样。我已经查看了所有内容,但找不到解决此问题的方法。


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

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

您还将观察到已创建一个新的缓存文件。上面的代码片段重新构建了缓存文件,该文件现在还包含 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

Note:所有步骤均在 IPython 控制台上执行,可能需要重新启动 IPython 会话才能使更改生效。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无法在 matplotlib 中使用自定义字体 的相关文章

随机推荐

  • Python - 使用列表创建字典

    我在列表中有以下字符串 并且能够使用该列表作为字典中的键并分配默认值 来创建字典 当我打印时 我看到字典是按照列表中字符串的相反顺序创建的 为什么会发生这种情况以及如何纠正它 是否需要反向语法 a hello bye tc iam crea
  • 由于 CORS 问题,无法从 Azure APIM 后面的网页调用 API

    我正在使用 Azure APIM 我的 API 托管在由 net core 编码的 Azure 应用服务上 我已经在 APIM 后面配置了我的 api 然而 当我尝试调用我的 API 时 我遇到了这个问题 访问从原点 获取 http 本地主
  • PHP,来自字符串的虚拟文件,无需写入硬盘

    如果我有一个字符串 包含pdf文件 可以制作一个 虚拟 文件以避免在硬盘上写入 以便稍后在需要现有文件的函数上使用 theorical code file stringToVirtualFile string require file Yo
  • 如何在 QLineEdit 中使用 std::string ?

    我有以下问题 我正在尝试将我编写的大量代码与 Qt 界面集成 我的一些函数返回std string 我没有成功制作QLineEdit setText接受它们 其他函数返回char不要给我带来问题 我应该怎么办 谢谢 朱塞佩 尝试这个 std
  • 未捕获的语法错误:JSON 中位置 0 处出现意外标记 u

    仅在结帐和单个产品页面上 我在控制台日志中收到以下错误 VM35594 1 Uncaught SyntaxError Unexpected token u in JSON at position 0 at JSON parse
  • 如何删除推送通知API

    Apple 在提交 iOS 应用程序时发送以下电子邮件 缺少推送通知权利 您的应用程序似乎包含用于注册 Apple 推送通知服务的 API 但应用程序签名的权利不包括 aps environment 权利 如果您的应用程序使用 Apple
  • 将简单注射器与 Umbraco 控制器结合使用

    我试图将依赖项注入到继承自 Umbraco 的 RenderMvcController 的控制器中并收到错误 找不到 RenderMvcController 类型的注册 并且无法进行隐式注册 为了让容器能够创建 RenderMvcContr
  • nums[:] = nums[::-1] 和 nums = nums[::-1] 之间的区别[重复]

    这个问题在这里已经有答案了 我目前正在学习 Python 并且遇到了分配列表的问题 In def nextPermutation self nums List int gt None 我有一行代码可以反转列表 如下所示 nums nums
  • 二维数组动态内存分配崩溃[重复]

    这个问题在这里已经有答案了 可能的重复 如何在 C 中正确设置 访问和释放多维数组 我正在尝试使用 calloc 为 2D 数组动态分配内存 列固定为 2 因此只有行是动态的 这是我一直在尝试的 unsigned int pts rows
  • 每个关键字的前 'n' 个结果

    我有一个查询 要获取对特定关键字发表评论的前 n 个用户 SELECT user COUNT AS magnitude FROM results WHERE keyword economy GROUP BY user ORDER BY ma
  • 为什么在 main() 内声明 extern 变量可以工作,但在 main() 内定义它却不起作用?

    这看起来很微不足道 但对以下行为的严格解释将有助于我的理解extern很多 所以我会很感激你的回答 在下面的示例程序中 我声明了一个extern多变的x在函数内部 main 现在 如果我在文件范围内定义变量main 并分配8到它 那么程序就
  • 如何防止未更改的组件重新渲染?

    我有一个由多个其他组件 例如文本字段 组成的组件 当向文本字段进行输入时 所有其他组件都会重新呈现 我想阻止重新渲染 只重新渲染实际更改的组件 我已经看到了useCallback是执行此操作的正确方法 我已经了解了如何使用它 但是 我遇到了
  • 如果用户通过社交登录登录,移动应用程序如何使用后端 API 进行身份验证?

    我试图了解移动应用程序上社交登录之间的基本组织和登录流程 以及该应用程序如何从后端 Flask API 请求资源 如果用户通过 Facebook 登录应用程序 后端 api 如何根据该登录提供资源 因为后端似乎不知道用户已经使用 Faceb
  • 选择行值不为空的列名 pandas dataframe

    这是一个示例数据框 A B C 23 45 30 54 39 NaN NaN 45 76 87 32 NaN 我想要一个包含行值不为 NaN 的列名称的列表 或列表列表 预期输出 A B C A B B C A B 这样做的正确方法是什么
  • IIS 崩溃并重新启动,但未删除小型转储

    我正在尝试调试一个艰难的场景 在 Web 表单页面上 当我单击 提交 时 Web 服务器遇到一些错误并重新启动 w3svc 进程 我没有看到任何堆栈跟踪转储到事件日志中 Windows 应用程序日志中的唯一条目是 错误应用程序名称 w3wp
  • System.Reflection.MethodInfo.Invoke 和多线程

    您好 我如何使用线程参数调用 System Reflection MethodInfo Invoke 例如 假设我有一个方法 允许您传入一个表示 类名并动态调用相应的类方法 现在我想要 使用线程调用此 Methodinfo invoke 我
  • 什么允许 id 属性使用字符,以便 jQuery 选择器不会抛出异常?

    我遇到的情况是最终用户输入 id 属性 假设文本框的 id 是用户输入的 11 11 html 代码看起来像
  • 不支持 Any 类型的架构

    我正在尝试创建一个 Spark UDF 以从用户定义的案例类中提取 键 值 对的映射 scala 函数似乎工作正常 但是当我尝试将其转换为 Spark2 0 中的 UDF 时 我遇到了 不支持 Any 类型的架构 错误 case class
  • Ruby,生成随机的十六进制颜色(仅限浅色)

    我知道这可能是重复的问题 Ruby 生成随机的十六进制颜色 我的问题略有不同 我需要知道 如何仅生成随机的六角浅色 而不是深色 在这个线程中颜色亮度用以下公式描述 0 2126 r 0 7152 g 0 0722 b 亮度的相同公式是维基百
  • 无法在 matplotlib 中使用自定义字体

    我在 Windows 上的 Python 3 7 3 上获取与 Matplotlib 版本 3 1 1 一起使用的自定义字体时遇到问题 标准方式使用 import matplotlib as mpl mpl rcParams font fa