数据可视化实战,画个新冠肺炎地图

本文来源于和鲸社区,作者王大毛

文中涉及数据集下载地址:

https://www.kesci.com/home/project/5e426eb4b8c462002d69c1c9/dataset 

导入库
导入数据
import pandas as pd 
import matplotlib.pyplot as plt
import folium
import folium.plugins as plugins
import numpy as np
import datetimedata= pd.read_csv("/home/kesci/input/2019ncov5600/2019_nCoV_data.csv")
print(data.head())
print(data.info())

一、数据清洗

1.Sno编号列没有用,要删去

data.drop(['Sno'],axis=1,inplace=True);

2.部分国家对应的地区为NAN,需要填充为空白字符串

data['Province/State'].fillna('',inplace=True)

3.部分国家/地区,受感染人数为0,也被列在表格中,需要删去

data.drop(data[data['Confirmed']==0].index.to_list(),axis=0,inplace=True)

4.查看受影响的国家/地区的数量

countries = data['Country'].unique().tolist()

print(countries)

5.中国有China, Mainland China两个写法,需要统一;另外还有一些你懂的问题需要修正

data['Country'].replace({'Mainland China':'China','Hong Kong':'China','Macau':'China','Taiwan':'China'},inplace=True)

countries = data[data['Confirmed']!=0]['Country'].unique().tolist()
print('迄今为止,受影响的国家/地区:',countries)
print('迄今为止,受影响的国家/地区个数:',len(countries))

二、取出最新数据

观察后发现,这个原始表格每天会把最新的数据更新在表格最后,而且,并不是每天每个国家都会更新数据。所以,需要筛选出每个国家的最新数据

5.将Date转化为datetime格式,方便操作后面进行时间的比较

data['Date'] = data['Date'].apply(pd.to_datetime)
data.head()

6.按国家+城市字段分组,方便进行时间上的筛选

grouped = data.groupby(['Country','Province/State'])

7.选出每个国家/城市最新的数据

latest = grouped['Date'].idxmax()
data_latest = data.loc[latest]

data_latest.head()

又发现一个问题,比如Australia,一开始是以国家为单位报数据,之后又分成小区域报数据,会导致计算重复,所以要删除这部分数据。也不能直接删,因为不知道有多少国家的数据有这个问题。

8.筛选出国家对应的城市字符串为空,且该国家下的城市(包括空字符串)数量大于一 的数据

useless=data_latest[
    (data_latest['Province/State']=='') &
    (data_latest['Country'].apply(lambda x:data_latest['Country'].value_counts()[x])>1)
    ].index.to_list()
    
useless

9.删除这些数据

data_latest.drop(useless,inplace=True)

三、简单的可视化

10.查看各个国家总感染数据

world_cases = data_latest.groupby(['Country'])['Confirmed','Deaths','Recovered'].sum().sort_values(by='Confirmed', ascending=False)
world_cases

11.可视化以上数据,因为中国的确诊数量太大,故不放在图片里

plt.figure(figsize=(12, 8))

plt.barh(y=world_cases[1:].index,width=world_cases['Confirmed'][1:],color='lightcoral')

 读入坐标数据

world_coordinates = pd.read_csv('/home/kesci/input/2019ncov5600/world_coordinates.csv')

12.将坐标数据与国家感染数据合并

world_data = pd.merge(world_coordinates,world_cases,on='Country').sort_values(by='Confirmed', ascending=False)
world_data

13.用folium创建一个初始地图,中心点(35,0),缩放2.3

world_map = folium.Map(location=[35, 0], zoom_start=2.3)
world_map

14.先尝试在地图上画出中国的点

lat=world_data.iloc[0]['latitude']
lon=world_data.iloc[0]['longitude']

folium.CircleMarker([lat, lon],
                    radius=20,
                    color='red',
                    fill_color='red',
                    fill_opacity=0.7,
                    popup = ('<strong>国家</strong>: China<br>'
                                '<strong>确诊</strong>: ' + str(world_data.iloc[0]['Confirmed']) + '<br>')
                    ).add_to(world_map)
world_map

15.了解套路之后,用for画出剩余的圆圈

for lat, lon, value, name in zip(
    world_data.iloc[1:]['latitude'],
    world_data.iloc[1:]['longitude'],
    world_data.iloc[1:]['Confirmed'],
    world_data.iloc[1:]['Country']):
    
    folium.CircleMarker([lat, lon],
                        radius=value*0.2,
                        color='red',
                        fill_color='red',
                        popup = ('<strong>国家</strong>: ' + str(name).capitalize() + '<br>'
                                '<strong>确诊</strong>: ' + str(value) + '<br>')
                        ).add_to(world_map)
world_map

 16.查看中国的各地区的数据

china_cases=data_latest[data_latest['Country']=='China'].sort_values(by='Confirmed', ascending=False)
china_cases.head()

17.画出出湖北外确诊病例的饼图

explode =np.hstack((np.zeros(10),np.linspace(0,3,len(china_cases)-11)))

plt.figure(figsize=(12, 8))

plt.pie(china_cases['Confirmed'][1:],labels=china_cases['Province/State'][1:],autopct='%1.1f%%',explode=explode);

 18.画出除湖北外确诊和痊愈的数据

plt.figure(figsize=(12, 8))
plt.barh(width="Confirmed", y="Province/State", data=china_cases[1:], color="lightcoral");
plt.barh(width="Recovered", y="Province/State", data=china_cases[1:], color="palegreen");

 读取中国的坐标数据集

