2021年(第14届)中国大学生计算机设计大赛作品详情表

作品类别 信息可视化设计-数据可视化
作品名称 2021017672-疫情数据的获取和展示
作者信息   姓名 专业 学历 年级
作者1钟明月管理学-管理科学与工程类-120102 信息管理与信息系统 本科三年级
作者2刘冰冰管理学-管理科学与工程类-120102 信息管理与信息系统 本科三年级
作者3李光宇工学-电子信息类-80701 电子信息工程 本科四年级

作品简介

2020年新冠疫情爆发后,几乎影响了所有人的生活,大家都关注着疫情数据的变化,一般来说,获取疫情数据都是通过浏览器上网或者手机第三方软件,而本设计通过运行Python程序即可获得主流媒体播报的可信数据,并且将数据以动态图形展示出来,数据展示效果直观,这样对于用户来说非常方便。

基于此,本设计利用Python在线获取数据及动态展示数据。设计分为两部分:

第一部分:数据获取,通过网易平台获取世界疫情数据并保存为Excel文件。

第二部分:数据展示,分别使用地理空间可视化库PyechartsMapPie,以及Matplotlib库的animation模块的FuncAnimation,动态展示数据;根据各国家的总计确诊、病死率、治愈率进行K-Means分类并展示;Pandas库柱形图展示指定国家历史疫情数据并保存到自建文件夹中。

其中利用PyechartsMap将世界疫情数据以世界地图的形式绘制出来;交互式数据显示采用:利用Map将单个国家疫情数据以地图形式绘制出来、用Pie将指定几个国家的数据用饼图绘制出来、用Pandas库柱形图展示指定国家历史疫情数据并保存到自建文件夹中;而Matplotlib库的animation模块的FuncAnimation将世界各国家最后一次更新的疫情数据以动态柱形图的形式绘制出来。

开源代码与组件使用情况说明

1、开源组件

 (1)Pyecharts库Map和Pie

 (2)Matplotlib库的animation模块的FuncAnimation

2、参考资源:

(1)干货.使用PYECHARTS绘制交互式动态地图-知乎.作者:朱卫军

(2)数据酷客

(3)百度百科-中英文国家对照表

 

作品安装说明

如果要运行代码并实现图形美化效果需要安装Anaconda开发环境,并使用pip命令在线安装的第三方库包括: requestspandasnumpypyechartsmatplotlibsklearn库。利用AnacondaJupyter Notebook编辑环境渲染展示数据图形或保存图形为网页。当然,以上操作的前提是必须能上网。同时也需要MP4视频播放器,才能观看录制的演示视频。

但是,考虑到方便,即不需要上述的准备工作,我只提供程序的html文档,名为“疫情数据的获取和展示——代码”,位于“2021017672-02素材与源码”文件夹下,只要能上网,使用浏览器就能打开查看全部代码以及运行结果

2021017672-02素材与源码”文件夹下的“代码运行的素材和获取的数据文件”下包含代码和数据文件,如果重复运行part4图形显示代码前,要把“第四部分绘图”文件夹删除再运行代码。

作品效果图

1、获取的数据文件截图

上述文件中,除了“百度百科中英文国家对照表.xlsx”为数据素材以外,其它文件均为运行程序获取保存的文件。详细的文件内容存放文件夹为:2021017672-02素材与源码。

2、数据展示

part1:第一种数据展示效果

       

第一种数据展示效果是动态的,当鼠标悬浮于国家地图板块之上,会弹出该国家当日确诊人数,这里仅仅展示了俄罗斯国家的数据。详细的动画展示,请参看演示视频,视频存放文件夹为:2021017672-04作品演示视频。

  part2:第二种动态数据展示效果

第二种数据展示图是动态的,因此只选截了三个国家最后一次更新数据的图像。详细的动画展示,请参看 演示视频,视频存放文件夹为:2021017672-04作品演示视频。

  part3:根据各国家的总计确诊、病死率、治愈率,进行K-Means分类并展示

图中,第三类国家为“美国、巴西、印度”,这是因为这三个国家的“总计确诊”、“总计治愈”和“总计死亡”数据的量级以及比率较为接近。详细的动画展示,请参看演示视频,视频存放文件夹为:2021017672-04作品演示视频。

part4:交互式+Pandas库绘图,柱形图展示指定国家历史疫情数据(notebook中显示并保存到自建文件夹中)

 

part4显示的图保存路径为“2021017672-02素材与源码\代码运行的素材和获取的数据文件\第四部分绘图”中。

 

 

设计思路

一、概要设计

设计概要如果以语言来描述的话,层次性不明显,千言万语不如一张图,所以,我将以框图形式来展示。图1为设计的整体思路,本设计的两个部分都是用Python编程实现。

1设计整体思路图

二、详细设计

第一部分:数据的获取

