大家好,我是东哥,你身边放心的香港保险顾问。

最近给客户做香港储蓄险的提取演示,觉得用图表是个不错的方案。

比数据更直观。

但提取演示的表格制作比较费事儿,就琢磨用Python把它给自动化。

结果,第一步matplotlib,就出了问题。

什么问题?

1

乱码。

还是乱码

不显示中文。

就比如下面这个。

本来是想做个演示,前五年每年存4万,一共存20万。

从第22年开始,就每年提4万,可以提取终身。

到最后保单价值还有60万。

就很High。

结果乱码……

啊天,什么效果都没有了。

2

怎么回事儿?

原来matplotlib默认使用的字体,不支持中文字符。

什么字体?

DejaVu Sans。

这是一个开源的无衬线字体,包含广泛的字符集和良好的可读性。

就像下面这样。

问题是,它支持语言很有限。

主要支持欧美国家的字母系统语言。

东亚地区的语言,就不行了。

比如中文。

怎么办?

换个支持中文的字体。

比如东哥就比较喜欢用微软雅黑(Microsoft YaHei)。

具体怎么做?

在脚本中使用matplotlib的rcParams来指定字体。

比如

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False

这里面

  • 第一句,导入了matplotlib。

  • 第二句,用rcParams字典,指定绘图字体为微软雅黑

  • 第三句,用rcParams字典,指定负号不要用Unicode的负号。

这个第三句,是什么意思?

在某些东亚字体中,负号可能会被显示为全角字符。

宽度与汉字相同的字符。

和我们常用的半角的ASCII减号,看起来就很不一样。

影响美观和清晰度。

通过设置plt.rcParams['axes.unicode_minus'] = False,会让matplotlib在渲染负数时使用半角字符。

这样可以确保在任何字体下,负号都能正确显示,并且与数字之间有适当的间距。

从而保证图表中的一致性和专业外观。

3

通过以上设置,保单的提取图示,终于正常了。

X轴表示保单年度。

X轴下面的竖杠,表示缴纳的保费,一共交了5年。

曲线表示保单价值。

蓝色的竖杠,表示每年从保单里面提取的金额。

前面5年,每年交4万,一共交了20万。

然后保单就不断升值。

后面即使一直在提取,每年提4万,保单的价值依然在往上走。

吼吼,稳定的永续现金流啊。

要不要来一单

4

进一步,我们探讨一下微软雅黑这个字体。

在比较新的Windows系统中,微软雅黑(Microsoft YaHei)的字体文件通常有两个版本。

一个是常规版,另一个是 UI 版。即

  • 常规版:msyh.ttc

  • UI 版:msyhbd.ttc

这里,“.ttc” 是 字体文件的扩展名,类似Word文件的docx。

这些字体文件通常位于C:\Windows\Fonts目录下。

通常情况下我们提到微软雅黑的时候,指的都是常规版。

当我们运行plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']的时候,Python就会去系统中寻找微软雅黑。

问题是,Microsoft YaHei是怎么和msyh.ttc关联起来的?

这就涉及到字体名和文件名的关联及区别。

字体名称是用户界面中显示的名字,比如微软雅黑或Microsoft YaHei。

文件名是存储在文件系统中的实际文件的名称。

字体文件,比如刚才说的msyh.ttc,既包含字体的长相,也包含字体名称在内的元数据。

当Python请求Microsoft YaHei时,Windows会匹配请求和元数据,来定位和加载对应的字体文件。

那我们刚才,用的是英文名。

改成中文名可不可以?

比如

plt.rcParams['font.sans-serif'] = ['微软雅黑']

可以。

字体文件中同时包含了中文名和英文名。

所以两者都可以通用。

但为了更加国际化,比如考虑可能得其他语言环境中使用,还是用英文名更好一些。

毕竟,整套编程系统用的都是英文呢。

关注东哥,保护中产财富,一起慢慢变富。

东哥目前提供如下服务,有需要的朋友欢迎微信来撩。

  • ,大家一起讨论读书、成长及赚钱;

  • 添加东哥微信:jetorz ,领取约30万字的《东哥在湾区》2023年历史文章合集电子版;