使用matplotlib进行制图,如果在标题,坐标轴,或者图例中使用了中文的话中文字符会被替换成”方块”。就像下面这样:An image to describe post Matplotlib使用中文绘图

使用英文作为标题,坐标轴和图例名称时就没有问题
An image to describe post Matplotlib使用中文绘图

造成这个问题的主要原因是没有告诉matplotlib使用支持中文的字体,而matplotlib默认使用的字体仅仅支持ASCII字符,所以遇到ASCII之外的字符就被替换成了方块。

可以通过设置支持中文的字体来验证这个说法。
以macOS为例,打开FontBook就可以看到系统中的所有字体

An image to describe post Matplotlib使用中文绘图

以字体“Hei”为例,让matplotlib使用我们选择的字体:

# 设置matplotlib的字体
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = ['Hei']

之后图像中的中文字符就可以正常显示了
An image to describe post Matplotlib使用中文绘图

基本问题已经得到验证了,那么如果要在生产上以Docker镜像的方式部署服务并且进行中文绘图的话,有几种方式可选来设置字体:

  1. 直接使用镜像中系统自带的中文字体文件。
  2. 拷贝开发机器中的字体文件(.ttf)到镜像的字体目录中。
  3. 构建镜像时下载安装开源中文字体。

对于我来说我比较喜欢最后一种方式,在构建镜像的时候下载开源的中文字体安装让matplotlib使用。

我选择的开源字体是文泉驿并且已经安装在了macOS上
An image to describe post Matplotlib使用中文绘图

安装之后使用matplotlib进行一次测试:
效果还不错:

在构建镜像的时候就加上安装字体的步骤

FROM python:3.10.11-slim-bullseye AS builder
# 安装中文字体
RUN apt-get update && apt-get install -y \
    fonts-wqy-zenhei \
    && rm -rf /var/lib/apt/lists/*
# 其他步骤

这样本地验证的字体和生产使用的字体保持一致,代码也不需要做额外的修改。

注意:如果你在开发机器先安装了matplotlib后安装了文泉驿字体,则需要删除matplotlib的字体缓存。具体参考Stackoverflow的回答

完整示例代码可以在这里找到。