欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

疫情世界地图

发布时间:2023/12/15 编程问答 49 豆豆
生活随笔 收集整理的这篇文章主要介绍了 疫情世界地图 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

疫情这么严重,想着说做个世界地图实时显示下疫情信息,结果做着做着发现有人已经做好了(可惜因为没有国内的相关资质不能随意发布数据,所以不能贴网址):
COVID-19 Dashboard by the Center for Systems Science and Engineering (CSSE) at Johns Hopkins University (JHU)
好吧,那就当学习吧:

数据来源

我在[某个无法透露的地址]找到了新冠疫情的实时数据,
每天更新,和上面的霍普金斯大学数据基本一致,还是比较靠谱的。
不过就是recovered的数字全是0。。。
数据格式如下:

{"latest":{"confirmed":1917319,"deaths":119482,"recovered":0},"locations":[{"id":0,"country":"Afghanistan","country_code":"AF","country_population":29121286,"province":"","last_updated":"2020-04-14T03:01:19.940220Z","coordinates":{"latitude":"33.0","longitude":"65.0"},"latest":{"confirmed":665,"deaths":21,"recovered":0}},...]

国家的数据放在locations里面,不过有点小问题,就是有些国家的数据是分省的,这个给我后面的geojson处理带来很多麻烦以至于没有成功,后面再说。

实现

基于folium实现热力图

首先想到是用folium来做,地图支持的比较好嘛~
废话不多先上代码:

# -*- coding: UTF-8 -*- # Ver 0.1 # Author:advancedanimalimport numpy as np import folium import os import pandas as pd from folium.plugins import HeatMap import json import urllib.request# GPS of current location latitude = 31.19 longitude = 121.32 map_data = folium.Map(location=[latitude, longitude], zoom_start=4,tiles=('http://www.google.cn/maps/vt?lyrs=m@189&gl=cn&x={x}&y={y}&z={z}'),attr='default')# Read Dataset resp = urllib.request.urlopen('https://coronavirus-tracker-api.herokuapp.com/v2/locations') org_data = (json.loads(resp.read()))['locations'] json_data = pd.json_normalize(org_data)# Instantiate a feature group for the incidents in the dataframe incidents = folium.map.FeatureGroup()# Add circle on the map for country_no in json_data.id:incidents.add_child(folium.CircleMarker([json_data["coordinates.latitude"][country_no],json_data["coordinates.longitude"][country_no]],radius=7,color='yellow',fill=True,fill_color='red',fill_opacity=0.4)) map_data.add_child(incidents)# Add pop-up text to circles for country_no in json_data.id:if json_data.province[country_no] != '':label_tooltip = "{}{}{}{}{}".format(str(json_data.province[country_no]),' CONFIRM:',str(json_data["latest.confirmed"][country_no]),' DEATH:',str(json_data["latest.deaths"][country_no]))else:label_tooltip = "{}{}{}{}{}".format(str(json_data.country[country_no]),' CONFIRM:',str(json_data["latest.confirmed"][country_no]),' DEATH:',str(json_data["latest.deaths"][country_no]))folium.RegularPolygonMarker([json_data["coordinates.latitude"][country_no],json_data["coordinates.longitude"][country_no]],tooltip=label_tooltip,number_of_sides=10,radius=5).add_to(map_data)# Convert data format lat = np.array(json_data["coordinates.latitude"][0:255], dtype=float) lon = np.array(json_data["coordinates.longitude"][0:255], dtype=float) confirm = np.array(json_data["latest.confirmed"][0:255], dtype=float) heatdata = [[lat[i], lon[i], confirm[i]] for i in range(255)]# add incidents to map HeatMap(heatdata, radius=40).add_to(map_data)

效果:

热力图倒是出来了,但是我寻思着这个效果还是不太明显,毕竟热力图主要是用圆圈融合起来的,
要是能按国界来把各个国家上色就好了,于是有了下面的第二版:

基于geojson的按国家边界涂色

本来还想用folium+geojson来做的,我找了个全世界各个国家的polygon数据,可是很奇怪这个数据里面的所有MultiPolygon都无法在地图上描画出来(没有省份数据的Polygon倒是没有问题),我试着把MultiPolygon里面的数据都提取出来,结果好像也不行全是杂乱的线条,不得已先放一放,改用别的方法。

基于pygal的按国家边界涂色

pygal算是上面geojson的一个低配版吧,毕竟国家数据都内嵌了,只要按照国家代码给数据就行了。
看代码:

# -*- coding: UTF-8 -*- # Ver 0.2 # Author:advancedanimalimport pygal_maps_world.maps import pygal.style import json import urllib.request import pandas as pdwm_style = pygal.style.RotateStyle('#336699', base_style=pygal.style.LightColorizedStyle) wm = pygal_maps_world.maps.World(style=wm_style) wm.title = 'Corona Virus Situation' # with open('corona_situation_org_20200414') as local_data: # org_data = (json.load(local_data))['locations'] resp = urllib.request.urlopen('https://coronavirus-tracker-api.herokuapp.com/v2/locations') org_data = (json.loads(resp.read()))['locations'] json_data = pd.json_normalize(org_data)dict_data_confirmed = {} dict_data_deaths = {} for country_no in json_data.id:dict_value_confirmed = dict_data_confirmed.get(str(json_data.country_code[country_no]).lower())dict_value_deaths = dict_data_deaths.get(str(json_data.country_code[country_no]).lower())if dict_value_confirmed is not None:dict_value_confirmed += json_data['latest.confirmed'][country_no]dict_value_deaths += json_data['latest.deaths'][country_no]else:dict_value_confirmed = json_data['latest.confirmed'][country_no]dict_value_deaths = json_data['latest.deaths'][country_no]dict_data_confirmed[str(json_data.country_code[country_no]).lower()] = dict_value_confirmeddict_data_deaths[str(json_data.country_code[country_no]).lower()] = dict_value_deaths # wm.add('Deaths', dict_data_deaths) wm.add('Confirmed', dict_data_confirmed)wm.render_to_file('corona_map.svg')


但是也还是有问题

  • 地图无法放大缩小(pygal自身问题,好像没法解决)
  • 颜色种类不够多,导致很多国家的颜色都差不多(我只是按照各个国家的确认人数给了数字让pygal自动设颜色了,理论上是可以给各个国家设不同颜色的,不过工作量好像有点大。。)
  • 对于同一个国家无法设置不同的数据,比如我希望通过点击图例,能看到确认和死亡人数,这个好像pygal也做不到(这也是我上面有个dict_data_deaths但是没有用的原因)

所以呢,pygal只能大致看看,真要是仔细看内容的话,可能还得用回geojson,我再研究研究。

总结

以上是生活随笔为你收集整理的疫情世界地图的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。