我的Python心路历程 第十期 (10.8 股票实战之数据可视化中文显示问题)

我的Python心路历程 第十期 (10.8 股票实战之数据可视化中文显示问题)

plt图中显示中文是常见用法,但似乎调试起来没那么容易呢。见初始代码:

    #展示效果设置
    plt.figure('SNS图例', figsize=(18, 5))

编译错误UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 3: ordinal not in range(128)

调试编译时截图如下:
我的Python心路历程 第十期 (10.8 股票实战之数据可视化中文显示问题)_第1张图片

首先,看看坐标中文显示方法。增加字体配置后的代码如下:

#字体配置
from pylab import *
from matplotlib.font_manager import FontProperties
#定义字体属性
font = FontProperties(fname=r"/System/Library/AssetsV2/com_apple_MobileAsset_Font6/4c66b413a81d594dc2fc430266c1629c30a5237b.asset/AssetData/STFANGSO.ttf", size=14)  # “”里面为字体的相对地址 或者绝对地址

......

#测试中文
def testChinese():

    plt.figure()
    plt.xlabel(u"横坐标名称", fontproperties=font)
    plt.ylabel(u"纵坐标名称", fontproperties=font)
    plt.title(u"题目", fontproperties=font)
    plt.plot([1,2,6,4], [4,5,6,9])
    plt.show()
    return

运行效果如下图所示:
我的Python心路历程 第十期 (10.8 股票实战之数据可视化中文显示问题)_第2张图片

需要说明的是,如果设置font时只是写字体文件名的话,那么编译会报错IOError: [Errno 2] No such file or directory: 'STFANGSO.ttf'。搜索对应字体文件并查询路径名后给予绝对路径后问题得以解决。

另外,有中文字符的代码必须使用u"算法",否则会编译报错UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 0: ordinal not in range(128)
错误代码如下:

    plt.title(u"题目", fontproperties=font)
    plt.plot([1,2,6,4], [4,5,6,9], marker='.', label="算法")
    plt.show()

label处报错,优化后并加上标题和label中文代码如下:

#测试中文
def testChinese():

    plt.figure(u"测试图例")
    plt.xlabel(u"横坐标名称", fontproperties=font)
    plt.ylabel(u"纵坐标名称", fontproperties=font)
    plt.title(u"题目", fontproperties=font)
    plt.plot([1,2,6,4], [4,5,6,9], marker='.', label=u"算法")
    plt.show()
    return

运行效果如下图所示:
我的Python心路历程 第十期 (10.8 股票实战之数据可视化中文显示问题)_第3张图片

尽管编译通过了,但奇怪的是label并没有显示。

接下来,研究一下图中注释的中文显示方法。
细心朋友就会发现上图中label未显示,改为英文试试看效果。

    plt.plot([1,2,6,4], [4,5,6,9], marker='.', label='label xxx')

运行结果表明label根本就没生效,何谈中文。是不是只有一个label的缘故呢?增加一个试试看。代码如下:

    x = [1,2,3,4,5,6,7]
    y1 = [4,5,6,9,5,6,7]
    y2 = [5, 6, 7,4,5,6,9]
    plt.plot(x, y1, color='r', linestyle='--', marker='>', label="shanghai")
    plt.plot(x, y2, color='b', linestyle='--', marker='.', label='shenzhen')

    plt.legend()

运行效果图如下:
我的Python心路历程 第十期 (10.8 股票实战之数据可视化中文显示问题)_第4张图片

看来真的是只有一个无法显示label,显示的意义似乎也不大。

最后,直接更改label为中文。

    plt.plot(x, y1, color='r', linestyle='--', marker='>', label=u"上海")
    plt.plot(x, y2, color='b', linestyle='--', marker='.', label=u'深圳')

效果截图:
我的Python心路历程 第十期 (10.8 股票实战之数据可视化中文显示问题)_第5张图片

label显示是乱码,看来上面的字体设置方法不适用于图中中文显示。

为了实现中文也是醉了。查看了很多资料发现是字体库的事。
第一步,下载SimHei字体库。
第二步,将下载的字体库放在'/Downloads/python/gupiao/venv/lib/python2.7/site-packages/matplotlib/mpl-data/fonts/ttf'文件夹中。
第三步,修改matplotlibrc配置文件。(路径为“/Downloads/python/gupiao/venv/lib/python2.7/site-packages/matplotlib/mpl-data”下,建议先备份一个)
1、使用文本编辑器打开matplotlibrc 文件,找到font.family,并将font.family和font.sans-serif两行前的#删除;
2、在font.sans-serif后添加中文字体SimHei,其他的不变;
我的Python心路历程 第十期 (10.8 股票实战之数据可视化中文显示问题)_第6张图片

3、可以修改axes.unicode_minus,将True改为False,作用就是解决负号’-'显示为方块的问题。
我的Python心路历程 第十期 (10.8 股票实战之数据可视化中文显示问题)_第7张图片

4、修改完配置文件重启Python,在主任务代码中添加这几行代码:

#支持中文,让plot中的label也能用中文,即图表中的中文显示问题
mpl.rcParams['font.sans-serif'] = ['SimHei']    #['DejaVu Sans']
mpl.rcParams['axes.unicode_minus'] = False

第四步,编译依然报错,修改font_manager.py (所在路径为“/Users/xxxxx/Downloads/python/gupiao/venv/lib/python2.7/site-packages/matplotlib/font_manager.py”)
截图如下:(3.8供参考)
我的Python心路历程 第十期 (10.8 股票实战之数据可视化中文显示问题)_第8张图片

具体修改操作是:打开文件后直接找 self.defaultFamily,进行修改为我们的 SimHei 文件,注意那个 afm 要保留,它是另一种字体文件。
将文件中的DejaVu Sans修改成SimHei:
修改前:

        self.defaultFamily = {
            'ttf': 'DejaVu Sans',
            'afm': 'Helvetica'}
        self.defaultFont = {}

        for fname in self.ttffiles:
            _log.debug('trying fontname %s', fname)
            if fname.lower().find('DejaVuSans.ttf')>=0:
                self.defaultFont['ttf'] = fname
                break

修改后:

        self.ttffiles = findSystemFonts(paths) + findSystemFonts()
        self.defaultFamily = {
            'ttf': 'SimHei',#DejaVu Sans',
            'afm': 'Helvetica'}
        self.defaultFont = {}

        for fname in self.ttffiles:
            _log.debug('trying fontname %s', fname)
            if fname.lower().find('SimHei.ttf')>=0:
                self.defaultFont['ttf'] = fname
                break

运行结果依然是乱码,编译错误为UserWarning: findfont: Font family [u'sans-serif'] not found. Falling back to DejaVu Sans (prop.get_family(), self.defaultFamily[fontext]))

第五步,如上编译错误可以断定设置未起作用,多半是缓存影响,故决定清缓存。
在python console中执行代码

import matplotlib
matplotlib.get_cachedir()

找到缓存路径。
在这里插入图片描述

在python terminal中执行rm -rf 路径来清楚缓存。
我的Python心路历程 第十期 (10.8 股票实战之数据可视化中文显示问题)_第9张图片

重新编译ok。
在这里插入图片描述

执行结果如下:我的Python心路历程 第十期 (10.8 股票实战之数据可视化中文显示问题)_第10张图片

哦耶,要的就是这个效果!

你可能感兴趣的:(python)