学习笔记 | 如何解决matplotlib绘图中文显示问题

2024-06-20 19:13:11 浏览数 (1)

前言

我们绘图时候常常会碰到写中文的时候画出来的是方框

这通常是字体缺失造成的,画图时候也会出警告

那么今天写一下记录我怎么解决这个问题

当然,我们要先去下载一个字体ttf格式的文件

我下载了宋体(网址为font/unicode/SimHei.ttf at master · dolbydu/font (github.com))

字体文件夹在哪里

首先,你需要知道matplotlib在哪里查找字体。可以通过以下Python代码找到matplotlib配置文件所在的目录,字体通常位于此目录下的fonts/ttf子目录中:

In [1]:

代码语言:javascript复制
代码语言:javascript复制
import matplotlib
print(matplotlib.get_data_path())
代码语言:javascript复制
代码语言:javascript复制
/opt/conda/lib/python3.9/site-packages/matplotlib/mpl-data

复制或者上传到字体文件夹

将你的.ttf字体文件复制or 上传到上面找到的fonts/ttf目录中。

In [6]:

代码语言:javascript复制
代码语言:javascript复制
!ls /opt/conda/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf
代码语言:javascript复制
代码语言:javascript复制
cmb10.ttf			LICENSE_DEJAVU
cmex10.ttf			LICENSE_STIX
cmmi10.ttf			SourceHanSansCN-Normal.otf
cmr10.ttf			STIXGeneralBolIta.ttf
cmss10.ttf			STIXGeneralBol.ttf
cmsy10.ttf			STIXGeneralItalic.ttf
cmtt10.ttf			STIXGeneral.ttf
DejaVuSans-BoldOblique.ttf	STIXNonUniBolIta.ttf
DejaVuSans-Bold.ttf		STIXNonUniBol.ttf
DejaVuSansDisplay.ttf		STIXNonUniIta.ttf
DejaVuSansMono-BoldOblique.ttf	STIXNonUni.ttf
DejaVuSansMono-Bold.ttf		STIXSizFiveSymReg.ttf
DejaVuSansMono-Oblique.ttf	STIXSizFourSymBol.ttf
DejaVuSansMono.ttf		STIXSizFourSymReg.ttf
DejaVuSans-Oblique.ttf		STIXSizOneSymBol.ttf
DejaVuSans.ttf			STIXSizOneSymReg.ttf
DejaVuSerif-BoldItalic.ttf	STIXSizThreeSymBol.ttf
DejaVuSerif-Bold.ttf		STIXSizThreeSymReg.ttf
DejaVuSerifDisplay.ttf		STIXSizTwoSymBol.ttf
DejaVuSerif-Italic.ttf		STIXSizTwoSymReg.ttf
DejaVuSerif.ttf

将宋体复制到字体文件夹

代码语言:javascript复制
代码语言:javascript复制
!cp /home/mw/project/SimHei.ttf /opt/conda/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf
代码语言:javascript复制

可以看到目录下的宋体

代码语言:javascript复制
代码语言:javascript复制
!ls /opt/conda/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf
代码语言:javascript复制
代码语言:javascript复制
cmb10.ttf			LICENSE_DEJAVU
cmex10.ttf			LICENSE_STIX
cmmi10.ttf			SimHei.ttf
cmr10.ttf			SourceHanSansCN-Normal.otf
cmss10.ttf			STIXGeneralBolIta.ttf
cmsy10.ttf			STIXGeneralBol.ttf
cmtt10.ttf			STIXGeneralItalic.ttf
DejaVuSans-BoldOblique.ttf	STIXGeneral.ttf
DejaVuSans-Bold.ttf		STIXNonUniBolIta.ttf
DejaVuSansDisplay.ttf		STIXNonUniBol.ttf
DejaVuSansMono-BoldOblique.ttf	STIXNonUniIta.ttf
DejaVuSansMono-Bold.ttf		STIXNonUni.ttf
DejaVuSansMono-Oblique.ttf	STIXSizFiveSymReg.ttf
DejaVuSansMono.ttf		STIXSizFourSymBol.ttf
DejaVuSans-Oblique.ttf		STIXSizFourSymReg.ttf
DejaVuSans.ttf			STIXSizOneSymBol.ttf
DejaVuSerif-BoldItalic.ttf	STIXSizOneSymReg.ttf
DejaVuSerif-Bold.ttf		STIXSizThreeSymBol.ttf
DejaVuSerifDisplay.ttf		STIXSizThreeSymReg.ttf
DejaVuSerif-Italic.ttf		STIXSizTwoSymBol.ttf
DejaVuSerif.ttf			STIXSizTwoSymReg.ttf

更新matplotlib字体缓存

matplotlib会缓存字体列表信息,这个缓存文件通常位于用户的matplotlib配置目录中。

每当向matplotlib的字体目录添加或删除字体后,都需要更新字体列表缓存

那么缓存文件夹在哪里,我们要怎么更新呢,

先回答后面那个问题,删除

下面的代码可以查看缓存文件夹位置

代码语言:javascript复制
代码语言:javascript复制
print(matplotlib.get_cachedir())
代码语言:javascript复制
代码语言:javascript复制
/home/mw/.cache/matplotlib

进入这个目录,你会看到一个名为fontlist-v310.json(版本号可能会有所不同)的文件,这就是字体列表缓存文件

In [16]:

代码语言:javascript复制
代码语言:javascript复制
!ls /home/mw/.cache/matplotlib/
代码语言:javascript复制
代码语言:javascript复制
fontlist-v330.json

In [18]:

代码语言:javascript复制
代码语言:javascript复制
!rm /home/mw/.cache/matplotlib/fontlist-v330.json
代码语言:javascript复制

我们需要关闭所有正在运行的matplotlib实例,然后手动删除这个fontlist--v330.json文件。使matplotlib在下次启动时重建字体缓存。

重启,然后查看

重启Python或Jupyter Notebook内核,确保所有引用matplotlib的进程都已重启,以便matplotlib能够注意到字体缓存已被清除并重新生成它

重启后,你可以通过以下代码检查新字体是否已经被matplotlib识别

In [1]:

代码语言:javascript复制
代码语言:javascript复制
from matplotlib.font_manager import FontManager
fm = FontManager()
fonts = fm.ttflist
font_names = [f.name for f in fonts]
print(font_names)
代码语言:javascript复制

好的,字体更新成功,可喜可贺,你可以愉快作图了

ps: 我记得当前matplotlib版本是3.7.4,以上经验可能对其他版本不适用,还请留意

0 人点赞