Matplotlib用fontproperties设置xtick字体仅首个生效,日语标签显示异常
日语标签柱状图仅首个xtick字体生效问题说明
问题现象
- 绘制xtick标签为日语的柱状图时,首先触发
RuntimeWarning: Glyph <对应字符编码> missing from current font运行时警告 - 定位到
xticks方法支持fontproperties参数传入自定义字体后,按最小复现代码测试时,仅第一个xtick标签能正确应用指定字体,其余所有后续标签仍显示缺字方框
最小复现代码
import pandas as pd import matplotlib.pyplot as plt import matplotlib.font_manager as fm fprop = fm.FontProperties(fname='NotoSansCJKjp-Regular.otf') d = {'a': {'ほげイ': 5250.0, 'ほげロ': 1497.0, 'ほげハ': 810.0}, 'b': {'ほげイ': 1707.0, 'ほげロ': 507.0, 'ほげハ': 305.0}} df_foo = pd.DataFrame.from_dict(d) df_foo.plot(kind='bar') plt.xticks(fontproperties=fprop, fontsize=15) plt.show()
问题根源
- pandas调用
DataFrame.plot(kind='bar')生成柱状图时,会为每个xtick位置提前创建独立的文本对象,这些对象在初始化阶段就绑定了matplotlib的全局默认字体(不含日文字形) plt.xticks()方法传入fontproperties参数时,仅会修改方法返回值对应的首个xtick对象的字体属性,不会批量覆盖所有已创建的xtick文本的字体配置,因此就出现了仅首个标签生效、其余标签缺字的问题
解决方法
方式1:全局配置默认字体(推荐)
直接将指定日文字体设置为matplotlib的全局默认字体,所有文本元素(xtick、ytick、标题、坐标轴标签等)都会自动应用该字体,无需单独给每个元素传字体参数,示例代码:
import pandas as pd import matplotlib.pyplot as plt import matplotlib.font_manager as fm # 加载指定日文字体 fprop = fm.FontProperties(fname='NotoSansCJKjp-Regular.otf') # 将该字体设置为matplotlib全局默认字体 plt.rcParams['font.family'] = fprop.get_name() d = {'a': {'ほげイ': 5250.0, 'ほげロ': 1497.0, 'ほげハ': 810.0}, 'b': {'ほげイ': 1707.0, 'ほげロ': 507.0, 'ほげハ': 305.0}} df_foo = pd.DataFrame.from_dict(d) df_foo.plot(kind='bar') # 无需再单独传入fontproperties,所有标签自动适配字体 plt.xticks(fontsize=15) plt.show()
方式2:批量遍历xtick标签设置字体
如果不想改动全局字体配置,可以直接遍历当前坐标轴下的所有xtick标签对象,逐个绑定自定义字体属性,示例代码:
# 原有绘图逻辑 df_foo.plot(kind='bar') # 获取当前激活的坐标轴对象 ax = plt.gca() # 遍历所有xtick标签,逐个应用字体和字号设置 for xtick_label in ax.get_xticklabels(): xtick_label.set_fontproperties(fprop) xtick_label.set_fontsize(15) plt.show()
内容的提问来源于stack exchange,提问作者hogegoo
相关产品推荐
相关产品推荐

