新型冠状疫情分布热力图

经常看人家用basemap做热力图,不过basemap也比较旧了。 试试用folium。

 

步骤

  1. 通过API获取当前最新信息
  2. 根据城市编码查找城市的经纬度数据
  3. 记录城市的经纬度和对应的数值生成数据集
  4. 通过工具生成地图

 

1、获取数据:

这里我选用的是新浪的API:

https://interface.sina.cn/news/wap/fymap2020_data.d.json

 

 

可以看到data中第一级参数有 times, mtime, gntotal. list 等等表示数据时间患病人数之类的。 这里我们先只做国内的热力图。

先看看数据内容的结构是怎么样的,list中显示各个省份/直辖市,下一级city显示有各省/直辖市的城市/市区的数据,这里我们取econNum查看当前确诊人数和citycode城市编号。

 

首先将返回的数据转换成JSON。由于本身就是JSON字符串,转换起来也相较简单。

r = requests.get(url_str, timeout=5)
r.json()

url_str就是填新浪的API.

 

2、查找数据:

刚才说了选择国内的信息,也就是要用‘list’这一列数据,这里我使用pandas:

import pandas as pd

df = pd.DataFrame(r.json())
# find 'list'
province_data_list = df.loc['list', 'data']

从第一张截图里你可以看到第一级是省/直辖市,第二级才是我们要的城市(city)。这里我们简单地用for去循环读取每个城市的数据。

 

在city里有‘citycode’这一个数据。通过这个城市编号在数据库中查找相应的经纬度,我下载的数据库是Excel格式。那我们依然用pandas获取这一列数据。

geo_df = pd.read_excel("./area.xlsx")

for index, row in geo_df.iterrows():
    print( str(row['area_code']) )

pandas可以使用 iterrows()对dataframe进行遍历。iterrows()返回值为元组,(index,row)
上面的代码里,for循环定义了两个变量 index,row,那么返回的元组,index=index,row=row.

我这里只需要row。里面就是具体城市的地理数据了。

 

3、生成folium数据集:

在新浪的接口里返回的citycode显示着各个省/城市/地区的编号,只不过开头是大写的CN,而且后面是以0填充到一定长度。那只需忽略开头的CN并且只匹配开头。如果匹配成功,获取Excel中的对应经度纬度。和患病人数一起组成列表,跳出循环。

这个数组是给folium 的 Heatmap函数使用的。Heatmap的第一个参数为数值集合,类型是列表 list,集合中每个子元素也是一个list。格式为:[经度, 纬度, 范围]

def get_fymap_data(url_str):
    r = requests.get(url_str, timeout=5)
    """ to pandas dataframe """
    # load json
    df = pd.DataFrame(r.json())
    # find 'list'
    province_data_list = df.loc['list', 'data']
    heatmap_list = []
    # load xlsx
    geo_df = pd.read_excel("./area.xlsx")

    for data_list in province_data_list:
        # ignore empty list
        if len(data_list['city']) != 0:
            for city_dict in data_list['city']:
                # find city/area
                if city_dict['citycode'] != "" and city_dict['conNum'] != "0":
                    for index, row in geo_df.iterrows():
                        a = str(city_dict['citycode'])
                        b = str(row['area_code'])
                        if a.startswith('CN' + b):
                            # heatmap data : [lat, lon, range]
                            heat_data = [round(row['lat'], 3), round(row['lon'], 3), float(city_dict['econNum'])]
                            heatmap_list.append( heat_data )
                            break
    return heatmap_list

这里就返回了相应的列表。

 

    map_data = get_fymap_data("https://interface.sina.cn/news/wap/fymap2020_data.d.json")
    map_osm = folium.Map(location=[35,110],zoom_start=5)
    HeatMap(map_data, name="coronavirus", min_opacity=0.8).add_to(map_osm)
    file_path = r"./test.html"
    map_osm.save(file_path)

将地图坐标定位到中国,这样一打开就可以定位到我们想到的地方:

map_osm = folium.Map(location=[35,110],zoom_start=5)

加载数据:

HeatMap(map_data, name="coronavirus", min_opacity=0.8).add_to(map_osm)

最后生成html文件。

 

源文件:

https://github.com/elihe999/Eli_observations/blob/master/python/c19map/download_map.py

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值