Python做数据可视化的时候,Matplotlib是常用的一款工具。在绘制图表的时候,设置坐标轴的标签能使图表有更好的可读性。然而,在实际使用中,标签中文不能正常显示是一个常见的问题,如下图:
对应的代码如下:
import matplotlib.pyplot as plt
input_values = [1, 2, 3, 4, 5]
squares = [1, 4, 9, 16, 25]
fig, ax = plt.subplots()
ax.plot(input_values, squares, linewidth=3)
# 设置图表标题并给坐标轴加上标签
ax.set_title("平方数", fontsize=24)
ax.set_xlabel("值", fontsize=14)
ax.set_ylabel("值的平方", fontsize=14)
# 设置刻度标记的大小
ax.tick_params(axis='both', labelsize=14)
plt.show()
如图所示,图表的标题,坐标轴的标签中文均不能正常显示。 分析发现是因为默认字体不支持中文。这个问题通常有几种解决方法:方法 1:指定支持中文的字体(推荐),方法 2:动态指定字体(适用于临时修改),方法 3:使用自定义字体文件(适用于特殊字体)。本文主要介绍方法1如何解决这个问题。
首先,查看系统可用字体:
import matplotlib.font_manager as fm
fonts = fm.findSystemFonts()
print([f for f in fonts if 'hei' in f.lower() or 'yahei' in f.lower()])
运行结果:
E:\PycharmProjects\pythonProject1\venv\Scripts\python.exe E:/PycharmProjects/pythonProject1/chapter15/find_font.py
['C:\\Windows\\Fonts\\simhei.ttf']
Process finished with exit code 0
查看发现可以设置为黑体字,修改后代码:
import matplotlib.pyplot as plt
input_values = [1, 2, 3, 4, 5]
squares = [1, 4, 9, 16, 25]
# 设置字体
plt.rcParams['font.sans-serif'] = ['SimHei']
fig, ax = plt.subplots()
ax.plot(input_values, squares, linewidth=3)
# 设置图表标题并给坐标轴加上标签
ax.set_title("平方数", fontsize=24)
ax.set_xlabel("值", fontsize=14)
ax.set_ylabel("值的平方", fontsize=14)
# 设置刻度标记的大小
ax.tick_params(axis='both', labelsize=14)
plt.show()
运行后,中文显示正常,如图:
本文至此应该结束了,但是后面又出现一个小插曲,在改进图表显示效果的过程中,使用plt.style.use('seaborn'),设置背景色、网格线等时,中文又无法正常显示了,如图;
分析问题,发现调用 plt.style.use('seaborn') 后,matplotlib 会加载 seaborn 主题的默认样式,其中包括重新设置字体(覆盖了之前手动设置的 rcParams)。因此,中文再次显示为乱码。解决这个问题,可以在 plt.style.use() 之后重新设置字体,代码如下:
import matplotlib.pyplot as plt
input_values = [1, 2, 3, 4, 5]
squares = [1, 4, 9, 16, 25]
plt.style.use('seaborn')
# 设置字体
plt.rcParams['font.sans-serif'] = ['SimHei']
fig, ax = plt.subplots()
ax.plot(input_values, squares, linewidth=3)
# 设置图表标题并给坐标轴加上标签
ax.set_title("平方数", fontsize=24)
ax.set_xlabel("值", fontsize=14)
ax.set_ylabel("值的平方", fontsize=14)
# 设置刻度标记的大小
ax.tick_params(axis='both', labelsize=14)
plt.show()
执行后,中文正常显示,如图:
至此,上述问题解决了。