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()
显示效果如图,中文显示乱码了
会乱码的代码解读
- 导入Matplotlib模块: matplotlib.pyplot 是 Python 中一个非常流行的绘图库,plt 是它的常用简称,用来创建各种图形(比如柱状图、折线图等)。
- 数据部分: provinces 是一个列表,里面存了中国各省的名字(不含港澳台),num_5a 也是一个列表,里面存了每个省对应的 5A 级景区数量,和 provinces 一一对应。比如江苏有 26 个,浙江有 22 个,等等
- 创建柱状图 :
- plt.figure(figsize=(12,8)) 创建了一个画布,figsize设置画布大小,宽度为12, 高度8(单位是英寸)
- plt.bar(provinces, num_5a, color='skyblue')绘制柱状图,provinces是x轴的数据(省份名字),num_5a是y轴的数据(景区数量),color='skyblue'设置柱子的颜色为天蓝色
- 添加标题和标签 plt.title 设置图表的标题,plt.xlabel 设置 x 轴的标签为"省份",plt.ylabel 设置 y 轴的标签为"5A 级景区数量",
- 在柱子上显示具体数字 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' 表示文字要垂直底部对齐,
- 调整x轴标签 plt.xticks(rotation=45) 把x轴上的省份名字旋转45度。因为省份名字比较多,横着放会挤在一起,斜着放更清晰
- 美化并显示图形
- 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
的效果
总结:
- 我们要使用matplotlib.font_manager的字体模块
- 我们要使用,能正确显示中文的字体,并且设置正确的字体路径
- 应用字体
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()