在嵌入式设备上(树莓派)动态显示带有中文字体的图片(采用matplotlib绘图)

1.运行环境

树莓派3B+
#***********************************#

2.创建一个PyQt界面

2.1配置Qt5、PyQt5

在树莓派的terminal中输入命令sudo apt-get update更新一下树莓派(在这个过程中确保良好的网络连接)
然后执行命令sudo apt-get install qt5-default安装Qt5
最后执行sudo apt-get inastall python3-pyqt5安装PyQt5

2.2 创建界面的代码
import sys
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtWidgets import *

class picture(QWidget):
    def __init__(self):
        super(picture, self).__init__()
        # resize()方法可以改变窗口控件的大小,在这里设置设置窗口的宽度为600像素
        # 宽度为400像素
        self.resize(600, 400)
        self.setWindowTitle("label显示图片")

        self.label = QLabel(self)
        self.label.setText("  显示图片")
        self.label.setFixedSize(191, 152)
        # move(x,y)方法设置控件的位置
        self.label.move(160, 160)

        self.label.setStyleSheet("QLabel{background:;}"
                                 "QLabel{color:rgb(300,300,300,120);font-size:10px;font-weight:bold;font-family:宋体;}"
                                 )

        btn = QPushButton(self)
        btn.setText("快点我")
        btn.move(220, 330)
        btn.clicked.connect(self.on_image)

    def on_image(self):
    	pass
if __name__ == "__main__":
    '''
    每一个PyQt5程序都需要有一个QApplication对象,QApplication类包含在QTWidget中
    sys.argv 是一个命令行参数列表。Python脚本可以从Shell中执行
    '''
    app = QtWidgets.QApplication(sys.argv)
    my = picture()
    my.show()
    sys.exit(app.exec_())

3. 采用matplotlib动态绘制图片并保存为图片

总体的思路是首先用matplotlib绘制五角雷达图,然后保存为png图片。
在这个过程中出现了图片显示中文不正常的现象,如图所示
在嵌入式设备上(树莓派)动态显示带有中文字体的图片(采用matplotlib绘图)_第1张图片

3.1 在windows中,参考了很多的网页,比较靠谱点的就是这篇文章了https://blog.csdn.net/lvshu_yuan/article/details/80413005

依据文章所述,采用了动态修改配置的方法,即在代码的最前面面添加

from pylab import *
mpl.rcParams['font.sans-serif'] = ['SimHei'] #显示中文字体(windows操作系统中)
mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题,或者转换负号为字符串

在嵌入式设备上(树莓派)动态显示带有中文字体的图片(采用matplotlib绘图)_第2张图片
成功解决了matplotlib在绘制图形时显示中文不正确的问题,第二种方法没有测试

3.2 在树莓派中采用matplotlib绘图,显示中文字体

在树莓派上运行上述代码,直接抛出错误findfont: Font family ['sans-serif'] not found. Falling back to DejaVu Sans而且中文字体显示不成功。

3.2.1树莓派中查看matplotlib的字体文件
###本步骤的目的主要是查看树莓派的matplotlib软件包的字体库文件所在的位置
#在树莓派的命令行(terminal)中依次输入
import matplotlib
print(matplotlib.matplotlib_fname())

得到路径/etc/matplotlibrc
在terminal中继续输入exit()退出python的编辑
然后进入matplotlibrc文件sudo nano /etc/matplotlibrc得到下图
在这里插入图片描述
在树莓派的提供的matplotlib字体family一共有5个分别是font.serif font.sans-serif font.cursive font.fantasy font.monospace,而且在字体family中并没有中文字体,这也是抛出上述错误的原因

3.2.2 解决方案
  1. 在Goole浏览器中下载下载字体文件或是直接从百度网盘中获取微软雅黑的字体文件 https://pan.baidu.com/s/1xs8ZAxU_QN8hWc30_gEkBQ 提取码:wykj
  2. 通过File Zilla软件https://www.filezilla.cn/download/server(下载链接)将字体文件msyh.ttl和文件msyhbd.ttl移到树莓派的桌面上。操作如图所示,操作过程注意树莓派和电脑连接同一个手机的热点在嵌入式设备上(树莓派)动态显示带有中文字体的图片(采用matplotlib绘图)_第3张图片
    3.将字体文件复制到路径/usr/share/fonts/truetype/freefont/下,至于为什么要移到这个路径下,我也不是很清楚,可能是为了方便管理吧。具体操作如下:
    在嵌入式设备上(树莓派)动态显示带有中文字体的图片(采用matplotlib绘图)_第4张图片
