matplotlib 中文乱码方框怎么办?MathModelAgent 黑体字体渲染完整方案
2026/9/17 11:20:35 网站建设 项目流程

matplotlib 中文乱码方框怎么办?MathModelAgent 黑体字体渲染完整方案

【免费下载链接】MathModelAgent🤖📐专为数学建模设计的 Agent & skills ,自动完成数学建模,生成一份完整的可以直接提交的论文。 An Agent Designed for Mathematical Modeling ,Automatically complete mathmodel and generate a complete paper ready for submission.项目地址: https://gitcode.com/GitHub_Trending/ma/MathModelAgent

MathModelAgent 是一个专为数学建模设计的开源 Agent 项目,能自动完成问题分析、建模、写代码、绘图并生成可直接提交的论文。其中"图表中文变成豆腐块(□□□)"是建模同学在用 matplotlib 绘图时几乎必然踩的坑,本项目通过内置黑体字体 + kernel 启动自动注册 + 提示词约束三管齐下,让 Agent 生成的每一张图表都稳定显示中文。本文带你拆解这套完整方案。

一、为什么 matplotlib 中文会变成方框?

matplotlib 默认只加载系统字体的一个缓存列表,而 Linux 服务器、Docker 容器、云端沙箱(E2B)这类环境通常没有安装中文字体。一旦字体缺失:

  • 中文标签、图例全部渲染成□□□方框;
  • 负号-也可能显示异常(axes.unicode_minus未处理);
  • 手动addfont之后,旧字体缓存不失效,字体依然"找不到"。

所以一个可靠方案必须同时解决三件事:字体文件就位、清缓存注册字体、固定 rcParams 配置。MathModelAgent 正是按这个思路设计的。

二、第一步:黑体字体文件随任务就位

项目在仓库里内置了思源黑体文件:

  • 字体文件:backend/fonts/simhei.ttf
  • 复制逻辑:backend/app/utils/common_utils.py

每当创建一个新任务工作目录(backend/project/work_dir/<task_id>/)时,create_work_dir()会自动把backend/fonts/下的全部.ttf/.otf/.ttc字体复制到工作目录。这样无论代码跑在本地还是云端,字体都"跟着数据走",不依赖宿主机的系统字体。

💡 这是整个方案的地基:不假设任何系统环境,把字体当数据文件分发

三、第二步:kernel 启动时一键注册中文字体

核心代码在 backend/app/tools/matplotlib_setup.py,build_matplotlib_init_code()会生成一段在 Jupyter / E2B kernel 启动时最先执行的初始化代码,逻辑分三步:

  1. 清字体缓存:删除matplotlib.get_cachedir()下的fontlist*.json,再调用font_manager.fontManager.__init__()重建字体列表——这解决了"手动加字体不生效"的经典坑;
  2. 注册黑体:遍历字体目录,对每个.ttf/.otf/.ttc调用font_manager.fontManager.addfont(),并记录真实字体名;
  3. 设置 rcParams:把已注册的黑体名放到font.sans-serif最前面,再依次兜底Heiti SCPingFang SCNoto Sans CJK SCMicrosoft YaHei等常见中文字体,同时设置axes.unicode_minus = False修复负号显示。

本地执行器在 backend/app/tools/local_interpreter.py 的initialize()中调用这段初始化代码,并把"中文字体已加载:SimHei(共 1 个)"这样的结论通过 WebSocket 推给前端;如果没找到字体,也会给出明确的 warning,方便排查。

另外,初始化代码还必须先os.path.abspath()解析绝对路径os.chdir()——这是一个隐蔽但关键的细节,否则会因相对路径失效导致addfont静默失败(源码注释中有专门说明,见 matplotlib_setup.py 第 43-48 行)。

四、第三步:统一注入学术图表样式

中文字体只是"能显示",论文级图表还需要统一观感。同一份初始化代码还注入了:

  • COLORS竞赛向配色(主色#2E5B88、辅色#E85D4C等 5 色);
  • FIG_SINGLE / FIG_DOUBLE / FIG_WIDE / FIG_SQUARE四种论文适配的画布尺寸;
  • 300dpi 保存、去掉上右边框、图例去边框、标题加粗等rcParams

Agent 写绘图代码时直接引用这些预置变量即可,产出风格高度一致:

五、第四步:用提示词约束 Agent 别"好心办坏事"

字体注册完就万事大吉了吗?不一定——如果模型在代码里随手写一句sns.set_theme()或重新改font.sans-serif,前面的配置全被覆盖,中文立刻变回方框。

因此项目在 Coder 的提示词里做了硬性约束(见 backend/app/core/prompts/coder.py):

执行环境已预配置CJK_FONTCOLORSFIG_*等变量,严格禁止在代码中调用sns.set_theme()或修改font.*/font.sans-serif/axes.unicode_minus(否则会覆盖中文字体导致方框)。

这是很多"环境配置 + 提示词护栏"双保险设计的缩影:环境层保证字体可用,提示词层保证字体不被破坏。

六、Docker 与云端沙箱的字体双保险

方案对三种运行环境都有覆盖:

运行环境字体来源说明
本地 Jupyter kernelbackend/fonts/simhei.ttf复制到工作目录见 common_utils.py
Docker 容器系统级fonts-noto-cjk+ 内置黑体backend/Dockerfile 第 5 行安装 Noto CJK
E2B 云端沙箱工作目录里的字体文件上传到/home/user后注册e2b_interpreter.py 第 64-111 行

云端沙箱的初始化代码同样包含"清缓存 →addfont→ 设置font.sans-serif兜底链"三步,逻辑与本地保持一致,只是字体目录换成了/home/user

七、小结:可复用的 4 步方法论

如果你自己也要在服务器/容器里用 matplotlib 画中文图表,可以直接套用 MathModelAgent 的四步方案:

  1. 字体当数据分发:把simhei.ttf放进项目仓库(参考 backend/fonts/simhei.ttf),运行前复制到代码执行目录;
  2. 先清缓存再注册:删除fontlist*.jsonfontManager.__init__()addfont()
  3. rcParams 固定中文字体链 +axes.unicode_minus=False,兜底多平台常见字体名;
  4. 在代码生成侧加约束,禁止后写入覆盖字体配置。

配合项目内置的 17 套论文模板与图表规范(见 skills/mathmodel-figure-templates/SKILL.md),从中文图表到整篇论文都能一次跑通。想快速体验完整效果,可以运行docker-compose up启动项目,在 WebUI 中提交一个建模任务,即可看到 CoderAgent 全程无方框的中文图表产出。

【免费下载链接】MathModelAgent🤖📐专为数学建模设计的 Agent & skills ,自动完成数学建模,生成一份完整的可以直接提交的论文。 An Agent Designed for Mathematical Modeling ,Automatically complete mathmodel and generate a complete paper ready for submission.项目地址: https://gitcode.com/GitHub_Trending/ma/MathModelAgent

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询