china_coordinates= pd.read_csv("/home/kesci/input/2019ncov5600/china_Province_coordinates.csv")
china_coordinates.head()

19.坐标数据集中,name3要和Province/State匹配,所以要改个名字。以及,原表格Province/State有大写,要处理成全部小写

china_coordinates.rename(columns={'name3':'Province/State'},inplace=True)
china_cases['Province/State']=china_cases['Province/State'].map(lambda x:x.lower())

20.两个表格数据匹配

china_data = china_cases.merge(china_coordinates)
china_data.head()

21.画出中国的感染分布,先画一个背景,中心点(39.91666667,116.383333),基础缩放4

latitude = 39.91666667
longitude = 116.383333
 
china_map1 = folium.Map(location=[latitude, longitude], zoom_start=4)
china_map1

22.画出武汉的数据

folium.CircleMarker([china_data.iloc[0]['lat'],china_data.iloc[0]['lon']],
                    radius=20,
                    color='red',
                    fill_color='red',
                    fill_opacity=0.7,
                    popup = ('<strong>省份</strong>: 湖北<br>'
                        '<strong>确诊: </strong>' + str(china_data.iloc[0]['Confirmed']) + '<br>'),
                    ).add_to(china_map1)
china_map1

23.画其他省市的数据

for lat, lon, value, name in zip(
    china_data.iloc[1:]['lat'],
    china_data.iloc[1:]['lon'],
    china_data.iloc[1:]['Confirmed'],
    china_data.iloc[1:]['name2']):
    
    folium.CircleMarker([lat, lon],
                        radius=value*0.01,
                        color='red',
                        fill_color='red',
                        popup = ('<strong>国家</strong>: ' + str(name) + '<br>'
                                '<strong>确诊</strong>: ' + str(value) + '<br>')
                        ).add_to(china_map1)
china_map1

四、复杂的可视化

这部分我们要做个动态的地图

先读取另一份颗粒度细一点儿的数据

china_history=pd.read_csv('/home/kesci/input/ncov6321/DXYArea.csv')
china_history.head()

24.再来一套和之前差不多的操作,丢掉province_confirmedCount, province_suspectedCount, province_curedCount, province_deadCount四列数据

china_history.drop([
    'province_confirmedCount',
    'province_suspectedCount',
    'province_curedCount',
    'province_deadCount'],
    axis=1,
    inplace=True
    )

25.将updateTime转换成date格式,就是只保留日期部分

china_history['updateTime']=china_history['updateTime'].apply(pd.to_datetime).dt.date

因为涉及到后面要匹配城市名字和坐标数据集的问题,所以现在要分几部分修改一些城市(区域)的写法

26.因为大部分城市都没有加“市”字,所以,要把直辖市的下属区的“区”字去掉。另外,这几个直辖市有时加“区”有时不加,所以需要判定一下(以下就写了上海市的)

china_history.loc[china_history['provinceName'] == '上海市','cityName'] = china_history[china_history['provinceName'] == '上海市']['cityName'].apply(
    lambda x: x[0:len(x)-1] if len(x)>2 else x)

还有一些没有变化规律的城市名字,互联网民工手动整理出来了,是个叫city_rename的字典

city_rename= {
    '恩施州':'恩施土家族苗族自治',
    '神农架林区':'神农架林',
    ...
    '丽江市':'丽江'}

27.这部分没有规律的名字也同样需要修改

china_history['cityName']=china_history['cityName'].apply(
    lambda x:city_rename[x] if x in city_rename else x)

读入详细坐标数据集

china_coor2=pd.read_csv('/home/kesci/input/chinacoor9160/china_coordinates.csv',header=None)
china_coor2.head()

28.因为坐标集没带标题,所以要给标题重命名,顺便将城市名列改成和前面一致

china_coor2.rename(columns={0:'code',1:'cityName',2:'lon',3:'lat'},inplace=True)

29.因为前面感染数据的表格,城市名后面都没有带“市”“区”,所以统一给去掉

china_coor2['cityName']=china_coor2['cityName'].apply(lambda x:x[0:len(x)-1])
china_coor2.head()

30.2个表格合并

china_history_data=china_history.merge(china_coor2)
china_history_data.head()

这里开始做动态地图需要的数据。需要构造一个三维数组,形如[[[Y1,X1,W1],...,[Y1,X1,W1]],[[Y1,X1,W1],...,[Y1,X1,W1]],...,[[Y1,X1,W1],...,[Y1,X1,W1]]],最外面一层是时间,每一层时间里面包含一堆数据点,每个数据点里面是坐标+数值。

31.筛出时间帧

update_time=china_history_data['updateTime'].unique()

32.用for循环构造出三维的数组

data_move=[]

for i in update_time[::-1]:
    tmp_pd=china_history_data[china_history_data['updateTime']==i]
    data_move.append(tmp_pd[['lat','lon','city_confirmedCount']].values.tolist())

33.再开个新地图,将刚刚构造的数组传给folium的HeatMapWithTime,并设置auto_play=True

m=folium.Map(location=[latitude, longitude], zoom_start=4)
plugins.HeatMapWithTime(data_move[:15],auto_play=True).add_to(m)
m

往期精彩回顾




适合初学者入门人工智能的路线及资料下载机器学习在线手册深度学习在线手册AI基础下载(pdf更新到25集)本站qq群1003271085,加入微信群请回复“加群”获取一折本站知识星球优惠券,请回复“知识星球”喜欢文章,点个在看
  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值