排查 Matplotlib 颜色与中文字体问题

358 字
2 分钟
排查 Matplotlib 颜色与中文字体问题

现象一:OpenCV 图像颜色异常#

根因#

OpenCV 的 imread() 默认返回 BGR 通道顺序,Matplotlib 的 imshow() 按 RGB 解释。同一组数值被当成不同颜色空间,红色和蓝色因此互换。

BGR 图像被按 RGB 显示后的颜色异常
通道顺序不一致会使红色和蓝色互换。

修复#

import cv2
import matplotlib.pyplot as plt

image_bgr = cv2.imread("example.jpg")
if image_bgr is None:
    raise FileNotFoundError("example.jpg")

image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
plt.imshow(image_rgb)
plt.axis("off")
plt.show()

灰度图应显式指定色图,避免 Matplotlib 自动应用伪彩色:

plt.imshow(gray_image, cmap="gray", vmin=0, vmax=255)

现象二:中文显示为空框#

根因#

当前 Matplotlib 字体不包含中文字符。直接把字体复制到 Python 包内部并修改 matplotlibrc 容易在升级或重装环境后丢失,不适合作为长期方案。

查找可用字体#

from matplotlib import font_manager

for font in font_manager.fontManager.ttflist:
    if font.name in {"PingFang SC", "Microsoft YaHei", "SimHei", "Noto Sans CJK SC"}:
        print(font.name, font.fname)
Matplotlib 输出已发现字体名称和文件路径
使用字体管理器确认系统中实际可用的字体名称。

在代码中配置#

import matplotlib as mpl

mpl.rcParams["font.sans-serif"] = [
    "PingFang SC",
    "Microsoft YaHei",
    "Noto Sans CJK SC",
    "DejaVu Sans",
]
mpl.rcParams["axes.unicode_minus"] = False

团队项目应把字体作为明确依赖安装到系统或容器,并在启动时配置。只有确实新增或删除了系统字体且 Matplotlib 未识别时,才考虑清理字体缓存。

Matplotlib 字体缓存目录输出
缓存目录可通过 matplotlib.get_cachedir() 查询,不要猜测固定路径。

验证#

import matplotlib.pyplot as plt

plt.plot([-1, 0, 1], [1, 0, 1])
plt.title("颜色与中文测试")
plt.xlabel("横轴")
plt.show()

确认中文没有方框、负号正常,并用已知纯红/纯蓝图像验证通道转换。保存为 PNG 后再次打开,排除仅交互窗口正常的情况。

参考#

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

排查 Matplotlib 颜色与中文字体问题
https://blog.mintalix.com/posts/study-matplotlib-plt-issue/
作者
Mint
发布于
2022-04-15
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
Mint
软件开发、工程实践与技术思考。
分类
标签