背景 :在Linux服务器上使用matplotlib或seaborn绘制论文图表时,经常会遇到
findfont: Font family ['Times New Roman'] not found的错误。本文将介绍两种解决方案:系统级字体安装和代码级动态加载,帮助你在Linux环境下完美使用Times New Roman字体。
一、问题描述
在使用matplotlib或seaborn进行科研绘图时,为了符合论文格式要求,我们通常需要设置字体为Times New Roman。但在Linux系统(如Ubuntu、CentOS等)中,默认并未安装该字体,导致出现以下警告:
findfont: Font family ['Times New Roman'] not found. Falling back to DejaVu Sans.
二、解决方案一:系统级字体安装
这是最彻底的解决方案,将Times New Roman字体安装到系统字体库中,所有应用程序均可使用。
步骤1:从Windows获取字体文件
Times New Roman字体受版权保护,最安全的获取方式是从已授权的Windows系统中复制:
- 在Windows系统中打开
C:\Windows\Fonts文件夹 - 搜索 "Times New Roman"
- 复制以下四个字体文件到桌面:
times.ttf(常规)timesbd.ttf(粗体)timesbi.ttf(粗斜体)timesi.ttf(斜体)

步骤2:上传到Linux服务器
将四个字体文件上传到Linux系统的字体目录(需要sudo权限):
bash
# 创建字体存放目录(如果不存在)
sudo mkdir -p /usr/share/fonts/
# 上传字体文件(使用scp、rsync或FTP工具)
scp times*.ttf user@server:/usr/share/fonts/
或者上传到用户级目录(无需sudo):
bash
mkdir -p ~/.local/share/fonts/
cp times*.ttf ~/.local/share/fonts/
步骤3:更新字体缓存
执行fc-cache命令刷新系统字体缓存:
bash
# 系统级字体缓存更新
sudo fc-cache -fv /usr/share/fonts/
# 或用户级缓存更新
fc-cache -fv ~/.local/share/fonts/
参数说明:
-f:强制重新生成缓存-v:显示详细过程
验证字体是否安装成功:
bash
fc-list | grep "Times New Roman"
预期输出:
/usr/share/fonts/times/times.ttf: Times New Roman:style=Regular
/usr/share/fonts/times/timesbd.ttf: Times New Roman:style=Bold
步骤4:清除matplotlib缓存
这是关键步骤!matplotlib会缓存字体列表,必须清除才能识别新字体:
python
import matplotlib
print(matplotlib.get_cachedir()) # 查看缓存路径
bash
# 删除matplotlib字体缓存
rm -rf ~/.cache/matplotlib/
步骤5:在代码中使用
python
import matplotlib.pyplot as plt
# 设置全局字体
plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams['font.size'] = 12
# 绘图测试
plt.figure(figsize=(8, 6))
plt.plot([1, 2, 3], [4, 5, 6], label='Sample Data')
plt.title('Title in Times New Roman')
plt.xlabel('X-axis Label')
plt.ylabel('Y-axis Label')
plt.legend()
plt.savefig('test_font.png', dpi=300, bbox_inches='tight')
plt.show()
三、解决方案二:代码级动态加载(临时方案)
如果你无法修改系统字体(如没有sudo权限,或在共享服务器上),可以使用fontManager.addfont()方法在代码中动态加载字体。
适用场景
- 无系统管理员权限
- 临时使用特定字体
- 需要在不同环境中快速部署
具体实现
python
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
# 动态添加字体(无需系统安装)
font_path = '/your_server_dirfonts/times.ttf' # 字体文件路径
fm.fontManager.addfont(font_path)
# 创建字体属性对象
times_font = fm.FontProperties(fname=font_path)
# 验证字体加载
print(f"Loaded font: {times_font.get_name()}")
# 使用方式1:局部设置(推荐,灵活性高)
plt.figure(figsize=(8, 6))
plt.plot([1, 2, 3], [4, 5, 6])
# 对特定文本元素应用字体
plt.title('Title with Times New Roman', fontproperties=times_font, size=14)
plt.xlabel('X-axis', fontproperties=times_font, size=12)
plt.ylabel('Y-axis', fontproperties=times_font, size=12)
# 图例字体设置
plt.legend(['Data'], prop=times_font)
plt.tight_layout()
plt.savefig('dynamic_font.png', dpi=300)
plt.show()
进阶:批量添加多个字体样式
python
import matplotlib.font_manager as fm
import os
# 定义字体目录
font_dir = '//your_server_dirfonts/times/'
# 自动添加目录下所有字体文件
for font_file in os.listdir(font_dir):
if font_file.endswith(('.ttf', '.otf', '.ttc')):
full_path = os.path.join(font_dir, font_file)
fm.fontManager.addfont(full_path)
print(f"Added: {font_file}")
# 设置全局默认字体
plt.rcParams['font.family'] = 'Times New Roman'
![动态加载效果截图占位符]
图4:动态加载字体后的渲染效果
五、常见问题与排查
Q1:执行fc-cache后仍找不到字体?
排查步骤:
- 确认字体文件权限:
chmod 644 /usr/share/fonts/truetype/times/*.ttf - 检查字体格式是否为TTF/OTF
- 确认缓存清除彻底:
rm -rf ~/.cache/matplotlib/*
Q2:中文显示为方框或乱码?
Times New Roman不支持中文字符,需要混合字体设置:
python
# 英文用Times New Roman,中文用SimHei
plt.rcParams['font.family'] = ['Times New Roman', 'SimHei']
# 或分别指定
plt.xlabel('中文标签', fontproperties='SimHei')
plt.ylabel('English Label', fontproperties='Times New Roman')
Q3:Docker容器内字体失效?
在Dockerfile中添加:
dockerfile
COPY times*.ttf /usr/share/fonts/truetype/times/
RUN fc-cache -fv && rm -rf /root/.cache/matplotlib/