3.3 利用matplotlib绘制图片,Python脚本如下所示
  1. 调用msyh字体myfont = fm.FontProperties(fname='/usr/share/fonts/truetype/freefont/msyh.ttf')
  2. 修改ax.set_thetagrids函数------->ax.set_thetagrids(angles * 180 /np.pi, fontproperties=myfont, fontsize=7)
  3. 利用matplotlib绘制图并保存成png图片的所有代码如下
import numpy as np
import matplotlib.pyplot as plt
from pylab import *

# 字体
font = {
    'family': 'Microsoft YaHei',
    'style': 'italic',
    'weight': 'normal',
    'color': 'black',
    'size': 12,
}

class RadarImage():
    def __init__(self):
        pass

    def plot_radar(self,data):

        criterion = [1, 1, 1, 1, 1, 1] # 基准雷达图
        angles = np.linspace(0, 2 * np.pi, 5, endpoint=False)
        angles = np.concatenate((angles, [angles[0]]))
        myfont = fm.FontProperties(fname='/usr/share/fonts/truetype/freefont/msyh.ttf') #在树莓派平台上显示中文字体
        # 设置绘制图片的大小一定要放到所有代码的前面
        fig = plt.figure(dpi=100, figsize=(1.91, 1.52)) # 确定所绘制图片的dpi和大小
        ax = fig.add_subplot(111, polar=True)  # 设置坐标为极坐标
        # 绘制三个五边形
        floor = 0
        ceil = 2
        labels = np.array(['苹果', '桃子', '橘子', '橙子', '香蕉'])
        # 绘制五边形的循环
        for i in np.arange(floor, ceil + 0.5 ,0.5):
            ax.plot(angles, [i] * (6), '-', lw= 0.5, color='black')
        for i in range(5):
            ax.plot([angles[i], angles[i]], [floor, ceil], '-',lw=0.5, color='black')
         # 绘制雷达图
        ax.plot(angles, criterion, 'b-', lw=2, alpha=0.4)
        ax.fill(angles, criterion, facecolor='b', alpha=0.3) #填充
        ax.plot(angles, data, 'b-', lw=2, alpha=0.35)
        ax.fill(angles, data, facecolor='b', alpha=0.25)

        ax.set_thetagrids(angles * 180 /np.pi, fontproperties=myfont, fontsize=7)
        ax.spines['polar'].set_visible(False)#不显示极坐标最外的圆形
        ax.set_theta_zero_location('N')#设置极坐标的起点(即0度)在正上方向
        ax.grid(False)# 不显示分隔线
        ax.set_yticks([]) # 不显示坐标间隔
        # 保存文png图片
        plt.subplots_adjust(left=0.1, right=0.9, wspace=0.25, hspace=0.25, bottom=0.13, top=0.81)
        plt.savefig('a_1.png')
        #plt.show()
        pass

4. 界面程序和matplotlib程序的融合

import sys
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtWidgets import *
import chart_2  #引入matplotlib程序的.py文件  chart_2 为matplotlib绘制png图片的文件名

class picture(QWidget):
    def __init__(self):
        super(picture, self).__init__()
        # resize()方法可以改变窗口控件的大小,在这里设置设置窗口的宽度为600像素
        # 宽度为400像素
        self.resize(600, 400)
        self.setWindowTitle("label显示图片")

        self.label = QLabel(self)
        self.label.setText("  显示图片")
        self.label.setFixedSize(191, 152)
        # move(x,y)方法设置控件的位置
        self.label.move(160, 160)

        self.label.setStyleSheet("QLabel{background:;}"
                                 "QLabel{color:rgb(300,300,300,120);font-size:10px;font-weight:bold;font-family:宋体;}"
                                 )

        btn = QPushButton(self)
        btn.setText("快点我")
        btn.move(220, 330)
        btn.clicked.connect(self.on_image)

    def on_image(self):
        radar = chart_2.RadarImage()  #  创建对象
        data = [0.8, 0.9, 1.2, 1.0, 1.5, 0.8]  #数据的传入
        radar.plot_radar(data= data) #   实例化
        #在Qt界面的label中显示图片
        img = QtGui.QPixmap('a_1.png').scaled(self.label.width(), self.label.height())
        self.label.setPixmap(img)


if __name__ == "__main__":
    '''
    每一个PyQt5程序都需要有一个QApplication对象,QApplication类包含在QTWidget中
    sys.argv 是一个命令行参数列表。Python脚本可以从Shell中执行
    '''
    app = QtWidgets.QApplication(sys.argv)
    my = picture()
    my.show()
    sys.exit(app.exec_())

5. 在树莓派上的运行结果

在嵌入式设备上(树莓派)动态显示带有中文字体的图片(采用matplotlib绘图)_第5张图片

在嵌入式设备上(树莓派)动态显示带有中文字体的图片(采用matplotlib绘图)_第6张图片

你可能感兴趣的:(python3,树莓派)