1、数据获取平台

采用媒体平台作为数据获取来源。这里以网易新闻的疫情播报平台作为爬取对象,网页内容截图如图2所示。地址为:https://wp.m.163.com/163/page/news/virus_report/index.html?_nw_=1&_anw_=1

2数据获取平台示意

2、数据获取的链接

网易平台是一个实时动态的网页,在网页的检查页面Network标签下刷新XHR可以看到数据的请求地址:https://c.m.163.com/ug/api/wuhan/app/data/list-total?t=323607828807

如图3所示。

3请求数据的链接

3、数据格式分析

请求的数据是一个几十万长度的json格式的字符串。在数据“data”键中存放着疫情数据,而在“data”中又包含了五个字典,分别是:'chinaTotal','chinaDayList', 'lastUpdateTime', 'overseaLastUpdateTime', 'areaTree'。其中,世界的疫情数据在'areaTree'中。

不论是中国还是世界的疫情数据,播报的键都是'today', 'total', 'extData',如表格1所示。

表格 1数据所在的键

第一层键
第二层键
'today'
'confirm', 'suspect', 'heal', 'dead', 'severe', 'storeConfirm', 'input'
'total'
'confirm', 'suspect', 'heal', 'dead', 'severe', 'input'
'extData'
'noSymptom', 'incrNoSymptom'
我们要爬取的数据即为'areaTree''today', 'total', 'extData'中的数据。

4、数据获取流程

表格2列出了第一部分设计中的自编函数以及对应的功能。

表格 2函数功能表

函数名

函数功能

get_html(url)

获取网页内容

to_json(html_text))

获取“data”键中存放的数据

save_html(file_name,text)

保存网页

read(file_name)

读文件

get_change(data_dict)

获取疫情数据,并变为中文

save_data(name,df)

保存数据为excel

main()

主函数

第一部分数据获取程序流程如图4所示。

4第一部分数据获取流程图

第二部分:数据的展示

1part1:世界地图展示实时疫情数据

把一些地域性明显的数据显示在一张地图上,远远比放在Excel文件中的好得多!Matplotlib库中也有绘制地图的函数,但其为静态的图,而Pyecharts地理空间可视化库可以绘制动态的图,故采用Pyecharts模块中的绘图功能绘制。在这里自豪一下,Pyecharts是中国人开发的,相较MatplotlibSeaborn等可视化库,更符合国人习惯,尤其在地理空间图表方面。

Pyecharts库中负责地理坐标系的模块是Geo,负责地图的模块是Map,负责百度地图的模块是BMap,负责图表配置的模块是options。在Pyecharts中,图表的一切皆通过options来修饰调整。故,本设计使用其中的Map模块绘图。

1)读入数据

读入文件“世界各国当日疫情数据.xlsx”,选取其中的'当日确诊','名称'两列,获得当日确诊人数和国家名,由于国家名为中文,故通过百度百科搜到世界国家的中英文名字对照,但有一部分国家(岛名)名必须单独搜索才行,将其保存为“百度百科中英文国家对照表.xlsx”。读入该文件为原数据添加一列英文名,如图5所示。

        

5世界各国家英文名称及其当日数据         

      

 

2)绘图数据准备

在图5中可见有个别国家当日确诊数据未更新,即为“NaN”,故将这样的空值填充为0,并且人数应为整数数据,故将当日确诊列取整数,如图6所示。取英文名称和当日确诊两列数据,转化为二维列表,作为绘图数据。

 6数据准备

3)采用python的可视化包Pyecharts绘图

Pyecharts的主要函数如表3所示。 

表格 3 Pyecharts绘图的主要函数

Map的功能函数名

函数功能

add()

添加图表名称、传入数据集、选择图类型等

set_series_opts()

系列配置项,可配置图元样式、文字样式、标签样式、点线样式等

set_global_opts()

全局配置项,可配置标题、动画、坐标轴、图例等

render_notebook()

notebook中渲染显示图表

绘图的程序流程如图7所示:

 7世界地图展示疫情数据流程

4)交互式绘图:地图显示指定一个国家当日确诊数据(保存为网页)

绘图流程如图8所示:


8 交互式绘制单个国家的数据

绘图后,出现名为“ 美国+map”的文件,双击打开网页可见图如图9所示:

9 绘图效果

5)交互式绘图:环形图显示指定的若干国家当日确诊数据(保存为网页)

Pyecharts库中负责绘制饼图的模块是Pie,和绘制地图模块Map中使用的设置参数极为相似。绘图流程如图10所示。


10 绘制饼图流程

绘图后,出现名为“美国+日本本土+英国+中国+印度+瑞士+巴西+pie1 ”的文件,双击打开网页可见如图11所示。

11 多个国家的饼图

2part2:最后更新的世界疫情数据动态展示

