python+pyecharts+pyqt打造疫情实时追踪可视化系统

项目简介

利用python爬取腾讯疫情实时播报数据,接着用pyecharts处理数据,生成相应的疫情分布图、疫情发展趋势图,最后利用pyqt打造一个GUI程序。
ps:如果不是老师要求,我基本不会写这么一篇博客,路过的就直接跳过吧。这篇博客只是等待老师的宠幸。(卑微咸鱼的自白)

工具安装

python安装

emmmm!要用python开发系统,肯定要安装python开发环境了,直接百度python3 安装,有很多教程很详细,直接安装就好了。

pycharm安装

pycharm是一个集成开发环境,可以直接到官网安装,有免费的社区版可以用,就是不知道社区版可不可以弄扩展工具,如果不可以的话,就得花钱买正版(自己想办法),安装成功后就可以使用了。

pyqt安装

这个安装比较复杂,我建议直接在pycharm里面安装。具体步骤如下:
1、打开pycharm;
2、点击下图我圈红色的那个file
python+pyecharts+pyqt打造疫情实时追踪可视化系统_第1张图片
3、点击file后,可以看到红色圈着的setting,点击setting
python+pyecharts+pyqt打造疫情实时追踪可视化系统_第2张图片
5、点击setting,先找到圈黑色笔的,然后找到圈红色笔的
python+pyecharts+pyqt打造疫情实时追踪可视化系统_第3张图片
6、然后开始搜索pyqt5、pyqt5-tools、qtpy、pyqtWebengine、把这些通通安装

工具配置

安装完以上工具差不多就可以配置了,步骤如下(接下来可能会遇到及其令你摸不着头脑的事儿)
1、打开pycharm;
2、点击菜单栏的file;
3、找到setting;
4、点击Tools,按照图片先找到黑色再点击红色的;
python+pyecharts+pyqt打造疫情实时追踪可视化系统_第4张图片
5、按照图片设置,name那一项随你填,知道这个扩展工具干啥的就行,program哪一个要找准位置,是你的可执行文件的路径,qtdesigner不用参数,后面两个的argument要填这个参数,具体看图片,参数在最后一张截图。路径一般都差不多,搜索pyqt安装教程一般都能找到。
python+pyecharts+pyqt打造疫情实时追踪可视化系统_第5张图片
python+pyecharts+pyqt打造疫情实时追踪可视化系统_第6张图片
python+pyecharts+pyqt打造疫情实时追踪可视化系统_第7张图片
python+pyecharts+pyqt打造疫情实时追踪可视化系统_第8张图片
6、安装完点击菜单栏的Tools,点击子菜单External Tools,点击qtdesigner,能成功打开就好了,一般会遇到说是无法驱动qt的程序,对于这个问题直接百度答案也是鱼龙混杂,我的解决方法是参照一篇文章链接: link.

开始开发

开始开发之前,放几张效果图。
python+pyecharts+pyqt打造疫情实时追踪可视化系统_第9张图片
python+pyecharts+pyqt打造疫情实时追踪可视化系统_第10张图片
python+pyecharts+pyqt打造疫情实时追踪可视化系统_第11张图片
python+pyecharts+pyqt打造疫情实时追踪可视化系统_第12张图片
python+pyecharts+pyqt打造疫情实时追踪可视化系统_第13张图片
python+pyecharts+pyqt打造疫情实时追踪可视化系统_第14张图片

整体思路是这样子的,点击按钮,触发相应的爬虫程序,爬取数据,生成html,然后利用webview渲染出来,(这个项目我同时又拿去交给另一个要求我们开发qt项目的老师了。)

前端界面开发

利用qt设计师模式设计界面

