解决Matplotlib的中文显示乱码

Matplotlib是Python 数据可视化的基础工具,也是许多高级可视化库(如 Seaborn、Plotly)的底层依赖。这篇笔记记录: Matplotlib图表,中文显示乱码修复的过程。

我想显示的效果如下,显示2024年中国各省5A级景区数量分布(不含港澳台)

会显示中文乱码的代码
python 复制代码
import matplotlib.pyplot as plt

# 数据
provinces = ['江苏', '浙江', '四川', '新疆', '河南', '广东', '湖北', '山东', '江西', '陕西', '安徽', '河北', '湖南', '重庆', '福建',
             '山西', '广西', '云南', '贵州', '北京', '吉林', '甘肃', '内蒙古', '海南', '辽宁', '黑龙江', '宁夏', '西藏', '上海', '青海', '天津']
num_5a = [26, 22, 18, 18, 17, 16, 16, 16, 15, 14, 13, 13, 12,
          12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 7, 6, 5, 5, 4, 2]

# 绘制柱状图
plt.figure(figsize=(12, 8))
plt.bar(provinces, num_5a, color='skyblue')

# 添加标题和标签
plt.title('2024年中国各省5A级景区数量分布(不含港澳台)', fontsize=16)
plt.xlabel('省份', fontsize=12)
plt.ylabel('5A级景区数量', fontsize=12)

# 显示数值 给每个柱子顶部标注具体的景区数量
# i 是每个柱子的位置(从0开始,对应省份的索引)
# v 是每个柱子的高度 (也就是 num_5a 里的值)
for i, v in enumerate(num_5a):
    plt.text(i, v + 0.5, str(v), ha='center', va='bottom',
             fontsize=10)

# 旋转x轴标签
plt.xticks(rotation=45)

# 显示图形
plt.tight_layout()
plt.show()

显示效果如图,中文显示乱码了

会乱码的代码解读
  1. 导入Matplotlib模块: matplotlib.pyplot 是 Python 中一个非常流行的绘图库,plt 是它的常用简称,用来创建各种图形(比如柱状图、折线图等)。
  2. 数据部分: provinces 是一个列表,里面存了中国各省的名字(不含港澳台),num_5a 也是一个列表,里面存了每个省对应的 5A 级景区数量,和 provinces 一一对应。比如江苏有 26 个,浙江有 22 个,等等
  3. 创建柱状图 :
    • plt.figure(figsize=(12,8)) 创建了一个画布,figsize设置画布大小,宽度为12, 高度8(单位是英寸)
    • plt.bar(provinces, num_5a, color='skyblue')绘制柱状图,provinces是x轴的数据(省份名字),num_5a是y轴的数据(景区数量),color='skyblue'设置柱子的颜色为天蓝色
  4. 添加标题和标签 plt.title 设置图表的标题,plt.xlabel 设置 x 轴的标签为"省份",plt.ylabel 设置 y 轴的标签为"5A 级景区数量",
  5. 在柱子上显示具体数字 plt.text(i, v + 0.5, str(v), ha='center', va='bottom',fontsize=10)
    • i是x坐标(柱子的位置),v+0.5 是y坐标(柱子高度加0.5,让数字显示在柱子顶部稍高一点)
    • str(v) 是要显示的文字 (把数字转为字符串) ha='center' 表示文字水平居中对齐 va='bottom' 表示文字要垂直底部对齐,
  6. 调整x轴标签 plt.xticks(rotation=45) 把x轴上的省份名字旋转45度。因为省份名字比较多,横着放会挤在一起,斜着放更清晰
  7. 美化并显示图形
    • plt.tight_layout() 自动调整图表的布局,避免标题、标签或柱子重叠,看起来更整洁
    • plt.show() 显示最终的图形,如果你在Jupyter Notebook 或 Python脚本里运行这段代码,就会弹出一个窗口,展示这个柱状图。
引入字体模块

我们要引入matplotlib.font_manager, 专门用来管理字体

python 复制代码
import matplotlib.font_manager as fm

设置字体

python 复制代码
font_path = "/System/Library/AssetsV2/com_apple_MobileAsset_Font7/3419f2a427639ad8c8e139149a287865a90fa17e.asset/AssetData/PingFang.ttc"
my_font = fm.FontProperties(fname=font_path)
  • font_path: 这里指定了一个字体文件的位置 (PingFang.ttc是一种支持中文的字体,常见于macOS系统)。它就像告诉程序: "我要用这个字体来显示中文。"
  • my_font = fm.FontProperties(fname=font_path): 这行创建了一个对象my_font, 告诉程序用这个字体来渲染文字。 这样图表里的中文标题和标签就不会变成乱码。
怎么知道要显示字体PingFang SC的路径呢(Mac系统PingFang SC)