Matplotlib库下的animation模块的FuncAnimation方法可以称的上Matplotlib功能最强大的方法之一,使用它可以创建随着时间变动而变动的图像。

1)读入数据

读入当前文件夹下除了百度百科中英文国家对照表”,世界各国当日疫情数据”以外的各个国家历史疫情数据Excel文件,并且只读取最后一条记录,即最后更新的疫情数据,并增加一列国家名称。

2)准备数据

取出数据中的当日确诊、当日治愈、“当日死亡”、“日期”、“国家”列数据。其中,“国家”列数据作为title;“日期”列数据作为xlabel当日确诊、当日治愈、“当日死亡”作为纵轴数据。

3)绘图

使用Matplotlib库下的animation模块的FuncAnimation函数绘图。

其核心要导入库:from matplotlib import animation

使用其中的函数:animation.FuncAnimation(fig,func,frames,init_func,interval,blit,repeat)

FuncAnimation的特点就是可以用一个给定的时间间隔不断地重复执行某个绘制函数, 从而实现动态数据的绘制。函数的参数如表4所示:

表格 4 FuncAnimation的参数

参数名

参数功能

fig

绘制动图的画布名称

func

自定义动画函数,即程序定义的函数update

frames

动画长度,一次循环包含的帧数,在函数运行时,其值会传递给函数update(num)的形参“num”

init_func

自定义开始帧,即传入刚定义的函数init,初始化函数,本设计不用。

interval

更新频率,以ms

blit

选择更新所有点,还是仅更新产生变化的点。应选择True,但mac用户请选择False,否则无法显示

repeat

是否重复

绘图的流程如图12所示。

12 animation动态展示数据流程图

3part3:根据各国家的总计确诊、病死率、治愈率,进行K-Means分类并展示

1)准备数据

读入“世界各国当日疫情数据.xlsx”文件,选取其中的“名称、最近更新时间、总计确诊、总计治愈、总计死亡”几列数据,命名为world_data3。为了防止数据在后面的操作中被修改,采用了深复制命名为world_data3_copy。在数据进行操作之前,首先查看是否含有缺失值,结果表明word_data3中不含缺失值。

2)归一化数据

word_data3增加一列“死亡率”和一列“治愈率”,即,采用“总计死亡”列数据除以“总计确诊”列数据,以及采用“总计治愈”列数据除以“总计确诊”列数据。再对“总计确诊”列数据进行归一化,即用“总计确诊”列数据除以该列的最大值。处理后的world_data3结果如图13所示:

13 归一化数据结果

3K-Means聚类

第一步:选取world_data3中的“总计确诊、死亡率、治愈率”三列数据的值(即array数组)命名为world_data3_values

第二步:选择合适的聚类参数n_clusters

由于爬取到的数据包含207个国家的数据,对其分几类采取了尝试,让n_clusters聚类数分别取值为120,对world_data3_values进行模型训练并对模型进行评分,获得20个模型评分,聚类数和评分关系如图14所示,由图中可见,当n_clusters取值在4左右,曲线所围的面积最大,效果最好,故这里让n_clusters4

14 聚类数和评分关系

第三步:建立聚类模型进行分类

 

建立聚类模型my_Kmeans,采用自动聚类算法、分4类、初始聚类中心选择10个中心、最大迭代次数200次,对world_data3_values进行训练,训练好的模型对world_data3进行聚类,将聚类结果作为world_data3_copy的最后一列,命名为“grade”,world_data3_copy如图15所示:

                                                    图15 聚类后的world_data3_copy

第四步:输出聚类后的国家分类和图形化显示聚类结果

 

整个part3的流程如图16所示。

16 part3的流程

由于数据占用篇幅较大,因此聚类后的国家分类详细数据详见程序运行结果。程序代码保存路径为“2021017672-02素材与源码\疫情数据的获取和展示——代码”。 

4part4:交互式+Pandas库绘图

Pandas绘图,绘制柱形图展示指定国家历史疫情数据,在notebook中显示并保存到自建文件夹“第四部分绘图”中。

整个part4的流程如图17所示。

               图17 part4的流程如图

 

其中draw_one_country函数采用Pandas绘图,绘制柱形图,数据以月为单位进行汇总再输出成图。

part4绘制的图除了在程序代码中显示以外(保存路径为“2021017672-02素材与源码\疫情数据的获取和展示——代码”),也在文件夹中保存为图片(保存路径为“2021017672-02素材与源码\代码运行的素材和获取的数据文件\第四部分绘图”)。

 

设计重点难点

一、重点

1、动态网页获取数据链接

网页的静态爬取和动态爬取是两种思路,数据获取平台应该选择具有公信度的平台,并且数据更新及时,网页数据格式规范,因此选择了网易163平台获取数据,在网页的检查页面Network标签下刷新XHR可以看到数据的请求地址:https://c.m.163.com/ug/api/wuhan/app/data/list-total?t=323607828807