首先,如果你工具安装了,也同时配置了,那么你可以在pycharm中打开qtdesigner,进行页面设计,要怎么设计就怎么设计噢,随你个人喜欢,因为qtdesigner已经移除了对web组件的支持,所以可以随便弄个组件代替它来定位,到时 修改就好了。
这里我附上我自己设计的,之所以多了一个关闭按钮,主要是因为我后期想要把窗口的标题栏去掉,之所以要隐藏标题栏是因为我不会重写mainwindow类,而且qdarkstyle不支持美化标题栏。
python+pyecharts+pyqt打造疫情实时追踪可视化系统_第15张图片
做完之后保存到python项目里,会发现项目里多了一个ui文件。

将ui文件生成py文件

接下来,选中ui文件,点击external tools,点击pyUIC,这时就会生成一个py文件了,这个文件实现了界面的效果,当然你现在还不可以使用。
python+pyecharts+pyqt打造疫情实时追踪可视化系统_第16张图片

前后端分离+qdarkstyle美化

这时候呢,你可以开始创建启动页面的py文件了,首先新建一个python文件,命名为Call+你ui文件保存的名字,然后,创建一个类,具体看代码:

import 由ui文件生成的py文件
import sys
class MyMainWin(QMainWindow, Ui_MainWindow):
    flag = 0
    def __init__(self, parent=None):
        super(MyMainWin, self).__init__(parent)
        self.setupUi(self)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = MyMainWin()
    win.show()
    sys.exit(app.exec_())

然后运行程序就可以看到你之前设计的界面,这个时候你的程序还是没什么美化的,如果你想自己写样式,可以网上搜索qstylesheet,自己美化,或者可以去网上下载开源的qdarkstyle样式表美化,下载完把qstyledark文件夹复制到项目里,然后修改代码为:

import sys
import qdarkstyle
import 由ui文件生成的py文件
class MyMainWin(QMainWindow, Ui_MainWindow):
    flag = 0
    def __init__(self, parent=None):
        super(MyMainWin, self).__init__(parent)
        self.setupUi(self)
 
 if __name__ == "__main__":
    app = QApplication(sys.argv)
    # app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
    win = MyMainWin()
    # 加载样式
    win.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
    win.show()
    sys.exit(app.exec_())

这时候运行就可以看到美化后的界面了。我实在太懒了不像放图了。
接下来我们要把前面有ui文件生成的py文件修改了,注意一旦生成后就不要随意使用qt设计师模式修改页面了,否则代码又会重新生成的。
找到你想替换成web组件的组件,讲组件修改为web组件。这样运行程序就会得到一个浏览器窗口了。

后台逻辑开发

以上开发出了界面,但是各种功能按钮都是没有用的,接下来你要做的就是做好逻辑功能的开发,废话不说,代码都写得很详细,直接上了。
生成中国疫情分布图情况的代码

'''
作者:谢思凌
时间:2020/06/17
'''

# 导入请求发送模块
import requests
# 导入json模块
import json
# 导入 xlrd模块解析excel表格
import xlrd
# 导入pyecharts
from pyecharts import Map
# 导入datetime模块
import datetime
# 请求中国疫情数据链接
def creatMap():
    # 获取当前时间
    curr_time = datetime.datetime.now()
    # 格式化时间
    time_str = curr_time.strftime("%Y-%m-%d %H:%M:%S")
    baseUrl = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5&callback=jQuery3410966110964980829_1592350653305&_=1592350653306'
    # 获取当前链接返回的数据
    chinaData = requests.get(baseUrl).text.replace('"{', '{').replace('}"}', '}}').replace('\\', '')
    # 处理数据
    chinaData = chinaData[chinaData.index("{"):-1]
    # 将当前的json字符串转化为python字典
    baseData = json.loads(chinaData)
    # 保存省份的名称
    provinceNameList = []
    # 保存各个省份的确诊数据
    provinceConfirmDataList = []
    # 从数据中提取各个省份的疫情信息
    provinceList = baseData["data"]["areaTree"][0]["children"]
    for province in provinceList:
        provinceNameList.append(province["name"])
        provinceConfirmDataList.append(province["total"]["confirm"])
    # 创建地图
    map = Map(title="中国疫情分布图 "+time_str, width=800, height=400, title_color="red")
    # 添加地图相关参数
    map.add("中国地图", provinceNameList, provinceConfirmDataList, maptype="china",
            visual_range=[1, 1000], visual_text_color="#000", is_visualmap=True)
    # 显示地图配置参数
    #map.show_config()
    # 渲染地图
    map.render(path="output/中国疫情分布图.html")
    # print("已生成,请移步output文件夹查看")

