【问题标题】:Matplotlib can't find font installed in my Linux machineMatplotlib 在我的 Linux 机器上找不到安装的字体
【发布时间】:2016-10-21 14:46:16
【问题描述】:

我正在尝试在 Python 3 下使用 matplotlib(1.4.2 版)绘制 xkcd 风格的绘图。

当我尝试运行时:

import matplotlib.pyplot as plt
plt.xkcd()
plt.plot([1,2,3,4], [1,4,9,16], 'bo')
plt.axis([0, 6, 0, 20])
plt.show()

它打开一个没有任何图像的空窗口,我收到错误:

/usr/lib/python3/dist-packages/matplotlib/font_manager.py:1279: UserWarning: findfont: Font family ['Humor Sans', 'Comic Sans MS', 'StayPuft'] not found. Falling back to Bitstream Vera Sans
  (prop.get_family(), self.defaultFamily[fontext]))
/usr/lib/python3/dist-packages/matplotlib/font_manager.py:1289: UserWarning: findfont: Could not match :family=Bitstream Vera Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=medium. Returning /usr/share/matplotlib/mpl-data/fonts/ttf/STIXSizOneSymReg.ttf
  UserWarning) Exception in Tkinter callback

我安装了 Humor Sans。我用fc-list | grep Humor检查了它。它也可以在其他程序中使用,例如 Libre Office。我也安装了staypuft。这还不够吗?

上面相同但没有 plt.xkcd() 位的代码可以完美运行。

plt.show() 的替代方法,例如 pylab.savefig() 对 xkcd 代码也不起作用,但在不使用 xkcd 的情况下使用相同的代码没有任何问题。

【问题讨论】:

    标签: python python-3.x matplotlib fonts


    【解决方案1】:

    正如@neves 所说,matplotlib.font_manager._rebuild() 不再有效。作为手动删除缓存目录的替代方法,从 Matplotlib 3.4.3 开始起作用的是:

    import matplotlib
    matplotlib.font_manager._load_fontmanager(try_read_cache=False)
    

    这是该函数的 Matplotlib 源代码:

    def _load_fontmanager(*, try_read_cache=True):
        fm_path = Path(
            mpl.get_cachedir(), f"fontlist-v{FontManager.__version__}.json")
        if try_read_cache:
            try:
                fm = json_load(fm_path)
            except Exception as exc:
                pass
            else:
                if getattr(fm, "_version", object()) == FontManager.__version__:
                    _log.debug("Using fontManager instance from %s", fm_path)
                    return fm
        fm = FontManager()
        json_dump(fm, fm_path)
        _log.info("generated new fontManager")
        return fm
    

    【讨论】:

      【解决方案2】:

      在 JupyterLab 中使用 matplotlib 版本 3.4.2 在 WSL2 中安装新字体以使其可用后,我必须执行以下过程。

      首先,删除缓存目录:

      import shutil
      import matplotlib
      
      shutil.rmtree(matplotlib.get_cachedir())
      

      然后重启你的笔记本内核。

      然后使用此命令测试新字体是否出现在笔记本单元格中:

      import matplotlib.font_manager
      from IPython.core.display import HTML
      
      def make_html(fontname):
          return "<p>{font}: <span style='font-family:{font}; font-size: 24px;'>{font}</p>".format(font=fontname)
      
      code = "\n".join([make_html(font) for font in sorted(set([f.name for f in matplotlib.font_manager.fontManager.ttflist]))])
      
      HTML("<div style='column-count: 2;'>{}</div>".format(code))
      

      【讨论】:

        【解决方案3】:

        以防万一有人想为他们的图表选择自定义字体。您可以手动设置图表标签、标题、图例或刻度标签的字体。以下代码演示了如何为图表设置自定义字体。你提到的错误可以消失。

        import matplotlib.font_manager as fm
        import matplotlib.pyplot as plt
        
        font_path = '/System/Library/Fonts/PingFang.ttc'  # the location of the font file
        my_font = fm.FontProperties(fname=font_path)  # get the font based on the font_path
        
        fig, ax = plt.subplots()
        
        ax.bar(x, y, color='green')
        ax.set_xlabel(u'Some text', fontproperties=my_font)
        ax.set_ylabel(u'Some text', fontproperties=my_font)
        ax.set_title(u'title', fontproperties=my_font)
        for label in ax.get_xticklabels():
            label.set_fontproperties(my_font)
        

        【讨论】:

          【解决方案4】:

          如果您在安装 matplotlib 后添加了新字体,请尝试删除字体缓存。 Matplotlib 将不得不重建缓存,从而添加新字体。

          它可能位于~/.matplotlib/fontList.cache~/.cache/matplotlib/fontList.json 下。

          【讨论】:

          • 我搜索了 fontList 并在 ~/.cache/matplotlib/fontList.py3k.cache 找到了它。删除它会使上面的代码再次工作。
          • 是的,matplotlib 配置文件的位置是由操作系统定义的。
          • 在 Windows 上,您需要查看 %HOMEPATH%\.matplotlib。有一个文件 fontList.py3k.cache。删除它。如果您使用的是 jupyter 笔记本,则必须在拾取新字体并重新创建缓存之前重新启动 jupyter。
          • 运行import matplotlib as mpl; print(mpl.get_cachedir())可以找到缓存的目录
          【解决方案5】:

          对于 Mac 用户:尝试在 python 中运行此命令:(或在 .py 文件之前)

          import matplotlib
          
          matplotlib.font_manager._rebuild()
          

          【讨论】:

          • 这似乎是当前版本的 matplotlib 的工作解决方案。我找不到fontList 缓存。
          • 至少在matplotlib v3.3.2 matplotlib.font_manager 在导入matplotlib 时是未知的,所以你需要做import matplotlib.font_manager; matplotlib.font_manager._rebuild()
          • 在 matplotlib 3.4.2 中字体管理器没有 _rebuild 属性。我也找不到字体缓存。
          猜你喜欢
          • 2011-09-26
          • 1970-01-01
          • 2023-03-18
          • 2013-02-27
          • 1970-01-01
          • 1970-01-01
          • 2011-06-16
          • 2013-08-09
          • 1970-01-01
          相关资源
          最近更新 更多