数据源如图1所示:


图1 请求网页的数据源

2、获取疫情数据

要对数据连接中的数据进行分析,和网页中的数据对比,找到需要爬取的数据键。锁定在data键下,而在“data”中又包含了五个字典,分别是:'chinaTotal','chinaDayList', 'lastUpdateTime', 'overseaLastUpdateTime', 'areaTree'。其中,世界的疫情数据在'areaTree'中。

不论是中国还是世界的疫情数据,播报的键都是'today', 'total', 'extData',如表格1所示。

表格 1数据所在的键

第一层键
第二层键
'today'
'confirm', 'suspect', 'heal', 'dead', 'severe', 'storeConfirm', 'input'
'total'
'confirm', 'suspect', 'heal', 'dead', 'severe', 'input'
'extData'
'noSymptom', 'incrNoSymptom'
我们要爬取的数据即为'areaTree''today', 'total', 'extData'中的数据。
3、疫情数据图形化之前,需要将世界各国的汉字名,改为对应的英文名。

二、难点

1、获取数据函数的编写

表格2列出了第一部分设计中的自编函数以及对应的功能。

表格 2函数功能表

函数名

函数功能

get_html(url)

获取网页内容

to_json(html_text))

获取“data”键中存放的数据

save_html(file_name,text)

保存网页

read(file_name)

读文件

get_change(data_dict)

获取疫情数据,并变为中文

save_data(name,df)

保存数据为excel

main()

主函数

 

第一部分数据获取程序流程如图2所示。为了防止网站反爬,最好将获取的网页文本保存在本地,命名为:疫情数据爬取网页文本.txt。也就是说,只爬取一次网页,然后保存网页内容后,读取该文件,再进行下一步的数据提取操作,这样做的原因是提取数据过程中,代码编写若不熟练则会经常出错,为了能反复修改代码而不用反复爬取网页,最好保存网页。

2第一部分数据获取流程图

 

2、数据展示

(1)使用Pyecharts库的Map模块绘制世界地图

需要为数据增加一列国家的英文名称,绘制地图需要准备数据对:名称列和数据列;

同时,需要根据疫情人数的多少,分不同的颜色显示地图中国家的颜色,人数越多,颜色越鲜艳。

(2)使用Matplotlib库的animation模块下的FuncAnimation绘制动态图形

编写update更新函数,为了动态图形显示得清楚,要留出反应时间,因此图形更新时间按照1000ms间隔设置。

(3)如和确定较好的聚类数

通过尝试20种聚类数并对其进行评分,找到最优的聚类数。由于K-Means聚类点选取的随机性,聚类效果并没有达到令自己非常满意的效果,即,需要反复运行该部分程序才能获得和开发文档中一样的聚类图形结果,详见演示视频中的操作。

(4)如何令Pandas绘图更加美观

选取绘图的参数尤为重要,table参数让Pandas绘图的优点凸显出来,因为它能够突出具体的数据分布。

指导老师自评

       本组学生能够认真地完成设计,且选题具有一定的实用性。学生自修Python程序设计,主动学习的精神可嘉。程序编写过程中遇到很多问题,大家讨论并搜集资料解决问题,其间能够按照老师的指引去学习相应的知识,寻找相应的内容完善设计。

       本设计实现了对世界各个国家疫情数据的获取、实现了用世界地图的形式动态展示疫情数据、实现了交互式以地图和饼图的形式动态展示疫情数据、实现了用动态柱形图的形式展示各国最后一次更新的疫情数据、实现了基于机器学习的K-Means聚类分析的显示、实现了基于Pandas的绘图优化,设计的过程中,在一定意义上充分锻炼了自学能力和攻克困难的团队协作能力。本设计中无敏感信息、无不良导向内容。

       符合大赛设计要求,推荐参赛。

学校评语

符合大赛要求,推荐参赛。

其他说明

设计的结果看,设计已经达到了预期,从项目的规模看,设计还较为“单薄”,本设计从数据获取到数据展示实现了可视化,能够较直观地展示数据。

但项目也需要改进:比如令整个项目定时(24小时)获取一次数据,从而最快获知疫情走向。

程序设计是十分有趣的,在整个设计的过程中,需要自学数据获取、自学数据展示第三方库,这拓宽了我们的知识面,同时,代码也经过无数次的调试最终才能实现设计目的,调试的过程辛苦而漫长,几百行的代码整体调试是很困难的,反复的错误下,我们学会了分段调试,即将代码模块化,逐个功能模块调试通过再整体调试。过程虽然辛苦,但看到数据展示的一刻,很有成就感。

设计还有很多不足之处,需要后期进一步优化,但整个设计的过程让我们受益匪浅。