生成中国疫情发展趋势图的代码

# 导入json
import json
# 导入request
import requests
# 导入pyecharts模块的Line
from pyecharts import Line
# 导入datetime模块
import datetime
# 创建折线图


def creatAnalysisMap():
    # 获取时间
    curr_time = datetime.datetime.now()
    time_str = curr_time.strftime("%Y-%m-%d %H:%M:%S")
    # 创建折线图
    line = Line("中国疫情发展趋势图 "+time_str, width=1200, height=600)
    # 请求中国疫情数据链接
    baseUrl = "https://view.inews.qq.com/g2/getOnsInfo?name=disease_other&callback=jQuery34105560710307785617_1592363143544&_=1592363143545"
    # 当前请求链接返回的数据
    chinaData = requests.get(baseUrl).text.replace('"{', '{').replace('}"}', '}}').replace('\\', '')
    # 处理数据
    chinaData = chinaData[chinaData.index("{"):-1]
    # 将当前的json字符串转换成python的字典
    baseData = json.loads(chinaData)
    # 保存疫情属性列表
    attrList = ["累计确诊", "现有疑似", "现有确诊", "现有重症", "境外输入"]
    # 日期列表
    dateList = []
    # 累计确诊列表
    confirmList = []
    # 现有疑似列表
    suspectList = []
    # 现有确诊列表
    nowConfirmList = []
    # 现有重症列表
    nowSevereList = []
    # 境外输入列表
    importedCaseList = []
    # 解析数据
    for item in baseData["data"]["chinaDayList"]:
        # 追加日期
        dateList.append(item["date"])
        # 追加累计确诊列表
        confirmList.append(item["confirm"])
        # 追加现有疑似列表
        suspectList.append(item["suspect"])
        # 追加现有确诊列表
        nowConfirmList.append(item["nowConfirm"])
        # 追加现有重症列表
        nowSevereList.append(item["nowSevere"])
        # 追加境外输入列表
        importedCaseList.append(item["importedCase"])
    # 添加各个属性直线图
    line.add("累计确诊", dateList, confirmList, mark_point=['max'])
    line.add("现有疑似", dateList, suspectList, mark_point=['max'])
    line.add("现有确诊", dateList, nowConfirmList, mark_point=['max'])
    line.add("现有重症", dateList, nowSevereList, mark_point=['max'])
    line.add("境外输入", dateList, importedCaseList, mark_point=['max'])
    # 显示图形参数
    # line.show_config()
    line.render(path="output/中国疫情发展趋势图.html")
    print("已生成,请移步output文件夹查看")



生成世界疫情分布图的代码

'''
作者:谢思凌
时间:2020/06/17
'''

