新冠肺炎数据可视化

数据获取

目前,腾讯的疫情实时追踪 网页能够看到实时的新冠病毒数据,网页的数据展示也非常清晰。但这个网页提供的数据没有每个市的历史数据。其它几个新闻网页的数据也都大同小异。

为了能够得到自己想看的数据,尤其的自己比较关心的数据,我观察了几个网址的数据并且用 Python 进行了获取。下面对数据获取和数据展示的方法进行介绍,供大家参考。

腾讯网页数据源

为了便于对照,建议大家使用 Chrome 浏览器查看,其实每种浏览器都类似,但界面不同,看自己的习惯。用 Chrome 打开 疫情实时追踪 页面,然后按下 F12,Chrome 打开 Developer Tools,再次点击页面刷新按钮,追踪到数据获取的的 Script 如下:

Response 返回的是 applicatio/json 格式的数据(Response Headers: application/json),双击左边的 getOnsInfo**, Chrome 打开一个新的页面,展示最新的病情数据:


我们再看 Query String Parameters 中有两个参数,其中 callback 参数应该是一个基于毫秒级别的时间戳。URL 去掉这个 callback 参数也可以获得最新的感染人数数据。



对这个返回的 json 数据,我们可以另存为一个 json 文件,并对数据的结构进行分析。分析的过程这里就不展开了。在这个网页中能获得如下数据:

  • 中国确认的总人数(chinaTotal)
  • 新增人数(chinaAdd)
  • 每日人数汇总历史数据(chinaDayList)
  • 每日新增人数历史数据(chinaDayAddList)
  • 每日新增人数历史数据,分湖北、非湖北、全国三个维度 (dailynewAddHistory)
  • 每日死亡率历史数据 (dailyDeadRateHistory)
  • areaTree: 这个节点下面包全世界数据,中国数据到市级的数据,是最详细的。

通过 Web API 获取

除了腾讯这种新闻页面,我们利用页面的数据源间接获取,也可以利用网上 Web API 进行获取。比如天气 api 就提供了疫情的 API。打开 http://tianqiapi.com/ 网页,我们可以看到页面有一个连接:


点击进入开发者指南页面,对调用的 url 和返回格式有详细说明。允许每天免费调用 3 万次,但需要先注册一个账号。

另外,Github 上也比较活跃,有很多项目利用爬虫,从诸如丁香医生的网站上爬取数据,然后提供数据更新和 Web API 服务。下面的这个项目就挺不错:

项目地址:https://github.com/BlankerL/DXY-COVID-19-Crawler
数据仓库:https://github.com/BlankerL/DXY-COVID-19-Data

这个项目提供的 api 调用示例如下:

https://lab.isaaclin.cn/nCoV/api/overall  # 返回全面疫情概况
https://lab.isaaclin.cn/nCoV/api/provinceName  # 返回省列表
https://lab.isaaclin.cn/nCoV/api/area?latest=0&province=湖北省  # 返回湖北省历史数据

API 调用请自行阅读 API 调用说明。

数据可视化

我根据自己的目的,使用 pandas 模块,将数据保存到 Excel,通过 pyecharts 模块,将可视化地图保存为 html 文件,代码比较直观,主要的处理过程为对含有多层次的数据进行扁平化,得到一个二维的数据。地图中显示的数据市确认病例的数据。pyecharts 的版本迭代较快,并且 0.5 版和 1.0 版不兼容。我使用的是 1.6 版。

import requests
import json
import pandas as pd
import os
import datetime

from pyecharts import options as opts
from pyecharts.charts import *

cities = []
def get_ncov_data() -> str:
    url = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5'
    data = requests.get(url).json()['data']

    return data

def get_daily_data() -> list:
    all = json.loads(get_ncov_data())
    return all['chinaDayList']


def flatten_ncov_data() -> list:
    all = json.loads(get_ncov_data())
    date = all['lastUpdateTime']

    # 第一层:国家
    china = all['areaTree'][0]['children']  # get China data

    # 第二层:省
    for province in china:
        province_ncov = province['children']

        # 第三层:市
        for city in province_ncov:
            # 输出格式
            city_ncov = {
                '日期': date,
                '省份': province['name'],
                '市': city['name'],
                '新增确认': city['today']['confirm'],
                '新增治愈': city['today']['heal'],
                '新增死亡': city['today']['dead'],
                '累计确认': city['total']['confirm'],
                '累计治愈': city['total']['heal'],
                '累计死亡': city['total']['dead']
            }

            cities.append(city_ncov)

def export_excel():
    cities.clear()
    flatten_ncov_data()
    df = pd.DataFrame(cities)

    # 导出Excel
    path = os.path.dirname(os.path.abspath(__file__))
    output_file = os.path.join(path, 'output.xlsx')

    df.to_excel(output_file)

def render_map_chart():
    cities.clear()
    flatten_ncov_data()
    df = pd.DataFrame(cities)

    # Render Map chart
    map_chart = Map()
    map_chart.add(
        "中国",  # map name
        [list(z) for z in zip(list(df["省份"]), list(df['累计确认']))],
        "china",
        is_map_symbol_show=False
    )

    map_chart.set_global_opts(
        title_opts=opts.TitleOpts(
            title="nCoV疫情地图(" + str(datetime.date.today()) + ")"
        ),
        visualmap_opts=opts.VisualMapOpts(
            max_=50000,
            is_piecewise=True,
            pieces=[
                {"min": 1, "max": 9, "label": "10人以下", "color": "#FFE6BE"},
                {"min": 10, "max": 99, "label": "10-99人", "color": "#FFB769"},
                {"min": 100, "max": 499, "label": "100-499人", "color": "#FF8F66"},
                {"min": 500, "max": 999, "label": "500-999人", "color": "#ED514E"},
                {"min": 1000, "max": 50000, "label": "1000人以上", "color": "#CA0D11"}
            ]))

    map_chart.render('ncov_map_chart_{}.html'.format(datetime.date.today()))


def render_line_chart():
    daily_data = get_daily_data()
    df = pd.DataFrame(daily_data)

    line_chart = Line()
    line_chart.add_xaxis(list(df["date"]))
    line_chart.add_yaxis("确认", list(df["confirm"]))
    line_chart.add_yaxis("疑似", list(df["suspect"]))
    line_chart.set_global_opts(
        title_opts=opts.TitleOpts(title="nCoV确认病例与疑似病例曲线")
    )

    line_chart.render('ncov_line_chart-{}.html'.format(datetime.date.today()))


if __name__ == "__main__":

    export_excel()
    render_map_chart()
    render_line_chart()

地图显示的效果如下,与腾讯疫情地图图例的颜色一样。

确认和疑似病例的日趋势曲线如下:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352