比如我这里要用PingFang SC 来显示中文,怎么知道PingFang SC字体的路径呢,这是一个 macOS 终端命令,用于列出补充字体(Supplemental)目录下的所有字体文件

bash 复制代码
ls /System/Library/Fonts/Supplemental/
  • /System/Library/Fonts/Supplemental/:这是 macOS 的系统字体目录,存放了补充字体(Supplemental Fonts),包括各种 TrueType (.ttf) 和 OpenType (.otf) 字体。

看截图(未截全)虽然显示了很多字体,但是没有PingFang SC字体,试下下面这个命令

获取指定字体的路径(我的是MAC系统)
bash 复制代码
system_profiler SPFontsDataType | grep PingFang
  • system_profiler SPFontsDataType
    • system_profiler 是macOS内置的系统信息查询工具,可以获取硬件、软件和网络相关的信息
    • SPFontsDataType 是字体(Fonts)相关的数据类型,它会列出系统中的所有字体信息,包括字体名称、路径、格式、是否启动等
  • | grep PingFang
    • | (管道): 将system_profiler SPFontsDataType的输出结果传递给grep命令进行过滤
    • grep PingFang: 只筛选包含PingFang的行,避免输出过多无关信息

执行上面的命令就可以获取PingFang的字体路径了

使用我们设置的字体
python 复制代码
plt.title('2024年中国各省5A级景区数量分布(不含港澳台)', fontsize=16, fontproperties=my_font)
plt.xlabel('省份', fontsize=12, fontproperties=my_font)
plt.ylabel('5A级景区数量', fontsize=12, fontproperties=my_font)
...
for i, v in enumerate(num_5a):
    plt.text(i, v + 0.5, str(v), ha='center', va='bottom',
             fontsize=10, fontproperties=my_font)

再看下使用PingFang SC的效果

总结:

  1. 我们要使用matplotlib.font_manager的字体模块
  2. 我们要使用,能正确显示中文的字体,并且设置正确的字体路径
  3. 应用字体
python 复制代码
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm

# 确保使用正确的字体路径 创建了一个字体对象 my_font
font_path = "/System/Library/AssetsV2/com_apple_MobileAsset_Font7/3419f2a427639ad8c8e139149a287865a90fa17e.asset/AssetData/PingFang.ttc"
my_font = fm.FontProperties(fname=font_path)

# 数据
provinces = ['江苏', '浙江', '四川', '新疆', '河南', '广东', '湖北', '山东', '江西', '陕西', '安徽', '河北', '湖南', '重庆', '福建',
             '山西', '广西', '云南', '贵州', '北京', '吉林', '甘肃', '内蒙古', '海南', '辽宁', '黑龙江', '宁夏', '西藏', '上海', '青海', '天津']
num_5a = [26, 22, 18, 18, 17, 16, 16, 16, 15, 14, 13, 13, 12,
          12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 7, 6, 5, 5, 4, 2]

# 绘制柱状图
plt.figure(figsize=(12, 8))
plt.bar(provinces, num_5a, color='skyblue')

# 添加标题和标签,确保指定字体
plt.title('2024年中国各省5A级景区数量分布(不含港澳台)', fontsize=16, fontproperties=my_font)
plt.ylabel('5A级景区数量', fontsize=12, fontproperties=my_font)

# 旋转 x 轴标签,并应用中文字体
plt.xticks(rotation=45, fontproperties=my_font)

# 显示数值
for i, v in enumerate(num_5a):
    plt.text(i, v + 0.5, str(v), ha='center', va='bottom',
             fontsize=10, fontproperties=my_font)

# 显示图形
plt.tight_layout()
plt.show()
相关推荐
蹦蹦跳跳真可爱58912 分钟前
Python----计算机视觉处理(Opencv:自适应二值化,取均值,加权求和(高斯定理))
人工智能·python·opencv·计算机视觉
dreadp22 分钟前
使用 OpenSSL 和 Python 实现 AES-256-CBC 加密与解密(安全密钥管理)
python·安全·网络安全·密码学·openssl
IT北辰1 小时前
《用 python、MySQL 和 Chart.js 打造炫酷数据看板》实战案例笔记
python
weixin_307779131 小时前
PyTorch调试与错误定位技术
开发语言·人工智能·pytorch·python·深度学习
魔障阿Q1 小时前
Yolo-Uniow开集目标检测本地复现
人工智能·python·yolo·目标检测·计算机视觉
用户9704438781161 小时前
如何在自己的网站接入API接口获取数据
人工智能·python·开源
_丿丨丨_1 小时前
Django下防御Race Condition
网络·后端·python·django
正经教主2 小时前
【菜鸟飞】Conda安装部署与vscode的结合使用
运维·vscode·python·conda
轻松Ai享生活2 小时前
5 Python 技巧,让你秒变大神
python
Ronin-Lotus3 小时前
深度学习篇---Opencv中的机器学习和深度学习
python·深度学习·opencv·机器学习