# 导入请求发送模块
import requests
# 导入json模块
import json
# 导入 xlrd模块解析excel表格
import xlrd
# 导入pyecharts
from pyecharts import Map
# 导入时间模块
import datetime
def creatMap():
    # 获取当前时间
    curr_time = datetime.datetime.now()
    time_str = curr_time.strftime("%Y-%m-%d %H:%M:%S")
    # 请求海外各国疫情数据链接
    baseUrl = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_foreign&callback=jQuery341035828799971754144_1592295771001&_=1592295771002'
    # 获取当前链接返回的数据
    worldData = requests.get(baseUrl).text.replace('"{', '{').replace('}"}', '}}').replace('\\', '')
    # 处理数据
    worldData = worldData[worldData.index("{"):-1]
    # 将当前的json字符串转化为python字典
    baseData = json.loads(worldData)
    # 打开excel文件获取数据
    excelData = xlrd.open_workbook("世界各国中英文对照表.xlsx")
    # 通过索引顺序获取当前sheet表
    table = excelData.sheet_by_index(0)
    # 获取行数
    rows = table.nrows
    # 创建国家中英文对照字典
    countryDict = {}
    # 循环获取中英文国家名称的键值对(字典)
    for i in range(rows):
        countryDict[table.row_values(i)[1]] = table.row_values(i)[0]
    # 保存英文国家名称列表
    englishCountryNameList = []
    # 保存各个国家的确诊数据
    countryConfirmDataList = []

    # 获取每个国家的名称和当前累计确诊人数

    for country in baseData["data"]["foreignList"]:
        if country["name"] in countryDict:
            englishCountryNameList.append(countryDict[country["name"]])
            countryConfirmDataList.append(country["confirm"])
    # 创建地图
    map = Map(title="世界疫情分布图  "+time_str, width=800, height=400, title_color="red")
    # 添加世界地图相关参数
    map.add("世界地图", englishCountryNameList, countryConfirmDataList, maptype="world",
            visual_range=[1, 10000], visual_text_color="#000", is_visualmap=True)
    # 显示地图配置参数
    # map.show_config()
    # 渲染地图
    map.render(path="output/世界疫情分布图.html")
    #print("已生成,请移步output文件夹查看")

查询世界任一国家疫情发展趋势图代码

# 导入json模块
import json
# 导入requests模块
import requests
# 导入pyecharts模块中的Line
from pyecharts import Line
# 导入datetime模块
import datetime


def creatAnalysisMap(country):
    # 获取当前时间
    curr_time = datetime.datetime.now()
    # 格式化当前时间
    time_str = curr_time.strftime("%Y-%m-%d %H:%M:%S")
    # 创建折线图
    line = Line(country+"疫情发展趋势图 "+time_str, width=800, height=400)
    # 参与统计国家的列表
    # countryNameList = ["美国", "意大利", "西班牙", "伊朗", "法国", "德国", "韩国", "日本本土", "加拿大"]
    # 定义各个国家获取链接模板
    url = "https://api.inews.qq.com/newsqa/v1/automation/foreign/daily/list?country="+country+"&"
    # 循环遍历各个国家获取数据
    basedata = requests.get(url).text
    data = json.loads(basedata)
    # 保存日期列表
    dateList = []
    # 保存每日确诊人数
    confirmList = []
    # 保存治愈人数
    healList = []
    # 保存死亡人数
    deadList = []
    for item in data["data"]:
        # 追加日期
        dateList.append(item["date"])
        # 追加确诊人数
        confirmList.append(item["confirm"])
        # 追加治愈人数
        healList.append(item["heal"])
        # 追加死亡人数
        deadList.append(item["dead"])
    # 添加各国折线图
    line.add("确诊人数", dateList, confirmList, mark_point=['max'])
    line.add("治愈人数", dateList, healList, mark_point=['max'])
    line.add("死亡人数", dateList, deadList, mark_point=['max'])
    # 显示图形参数
    # line.show_config()
    line.render(path="output/"+country+"疫情发展趋势图.html")
    # print("已生成,请移步output文件夹查看")


前端与后端的绑定

前后端写完了,接下来我们来看前端与后端如何绑定在一起,在qt中,通过信号与槽机制来实现前后端的绑定,为每一个功能键或按钮绑定一个信号与槽函数,通过发送信号,来执行槽函数,实现相应功能,具体看代码:

from MainWin import Ui_MainWindow
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
import qdarkstyle
import ChinaAnalysis, ChinaMap, WorldAnalysis, WorldMap


