matplotlib中文显示为方块的根本原因是默认字体不支持中文,需通过设置font.sans-serif或font.family指定本地中文字体,并注意系统间字体名称差异。

matplotlib绘图时中文显示为方块或乱码
根本原因是matplotlib默认字体不支持中文,尤其在Windows系统上默认用DejaVu Sans,Linux/macOS可能用Bitstream Vera,都不含中文字形。直接调用plt.show()后看到一堆方块,不是代码写错了,是字体缺位。
实操建议:
- 先确认当前可用字体:
matplotlib.font_manager.findSystemFonts(fontpaths=None, fontext='ttf'),过滤出含“sim”“hei”“song”“kai”的路径(如C:\Windows\Fonts\simsun.ttc) - 临时生效:在绘图前加两行:
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS', 'DejaVu Sans'] plt.rcParams['axes.unicode_minus'] = False
注意顺序——把中文字体放前面,否则fallback到英文体会失效 - 永久生效:修改
matplotlib.get_configdir()返回路径下的matplotlibrc文件,取消注释并改写font.sans-serif行,加入本地存在的中文字体名(不是文件名!是字体内部名称,可用fc-list :lang=zh查)
使用graphviz绘制决策树时中文节点乱码
export_graphviz生成的dot文件本身是纯文本,乱码只发生在graphviz渲染阶段。核心在于dot命令调用的字体配置未指定中文字体,和Python无关。
实操建议:
- 检查graphviz版本:低于2.45可能对UTF-8支持不稳,升级到
graphviz>=2.47更稳妥 - 生成dot时强制声明字体:
export_graphviz(clf, out_file='tree.dot', feature_names=feature_names, class_names=class_names, filled=True, rounded=True, special_characters=True, font_name='SimHei') # ← 关键参数 - 命令行渲染时显式传参:
dot -Tpng -Gfontname="SimHei" -Nfontname="SimHei" tree.dot -o tree.png,-G控制全局,-N控制节点,二者都要设 - 若仍乱码,把中文字体文件(如simsun.ttc)复制到graphviz安装目录的
fonts/子目录下,并在dot命令中用绝对路径引用
sklearn的plot_tree函数中文不显示
sklearn.tree.plot_tree底层用的是matplotlib,所以乱码本质和第一个问题一样,但它的接口不暴露font_family参数,不能像export_graphviz那样直接传字体名。
实操建议:
- 必须提前设置全局rcParams:
plt.rcParams['font.family'] = 'SimHei',且要在plot_tree调用之前执行 - 避免混用不同绘图方式:如果同时用了
plot_tree和export_graphviz,确保两者字体配置一致,否则容易出现一个正常一个乱码 - macOS用户注意:
'Heiti SC'或'STHeiti'比'SimHei'更可靠;Linux用户常用'WenQuanYi Zen Hei'或'Noto Sans CJK SC' - 如果节点文字过长被截断,不是乱码问题,而是
max_depth或fontsize参数没调好,和字体无关
服务器环境(无GUI)下生成中文图表失败
在Docker、JupyterHub或SSH终端里,即使字体配置正确,plt.show()会报TclError: no display name and no $DISPLAY environment variable,而保存图片时中文又变方块——这是因为Agg后端不读系统字体缓存。
实操建议:
- 强制指定字体文件路径(绕过字体名查找):
import matplotlib.font_manager as fm plt.rcParams['font.family'] = fm.FontProperties(fname='/path/to/simsun.ttc').get_name()
- Docker镜像中预装中文字体:Ubuntu系加
fonts-wqy-zenhei,CentOS系加liberation-fonts-common和wqy-unibit-fonts - 生成图片时用
plt.savefig(..., bbox_inches='tight', dpi=150),bbox_inches能防止中文标签被裁掉
真正麻烦的不是配字体,而是字体名在不同系统里叫法不一——Windows里叫“SimHei”,macOS里叫“Heiti SC”,Linux里可能叫“WenQuanYi Zen Hei”。别信网上抄来的固定字符串,先用系统命令查真实名称,再填进代码。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











