总是看到网上有各种各样的可以用地图来展示某一地区的情况,如GDP的增速、人口的变化等,于是就想想这个问题是否能用python来实现,经查阅资料发现,用python来画地图其实也并不难,做好数据和地图的关联就可以实现。
一、项目准备
使用python画地图,需要安装pyecharts库和tushare库,所以得先下载安装,安装方法也比较简单,语句为:
pip install pyecharts
pip install tushare
二、项目目标
在tushare里,有关于疫情的另类数据,本次就通过使用该数据来学习如何画地图,由于数据中包含有世界范围数据和国内的数据,因此本次画地图主要是利用上述数据画世界地图和中国地图。
三、项目过程
(一)数据获取
(1)世界数据
对于世界级数据,tushare给出的接口是ncov_global,具体地址和详细参数解释可以查看网站https://tushare.pro/document/2?doc_id=213
import tushare as ts
pro=ts.pro_api('*****************************************')#这里是要token的,不是全***
dtw=pro.ncov_global()
dtw
可以看到,拿的数据有10000条,世界上的国家个数也还不到200,有这么多数据的原因在于每个国家在多个日期都有发布更新数据,所以我们需要拿到最后的更新的每个国家的数据。通过查看数据列,发现有个publish_date,即发布日期,我们就以最后这一天的发布数据为准,获取各国的对应数据。这个数据也比较旧了,最后一个日期是2020年6月19日的,后续一直没有更新。
(2)中国数据
对于国内数据,tushare给出的接口是ncov_num,具体地址和详细参数解释可以查看网站https://tushare.pro/document/2?doc_id=202
对于中国的省级数据,首先根据接口定义中将level值设定为3,表示获取省级层面数据,日期范围可以先暂定为2020年3月1日到2020年3月22日。
import tushare as ts
pro=ts.pro_api('***********************************')
dtc=pro.ncov_num(start_date='20200301',end_date='20200322',level=3)
dtc
国内的数据则在2020年3月22日就停止更新了,因此需要获取在这个日期前的每个省的对应数据。
(二)数据整理
从获取到的数据可以发现,无论是在世界数据方面还是在中国数据方面,应该都存在有大量的冗余数据,我们所需要做的是保留最后一次更新的数据。
(1)世界数据
对于世界级数据,去除多余数据的思路比较清晰,直接提取publish_date为20200619那天的数据就好,于是拿到了197条数据。
dtw.loc[dtw.publish_date=='20200619']
然而,后续在画图时发现数据存在问题,经过检验后发现,这一天的数据里,还存在有多个中国地区的数据,所以需要将其再次删除,只保留国家层面的数据。
dtw.loc[dtw.publish_date=='20200619'][dtw.country=='中国']
在中国的数据里,很明显,province这一列是和country这一列不相同的,而所有国家层面数据在这两列上都相同。因此,相应的操作是:
dtw=dtw.loc[dtw.publish_date=='20200619']
dtw=dtw.loc[dtw.country==dtw.province]
dtw
最终,拿到了190条数据。
(2)中国数据
对于中国数据,我们可以再原数据的基础上删除那些重复的数据,仅保留最后一次出现的数据。
dtc=dtc.drop_duplicates(['area_name'],keep='last')
dtc
最后,我们拿到了29条数据。
(三)绘制地图
(1)基本思路
在有了数据后,绘制地图就简单多了。绘制地图需要的是pyecharts库中的map类,该方法的参数设置请参照库文档。
Map类首先有个实例化方法,主要是对地图的基本参数进行设置,比如地图大小。
之后是.add方法,主要是给地图添加数据关联,这里对于国家和数据的关联,是需要建立数据对的,一般通过zip方式将两个列表进行构建。
再是地图的相关设置,主要是对图例、标签等进行相关设置。
最后是.render方法,主要是生成对应地图的网页。
大概框架如下:
tu=(
Map()
.add()
.render()
)
(2)生成数据对
从数据中可以看到,感染人数是confirmed_num,国家名是country_enname,地区名是area_name,分别将其取出,然后构建数据对。数据对格式是:[国家名,数据]
m0=list(dtw.confirmed_num)
n0=list(dtw.country_enname)
m1=list(dtc.confirmed_num)
n1=list(dtc.area_name)
z1=[list(i) for i in zip(n0,m0)]
z2=[list(i) for i in zip(n1,m1)]
(3)画世界地图
k = (
Map(init_opts=opts.InitOpts(width="1440px",height='900px'))
.add("新冠疫情感染人数",z1,"world",is_map_symbol_show=False)
.set_global_opts(title_opts=opts.TitleOpts(title="地图绘制第一例"))
.set_global_opts(
title_opts=opts.TitleOpts(title="世界地图"),
visualmap_opts=opts.VisualMapOpts(min_=1,max_=100000),
)
.render("first.html")
)
世界地图很快就出来了,但很奇怪的是,美国这个国家居然不是红色的,而且也没有数据,后面通过对比其国家名才发现,原来在数据中,美国的英文名称是United States of America,而在地图上,美国的名称是United States,所以二者对不上,造成美国没有被关联上。于是对数据进行再次修改。
dtw.loc[dtw.country=='美国','country_enname']='United States'
重新关联并生成地图:
这下美国就没有逃脱了。但要吐槽一下,这个地图的质量还是不高,有些国家名称的位置都是错误的,比如新西兰。
(4)画中国地图
画中国地图的时候也遇到了和美国一样的问题,发现在地图上,每个省的名称都只有两个字,而在做数据对的时候,是按省、市、自治区的全名来写的,所以要对数据进行重新配对。发现除了内蒙古和黑龙江外,其他的都是只有两个字符,于是把每个地区名重新做了设置。
dtc.index=range(0,len(dtc))#因删除了数据,需要重置索引
for i in range(len(dtc)):
if dtc.loc[i,'area_name'][:2]=='内蒙':
dtc.loc[i,'area_name']='内蒙古'
elif dtc.loc[i,'area_name'][:2]=='黑龙':
dtc.loc[i,'area_name']='黑龙江'
else:
dtc.loc[i,'area_name']=dtc.iloc[i]['area_name'][:2]
调整代码画中国地图:
k = (
Map(init_opts=opts.InitOpts(width="1440px",height='900px'))
.add("新冠疫情感染人数",z2,"china",is_map_symbol_show=False)
.set_global_opts(title_opts=opts.TitleOpts(title="地图绘制第二例"))
.set_global_opts(
title_opts=opts.TitleOpts(title="中国地图"),
visualmap_opts=opts.VisualMapOpts(min_=1,max_=500),
)
.render("second.html")
)
四、尾声
地图是画完了,感觉用pyecharts画的地图还是很粗糙,希望以后能够更精确一点,更美观一些。