class MyMainWin(QMainWindow, Ui_MainWindow):
    flag = 0
    def __init__(self, parent=None):
        super(MyMainWin, self).__init__(parent)
        self.setupUi(self)
        # 初始化页面数据
        url = r'D:/Document/code/python/PyQt_Diease_RealTime/output/中国疫情分布图.html'
        self.browser.load(QUrl(url))
        # 为菜单键查看中国疫情情况信号绑定槽函数
        self.China_diease.triggered.connect(self.view_Chain)
        # 为菜单键查看世界疫情情况信号绑定槽函数
        self.World_diease.triggered.connect(self.view_World)
        # 为菜单键查询国家疫情情况信号绑定槽函数
        self.Query_country_diease.triggered.connect(self.query_Country)
        # 为疫情分布图按钮信号绑定槽函数
        self.pushButton.clicked.connect(self.btn_diease)
        # 为疫情趋势图按钮信号绑定槽函数
        self.pushButton_2.clicked.connect(self.btn2_diease)
        # 为更新按钮信号绑定槽函数
        self.pushButton_3.clicked.connect(self.upadate_diease)

    # 查看中国疫情情况槽函数
    def view_Chain(self):
        self.flag = 1
        # 创建中国疫情分布图
        ChinaMap.creatMap()
        # 创建中国疫情发展趋势图
        ChinaAnalysis.creatAnalysisMap()
        # 渲染中国疫情分布图
        url = r'D:/Document/code/python/PyQt_Diease_RealTime/output/中国疫情分布图.html'
        self.browser.load(QUrl(url))

    # 查看世界疫情情况槽函数
    def view_World(self):
        self.flag = 2
        WorldMap.creatMap()
        url = r'D:/Document/code/python/PyQt_Diease_RealTime/output/世界疫情分布图.html'
        self.browser.load(QUrl(url))

    # 查询任意国家疫情情况槽函数
    def query_Country(self):
        # 调用输入对话框,获取待查询国家名称
        countryName, ok = QInputDialog.getText(self, "查询", "输入国家名字")
        if ok:
            WorldAnalysis.creatAnalysisMap(countryName)
            url = r'D:/Document/code/python/PyQt_Diease_RealTime/output/'+countryName+'疫情发展趋势图.html'
            self.browser.load(QUrl(url))

    # 更新按钮槽函数
    def upadate_diease(self):
        # flag = 1 代表查看了中国的情况,接下来的分布图、趋势图的更新等都要渲染中国的情况
        if self.flag == 1:
            self.view_Chain()
            # 弹出提示框
            reply = QMessageBox.information(self, "提示", "更新成功", QMessageBox.Yes, QMessageBox.Yes)
        # flag = 2 代表查看了世界的情况,接下来的趋势图更新要渲染世界的情况
        if self.flag == 2:
            self.view_World()
            # 弹出提示框
            reply = QMessageBox.information(self, "提示", "更新成功", QMessageBox.Yes, QMessageBox.Yes)

    # 疫情分布图按钮槽函数
    def btn_diease(self):
        # flag = 1 代表查看了中国的情况,接下来要渲染中国疫情分布图情况
        if self.flag == 1:
            ChinaMap.creatMap()
            url = r'D:/Document/code/python/PyQt_Diease_RealTime/output/中国疫情分布图.html'
            self.browser.load(QUrl(url))
        # flag = 2 代表查看了世界的情况,接下来要渲染世界疫情分布图情况
        if self.flag == 2:
            WorldMap.creatMap()
            url = r'D:/Document/code/python/PyQt_Diease_RealTime/output/世界疫情分布图.html'
            self.browser.load(QUrl(url))

    # 疫情趋势图按钮槽函数
    def btn2_diease(self):
        url = r'D:/Document/code/python/PyQt_Diease_RealTime/output/中国疫情发展趋势图.html'
        self.browser.load(QUrl(url))


if __name__ == "__main__":
    app = QApplication(sys.argv)
    # app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
    win = MyMainWin()
    # 加载样式
    win.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
    win.show()
    sys.exit(app.exec_())

成果展示

结语

活在当下,不为未来担忧!这个学期写实验报告总结写得快吐了。

你可能感兴趣的:(python+pyecharts+pyqt打造疫情实时追踪可视化系统)