栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Linux无root权限解决matplotlib中文字体各种疑难杂症

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux无root权限解决matplotlib中文字体各种疑难杂症

问题简述

python经典中文字体问题,非管理员、无root环境下 matplotlib;seaborn 设置中文。

在使用yolov5训练的时候,报Warming

Plotting labels to runs/train/exp4/labels.jpg... 
backend_agg.py:238: RuntimeWarning: Glyph 22823 missing from current font.

其最大的影响就是,生成的label.jpg,图片上中文字被方框替代。

findfont: Font family ['SimHei'] not found. Falling back to DejaVu Sans.
findfont: Font family ['sans-serif'] not found. Falling back to DejaVu Sans.
问题分析

linux缺中文字体是一件很常见的事情。

因为图片识别需要消耗大量CPU、GPU资源,电脑GPU资源吃紧,所以寻找了一些专门的服务器训练。

这些jupyter服务器,通常不带有su管理员权限,然而已经配置好了python环境,非root无法将字体文件复制到mpl-data文件夹下,也无法修改matplotlibrc文件。

无root、但是python环境已经在root环境下配置好,这导致网上流行的90%方法不能使用。


解决方法 解决方法1:最直接的解决方法,治标又治本。

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

使用font_manager中的addfont.

之后在所有调用plt绘制中文标签的py文件,开头都加上:

import matplotlib.pyplot as plt
from matplotlib import font_manager

font_path = 'SimHei.ttf' # ttf的路径 最好是具体路径
font_manager.fontManager.addfont(font_path)

# plt.rcParams['font.family'] = 'SimHei' #下面代码不行,在加上这一行
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签

plt.rcParams['axes.unicode_minus']=False #用来正常显示负号(用中文显示符号会有bug)

若seaborn也会报错,在所有使用到seaborn的py文件,都加上

import seaborn as sn

sn.set(font='SimHei')

 问题迎刃而解。

解决方法2:用FontProperties,并指定字体文件

之后在所有调用plt绘制中文标签的py文件中,含有绘制代码的,例如plt.title("***"),加上参数fontproperties=font。

这种方法有点繁琐,并且不能一次性解决seaborn的问题。

from matplotlib.font_manager import FontProperties
import matplotlib.pyplot as plt
font = FontProperties(fname='SimHei.ttf')
plt.title('测试', fontproperties=font)

yolov5

在train.py;val.py;detect.py加上解决方法1上的代码即可

在utils/metrics.py文件中,ConfusionMatrix类plot函数,

def plot(self, normalize=True, save_dir='', names=()):
    try:
        import seaborn as sn
        # 加入如下代码
        sn.set(font='SimHei')
        

问题复现

我们的方法都是临时性的,不带有root权限的。

重新构建matplotlib缓存。

from matplotlib.font_manager import _rebuild
_rebuild()

打印字体名称

import matplotlib.font_manager
sorted([f.name for f in matplotlib.font_manager.fontManager.ttflist])

 输出结果如下:可见是没有中文字体的

['DejaVu Sans',
 'DejaVu Sans',
 'DejaVu Sans',
....
 'cmmi10',
 'cmr10',
 'cmss10',
 'cmsy10',
 'cmtt10']

 使用plt绘个图,报错,文字变方块。 

plt.title('测试')

使用seaborn绘图,报错,文字变方块。

import os
import seaborn as sns
import pandas as pd


tips = pd.DataFrame({
    'time':["午餐","晚餐"],
    'total_bill':[1,2],
})
sns.pointplot(x="time", y="total_bill", data=tips)

 运行解决方案1:中文正确显示。

import matplotlib.pyplot as plt
from matplotlib import font_manager

font_path = 'SimHei.ttf' # ttf的路径 最好是具体路径
font_manager.fontManager.addfont(font_path)

# plt.rcParams['font.family'] = 'SimHei' #下面代码不行,在加上这一行
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签

plt.rcParams['axes.unicode_minus']=False #用来正常显示负号(用中文显示符号会有bug)

plt.title('测试')

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/829707.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号