Python 绘制全球疫情地图

Python 绘制全球疫情地图

海内疫情获得控制后,我就没怎么再体贴过疫情,最近看到一条新闻,全球疫情累计确诊人数已经突破 500w 大关,看到这个数字我照样有点受惊的。

思来想去,照样写一篇全球疫情的剖析的文章,本文包罗网络爬虫、全球疫情舆图绘制等方面。

网络爬虫

我之前有分享过疫情数据的泉源,用的是 AKShare 的数据源,好用是真好用,就是网络太慢了, AKShare 的数据很多是泉源于 GitHub ,我的网络接见太平洋彼岸的数据照样有点力有未逮。

这次我换了新的数据源,泉源腾讯新闻的实时数据,站点链接如下:

Python 绘制全球疫情地图

原本我以为需要剖析页面元素,才气获取到数据,然则等我剖析了 network 以后发现,竟然可以直接找到数据接口,这大大的方便了我们数据抓取。

Python 绘制全球疫情地图

获取全球疫情数据接口如下:

https://api.inews.qq.com/newsqa/v1/automation/foreign/country/ranklist

把这个接口放在 PostMan 内里模拟接见一下:

Python 绘制全球疫情地图

从这道字符串处理的难题,寻找解决复杂问题的套路

毫无反爬手段,header 神马的都不需要设置,直接接见就能拿到数据,到这里,我们可以最先写爬虫的代码了,最终代码如下:

import requests
from datetime import datetime

def catch_data():
    """
    抓取当前实时数据,并返回 国家、大洲、确诊、疑似、殒命、治愈 列表
    :return:
    """
    url = 'https://api.inews.qq.com/newsqa/v1/automation/foreign/country/ranklist'
    data = requests.post(url).json()['data']

    date_list = list()  # 日期
    name_list = list() # 国家
    continent_list = list() # 大洲
    confirm_list = list()  # 确诊
    suspect_list = list()  # 疑似
    dead_list = list()  # 殒命
    heal_list = list()  # 治愈

    for item in data:
        month, day = item['date'].split('.')
        date_list.append(datetime.strptime('2020-%s-%s' % (month, day), '%Y-%m-%d'))
        name_list.append(item['name'])
        continent_list.append(item['continent'])
        confirm_list.append(int(item['confirm']))
        suspect_list.append(int(item['suspect']))
        dead_list.append(int(item['dead']))
        heal_list.append(int(item['heal']))

    return date_list, name_list, continent_list, confirm_list, suspect_list, dead_list, heal_list


def save_csv():
    """
    将数据存入 csv 文件
    :return:
    """
    date_list, name_list, continent_list, confirm_list, suspect_list, dead_list, heal_list = catch_data()
    fw = open('2019-nCoV.csv', 'w', encoding='utf-8')
    fw.write('date,name,continent,confirm,suspect,dead,heal\n')

    i = 0
    while i < len(date_list):
        date = str(date_list[i].strftime("%Y-%m-%d"))
        fw.write(date + ',' + str(name_list[i]) + ',' + str(continent_list[i]) + ',' + str(confirm_list[i]) + ',' + str(suspect_list[i]) + ',' + str(dead_list[i]) + ',' + str(heal_list[i]) + '\n')
        i = i + 1
    else:
        print("csv 写入完成")
        fw.close()


if __name__ == '__main__':
    save_csv()

最终获得的 csv 文件是这样的:

Python 绘制全球疫情地图

全球疫情舆图

前端或网站开发的同伙应该都使用过壮大的 Echarts 插件。 ECharts 是一个纯 Javascript 的图表库,可以流通的运行在 PC 和移动装备上,兼容当前绝大部分浏览器,底层依赖轻量级的 Canvas 类库 ZRender ,提供直观、生动、可交互、可高度个性化定制的数据可视化图表。 ECharts 提供了通例的折线图、柱状图、散点图、饼图、K线图,用于统计的盒形图,用于地理数据可视化的舆图、热力争、线图,用于关系数据可视化的关系图、treemap,多维数据可视化的平行坐标,另有用于 BI 的漏斗图、仪表盘,而且支持图与图之间的混搭。

既然 Echarts 云云壮大, Python 一定有响应的第三方扩展包支持,它就是我们接下来绘制世界舆图要用到的 PyEcharts 。 PyEcharts 是一个用于天生 Echarts 图表的类库,即 Echarts 与 Python 的对接。

安装语句如下:

pip install pyecharts

PyEcharts 安装完成后我们就可以最先写接下来的代码了,如下:

from pyecharts import options as opts
from pyecharts.charts import Map
import pandas as pd
import namemap

def read_country_code():
    """
    获取国家中英文字典
    :return:
    """
    country_dict = {}
    for key, val in namemap.nameMap.items():  # 将 nameMap 列表内里键值交换
        country_dict[val] = key
    return country_dict

def read_csv():
    """
    读取数据,返回国家英文名称列表和累计确诊数列表
    :return:
    """
    country_dict = read_country_code()
    data = pd.read_csv("2019-nCoV.csv", index_col=False)

    countrys_names = list()
    confirmed_count = list()

    for x in range(len(data.index)):
        if data['name'].iloc[x] in country_dict.keys():
            countrys_names.append(country_dict[data['name'].iloc[x]])
            confirmed_count.append(data['confirm'].iloc[x])
        else:
            print(data['name'].iloc[x])

    return countrys_names, confirmed_count


def draw_map():
    """
    绘制世界舆图
    遇到一个很神奇的问题:
    两个列表必须写死数据舆图才会渲染数据,若是数据是从方式中获得,则舆图不渲染数据
    :return:
    """

    # countrys_names, confirmed_count = read_csv()
    # print(countrys_names)
    # print(confirmed_count)

    countrys_names = ['United States', 'Brazil', 'Russia'...]

    confirmed_count = [1666828, 347398, 335882...]


    c = (
        Map()
        .add(
            "确诊人数",
            [list(z) for z in zip(countrys_names, confirmed_count)],
            is_map_symbol_show=False,
            maptype="world",
            label_opts=opts.LabelOpts(is_show=False),
            itemstyle_opts=opts.ItemStyleOpts(color="rgb(49,60,72)")
        )
        .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
        .set_global_opts(
            title_opts=opts.TitleOpts(title="全球 2019-nCoV 舆图"),
            visualmap_opts=opts.VisualMapOpts(max_=1700000),
        )
        .render("map_world.html")
    )


if __name__ == '__main__':
    draw_map()

最终效果如下:

Python 绘制全球疫情地图

在绘制全球疫情舆图的时刻,我们最终使用的国家的名称是英文的,以是需要用到一个中英文国家名称对照字典,这个字典我找到了两个版本,一个是 Python 花样的文件 namemap.py ,另有一个是 json 花样的文件 country-code.json , 使用这两个文件中的随便一个将我们在前面获取到的数据中的中文国家名称转换为英文。这两个文件我都市提交到代码堆栈,有需要的同砚可以在民众号里回复关键字获取。

另外,在最后绘制舆图的时刻遇到了一个很奇葩的问题,国家名称列表和累计确诊人数列表若是是早年面的方式中获取到的,在最后渲染成 map_world.html 的时刻,将不会渲染数字,所有的数字都是 null ,然则若是这两个列表 copy 出来,写死在代码中,就可以乐成的渲染,有清晰这个问题的同伙可以在留言中解答一下,万分感激。

需要源代码的同砚可以在民众号后台回复「全球疫情」获取。

原创文章,作者:admin,如若转载,请注明出处:https://www.2lxm.com/archives/11887.html