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('测试')



