【世界加油⛽️】基于Pyecharts的疫情数据可视化~

更新数据

Python系列教程,免费获取,遇到bug及时反馈,讨论交流可加扣裙<60 61 15 02 7>

 由于目前时间序列数据越来越大了,通过requests请求实在太慢 & 不稳定,现改用git来更新数据;

首次使用请先执行以下命令,数据会下载到/home/kesci/work/covid-19/json/路径下(第一次是更新全量,所以会很慢,耐心的等待☕️);

# 建立文件夹 covid-19  
mkdir covid-19  
cd covid-19  
git init  
# 指定远程仓库地址  
git remote add -f origin https://github.com/BlankerL/DXY-COVID-19-Data.git  
# 设置允许克隆子项目  
git config core.sparsecheckout true  
# 子项目路径  
echo json >> .git/info/sparse-checkout  
# 通过pull拉取代码  
git pull origin master

In [1]:

%cd covid-19
!git init 

# 设置允许克隆子项目
!git config core.sparsecheckout true

# 子项目路径
!echo json >> .git/info/sparse-checkout

# 拉取数据
!git pull origin master
/home/kesci/work/covid-19
Reinitialized existing Git repository in /home/kesci/work/covid-19/.git/
remote: Enumerating objects: 307, done.
remote: Counting objects: 100% (307/307), done.
remote: Compressing objects: 100% (22/22), done.
error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed

In [2]:

import warnings

warnings.filterwarnings("ignore")

In [3]:

import requests
import pyecharts
from pyecharts.charts import *
from pyecharts import options as opts
from pyecharts.commons.utils import JsCode
from pyecharts.datasets import register_url
import pandas as pd
from datetime import date
import datetime
from dateutil import tz
import json

数据来源

  • 通过https://lab.isaaclin.cn/nCoV/api/area接口获取最新疫情数据;

  • 通过https://lab.isaaclin.cn/nCoV/api/area?latest=0接口获取时间序列疫情数据;

  • 通过http://lab.isaaclin.cn/nCoV/api/overall?latest=0接口获取全国时间序列疫情数据;

详细的API使用介绍可直接访问https://lab.isaaclin.cn/nCoV/zh查看。

In [4]:

update_date = datetime.datetime.now(tz=tz.gettz(
    'Asia/Shanghai')).strftime('%Y-%m-%d %H:%M:%S')

# 最新数据
with open('/home/kesci/work/covid-19/json/DXYArea.json', 'r') as f:
    data = json.load(f)

# 全球时间序列数据
with open('/home/kesci/work/covid-19/json/DXYArea-TimeSeries.json', 'r') as f:
    area_data_timeline = json.load(f)

# 全国时间序列数据
with open('/home/kesci/work/covid-19/json/DXYOverall-TimeSeries.json', 'r') as f:
    all_data_timeline = json.load(f)

如果要继续沿用requests请将替换成

# 生成更新时间  
update_date = datetime.datetime.now(tz=tz.gettz('Asia/Shanghai')).strftime('%Y-%m-%d %H:%M:%S')  


# 建立连接太多时会报错  
# 同一个会话下请求  
sess = requests.session()  
# 数据来源于 Github DXY-COVID-19-Data, 原作者为 Isaac Lin  
url = 'https://github.com/BlankerL/DXY-COVID-19-Data/raw/master/json/DXYArea.json'  
data = sess.get(url, verify=False).json()  

# 获取时间序列数据  
# 细分到城市  
# 数据量较大,大约1-3mins  
area_data_timeline = sess.get('http://raw.githubusercontent.com/BlankerL/DXY-COVID-19-Data/master/json/DXYArea-TimeSeries.json',   
                                    verify=False).json()  

# 全国数据  
all_data_timeline = sess.get('http://github.com/BlankerL/DXY-COVID-19-Data/raw/master/json/DXYOverall-TimeSeries.json',   
                                 verify=False).json()

最新疫情数据

海内外疫情对比

In [5]:

oversea_data = {'currentConfirmedCount': {'国内': 0, '海外': 0},
                'confirmedCount': {'国内': 0, '海外': 0},
                'curedCount': {'国内': 0, '海外': 0},
                'deadCount': {'国内': 0, '海外': 0}}
for item in data['results']:
    if item['provinceEnglishName'] == 'China':
        oversea_data['currentConfirmedCount']['国内'] += item['currentConfirmedCount']
        oversea_data['confirmedCount']['国内'] += item['confirmedCount']
        oversea_data['curedCount']['国内'] += item['curedCount']
        oversea_data['deadCount']['国内'] += item['deadCount']
    elif item['countryEnglishName'] != 'China':
        oversea_data['currentConfirmedCount']['海外'] += item['currentConfirmedCount']
        oversea_data['confirmedCount']['海外'] += item['confirmedCount']
        oversea_data['curedCount']['海外'] += item['curedCount']
        oversea_data['deadCount']['海外'] += item['deadCount']

fn = """
    function(params) {
        if(params.name == '海外')
            return '\\n\\n\\n' + params.name + ' : ' + params.value;
        return params.seriesName + '\\n' + params.name + ' : ' + params.value;
    }
    """


def new_label_opts():
    return opts.LabelOpts(formatter=JsCode(fn), position="center")


pie = (Pie(init_opts=opts.InitOpts(theme='dark', width='1000px'))
       .add(
    "当前确诊",
    [(x, y) for x, y in oversea_data['currentConfirmedCount'].items()],
    center=["30%", "30%"],
    radius=[60, 90],
    label_opts=new_label_opts(),
)
    .add(
        "累计确诊",
        [(x, y) for x, y in oversea_data['confirmedCount'].items()],
        center=["70%", "30%"],
        radius=[60, 90],
        label_opts=new_label_opts(),
)
    .add(
        "治愈",
        [(x, y) for x, y in oversea_data['curedCount'].items()],
        center=["30%", "75%"],
        radius=[60, 90],
        label_opts=new_label_opts(),
)
    .add(
        "死亡",
        [(x, y) for x, y in oversea_data['deadCount'].items()],
        center=["70%", "75%"],
        radius=[60, 90],
        label_opts=new_label_opts(),
)
    .set_global_opts(
        title_opts=opts.TitleOpts(title="海内外疫情数据对比",
                                  subtitle="更新时间:{}".format(update_date)),
        legend_opts=opts.LegendOpts(is_show=True),)
    .set_series_opts(
        tooltip_opts=opts.TooltipOpts(
            trigger="item", formatter="{a} 
{b}: {c} ({d}%)" ),) ) pie.render_notebook()

Out[5]:

 

全球疫情地图

In [6]:

oversea_confirm = []
for item in data['results']:
    if item['provinceEnglishName']:
        oversea_confirm.append((item['provinceEnglishName'].replace('United States of America', 'United States')
                                .replace('United Kiongdom', 'United Kingdom'),
                                item['currentConfirmedCount']))

_map = (
    Map(init_opts=opts.InitOpts(theme='dark', width='1000px'))
    .add("当前确诊人数", oversea_confirm, "world", is_map_symbol_show=False,  is_roam=False)
    .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
    .set_global_opts(
        title_opts=opts.TitleOpts(title="新型冠状病毒全球疫情地图",
                                  subtitle="更新时间:{}".format(update_date)),
        legend_opts=opts.LegendOpts(is_show=False),
        visualmap_opts=opts.VisualMapOpts(is_show=True, max_=10000,
                                          is_piecewise=False,
                                          range_color=['#FFFFE0', '#FFA07A', '#CD5C5C', '#8B0000']),
        graphic_opts=[
            opts.GraphicGroup(
                graphic_item=opts.GraphicItem(
                    bounding="raw",
                    right=150,
                    bottom=50,
                    z=100,
                ),
                children=[
                    opts.GraphicRect(
                        graphic_item=opts.GraphicItem(
                            left="center", top="center", z=100
                        ),
                        graphic_shape_opts=opts.GraphicShapeOpts(
                            width=200, height=50
                        ),
                        graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
                            fill="rgba(0,0,0,0.3)"
                        ),
                    ),
                    opts.GraphicText(
                        graphic_item=opts.GraphicItem(
                            left="center", top="center", z=100
                        ),
                        graphic_textstyle_opts=opts.GraphicTextStyleOpts(
                            text=JsCode("['钻石号邮轮', '当前确诊人数:{}人'].join('\\n')"
                                        .format(dict(oversea_confirm)['Diamond Princess Cruise Ship'])),
                            font="bold 16px Microsoft YaHei",
                            graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
                                fill="#fff"
                            ),
                        ),
                    ),
                ],
            )
        ],
    )
)

_map.render_notebook()

Out[6]:

 

全国疫情地图

In [7]:

cofirm, currentCofirm, cured, dead = [], [], [], []
for item in data['results']:
    if item['countryName'] == '中国':
        cofirm.append((item['provinceShortName'], item['confirmedCount']))
        currentCofirm.append(
            (item['provinceShortName'],
             item['currentConfirmedCount']))
        cured.append((item['provinceShortName'], item['curedCount']))
        dead.append((item['provinceShortName'], item['deadCount']))

tab = Tab()

_map = (
    Map(init_opts=opts.InitOpts(theme='dark', width='1000px'))
    .add("累计确诊人数", cofirm, "china", is_map_symbol_show=False,  is_roam=False)
    .set_series_opts(label_opts=opts.LabelOpts(is_show=True))
    .set_global_opts(
        title_opts=opts.TitleOpts(title="新型冠状病毒全国疫情地图",
                                  subtitle="更新时间:{}".format(update_date)),
        legend_opts=opts.LegendOpts(is_show=False),
        visualmap_opts=opts.VisualMapOpts(is_show=True, max_=1000,
                                          is_piecewise=False,
                                          range_color=['#FFFFE0', '#FFA07A', '#CD5C5C', '#8B0000'])
    )
)
tab.add(_map, '累计确诊')

_map = (
    Map(init_opts=opts.InitOpts(theme='dark', width='1000px'))
    .add("当前确诊人数", currentCofirm, "china", is_map_symbol_show=False,  is_roam=False)
    .set_series_opts(label_opts=opts.LabelOpts(is_show=True))
    .set_global_opts(
        title_opts=opts.TitleOpts(title="新型冠状病毒全国疫情地图",
                                  subtitle="更新时间:{}".format(update_date)),
        legend_opts=opts.LegendOpts(is_show=False),
        visualmap_opts=opts.VisualMapOpts(is_show=True, max_=100,
                                          is_piecewise=False,
                                          range_color=['#FFFFE0', '#FFA07A', '#CD5C5C', '#8B0000'])
    )
)
tab.add(_map, '当前确诊')

_map = (
    Map(init_opts=opts.InitOpts(theme='dark', width='1000px'))
    .add("治愈人数", cured, "china", is_map_symbol_show=False,  is_roam=False)
    .set_series_opts(label_opts=opts.LabelOpts(is_show=True))
    .set_global_opts(
        title_opts=opts.TitleOpts(title="新型冠状病毒全国疫情地图",
                                  subtitle="更新时间:{}".format(update_date)),
        legend_opts=opts.LegendOpts(is_show=False),
        visualmap_opts=opts.VisualMapOpts(is_show=True, max_=1000,
                                          is_piecewise=False,
                                          range_color=['#FFFFE0', 'green'])
    )
)
tab.add(_map, '治愈')

_map = (
    Map(init_opts=opts.InitOpts(theme='dark', width='1000px'))
    .add("死亡人数", dead, "china", is_map_symbol_show=False,  is_roam=False)
    .set_series_opts(label_opts=opts.LabelOpts(is_show=True))
    .set_global_opts(
        title_opts=opts.TitleOpts(title="新型冠状病毒全国疫情地图",
                                  subtitle="更新时间:{}".format(update_date)),
        legend_opts=opts.LegendOpts(is_show=False),
        visualmap_opts=opts.VisualMapOpts(is_show=True, max_=50,
                                          is_piecewise=False,
                                          range_color=['#FFFFE0', '#FFA07A', '#CD5C5C', '#8B0000'])
    )
)
tab.add(_map, '死亡')

tab.render_notebook()

Out[7]:

累计确诊当前确诊治愈死亡

 

境外输入病例

In [8]:

out_in_data = []

for item in data['results']:
    if item['cities']:
        for city in item['cities']:
            if city['cityName'] == '境外输入':
                out_in_data.append(
                    (item['provinceShortName'], city['confirmedCount']))
out_in_data = sorted(out_in_data, key=lambda x: x[1],  reverse=True)

bar = (
    Bar(init_opts=opts.InitOpts(theme='dark', width='1000px'))
    .add_xaxis([x[0] for x in out_in_data if x[1] > 0])
    .add_yaxis("境外输入", [x[1] for x in out_in_data if x[1] > 0],
               itemstyle_opts=opts.ItemStyleOpts(
        border_color='rgb(220,220,220)',
        color=JsCode("""new echarts.graphic.LinearGradient(0, 0, 0, 1,
                                             [{
                                                 offset: 0,
                                                 color: 'rgb(255,99,71)'
                                             }, {
                                                 offset: 1,
                                                 color: 'rgb(32,178,170)'
                                             }])""")))
    .set_series_opts(label_opts=opts.LabelOpts(is_show=True,
                                               position='top',
                                               font_style='italic'))
    .set_global_opts(
        title_opts=opts.TitleOpts(title="境外输入病例",
                                  subtitle="更新时间:{}".format(update_date)),
        xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=45)),
        legend_opts=opts.LegendOpts(is_show=False),
    )
)

bar.render_notebook()

Out[8]:

 

湖北省内确诊情况

In [9]:

for item in data['results']:
    if item['provinceShortName'] == '湖北':
        hubei_data = item['cities']

bar = (
    Bar(init_opts=opts.InitOpts(theme='dark', width='1000px'))
    .add_xaxis([x['cityName'] for x in hubei_data])
    .add_yaxis("治愈", [x['curedCount'] for x in hubei_data], stack="stack1",
               itemstyle_opts=opts.ItemStyleOpts(
        border_color='rgb(220,220,220)',
        color=JsCode("""new echarts.graphic.LinearGradient(0, 0, 0, 1,
                                             [{
                                                 offset: 0,
                                                 color: 'rgb(255,215,0)'
                                             }, {
                                                 offset: 1,
                                                 color: 'rgb(32,178,170)'
                                             }])""")))
    .add_yaxis("当前确诊", [x['currentConfirmedCount'] for x in hubei_data], stack="stack1",
               itemstyle_opts=opts.ItemStyleOpts(border_color='rgb(220,220,220)',
                                                 color=JsCode("""new echarts.graphic.LinearGradient(0, 0, 0, 1,
                                             [{
                                                 offset: 0,
                                                 color: 'rgb(255,99,71)'
                                             }, {
                                                 offset: 1,
                                                 color: 'rgb(255,215,0)'
                                             }])""")))
    .add_yaxis("死亡", [x['deadCount'] for x in hubei_data], stack="stack1",
               itemstyle_opts=opts.ItemStyleOpts(border_color='rgb(220,220,220)',
                                                 color=JsCode("""new echarts.graphic.LinearGradient(0, 0, 0, 1,
                                             [{
                                                 offset: 0,
                                                 color: 'rgb(128,0,0)'
                                             }, {
                                                 offset: 1,
                                                 color: 'rgb(255,99,71)'
                                             }])""")))
    .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
    .set_global_opts(
        title_opts=opts.TitleOpts(title="湖北省内确诊情况",
                                  subtitle="更新时间:{}".format(update_date)),
        xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=45)),
        legend_opts=opts.LegendOpts(is_show=True),
        graphic_opts=[
            opts.GraphicGroup(
                graphic_item=opts.GraphicItem(
                    bounding="raw",
                    right=200,
                    top=120
                ),
                children=[
                    opts.GraphicRect(
                        graphic_item=opts.GraphicItem(
                            left="center", top="center"
                        ),
                        graphic_shape_opts=opts.GraphicShapeOpts(
                            width=200, height=60
                        ),
                        graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
                            fill="rgba(0,0,0,0.3)"
                        ),
                    ),
                    opts.GraphicText(
                        graphic_item=opts.GraphicItem(
                            left="center", top="center", z=1
                        ),
                        graphic_textstyle_opts=opts.GraphicTextStyleOpts(
                            text=JsCode(
                                "['当前确诊人数:', '','累计确诊人数-死亡人数-治愈人数'].join('\\n')"),
                            font="bold 12px Microsoft YaHei",
                            graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
                                fill="#fff"
                            ),
                        ),
                    ),
                ],
            )
        ],
    )
)

bar.render_notebook()

Out[9]:

 

全国疫情热力图

In [10]:

cities_data = []
for item in data['results']:
    if item['countryName'] == '中国':
        try:
            cities_data.extend((item['cities']))
        except TypeError:
            pass

geo = (
    Geo(init_opts=opts.InitOpts(theme='dark', width='1000px'))
    .add_schema(maptype="china", zoom=2, center=[114.31, 30.52])
    .add("当前确诊人数",
         [(i['cityName'], i['currentConfirmedCount']) for i in cities_data
          if i['cityName'] in pyecharts.datasets.COORDINATES.keys()],
         type_='heatmap',
         symbol_size=3,
         progressive=50)
    .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
    .set_global_opts(
        title_opts=opts.TitleOpts(title="新型冠状病毒全国疫情热力图",
                                  subtitle="更新时间:{}".format(update_date),
                                  pos_left='right'),
        legend_opts=opts.LegendOpts(is_show=False),
        visualmap_opts=opts.VisualMapOpts(is_show=True,
                                          is_piecewise=False,
                                          range_color=['blue', 'green', 'yellow', 'yellow', 'red'])
    )
)

geo.render_notebook()

Out[10]:

 

时间序列数据

数据处理

因为各地疫情数据更新时间不一致且存在缺失情况,需先对数据进行处理。

In [11]:

def get_value(dic, key):
    try:
        return dic[key]
    except KeyError:
        return 0


def insert_data(to_update_date, to_update_area, dic, is_city):
    if to_update_date in format_data:
        if to_update_area in format_data[to_update_date]:
            pass
        else:
            format_data[to_update_date][to_update_area] = {}
    else:
        format_data[to_update_date] = {}
        format_data[to_update_date][to_update_area] = {}
    format_data[to_update_date][to_update_area]['currentConfirmedCount'] = get_value(
        dic, 'currentConfirmedCount')
    format_data[to_update_date][to_update_area]['confirmedCount'] = get_value(
        dic, 'confirmedCount')
    format_data[to_update_date][to_update_area]['deadCount'] = get_value(
        dic, 'deadCount')
    format_data[to_update_date][to_update_area]['suspectedCount'] = get_value(
        dic, 'suspectedCount')
    format_data[to_update_date][to_update_area]['curedCount'] = get_value(
        dic, 'curedCount')
    format_data[to_update_date][to_update_area]['countryName'] = get_value(
        dic, 'countryName')
    format_data[to_update_date][to_update_area]['countryEnglishName'] = get_value(
        dic, 'countryEnglishName')
    # 用于区分区域层级
    if is_city:
        format_data[to_update_date][to_update_area]['is_city'] = 1
    else:
        format_data[to_update_date][to_update_area]['is_city'] = 0


format_data = {}
for item in area_data_timeline[::-1]:
    to_update_date = date.fromtimestamp(item['updateTime']/1000)
    to_update_area = item['provinceShortName']
    insert_data(to_update_date, to_update_area, item, 0)
    if 'cities' in item:
        if item['cities']:
            for city_data in item['cities']:
                insert_data(
                    to_update_date,
                    city_data['cityName'],
                    city_data,
                    1)

for item in all_data_timeline[::-1]:
    to_update_date = date.fromtimestamp(item['updateTime']/1000)
    insert_data(to_update_date, '全国', item, 0)

time_range = list(format_data.keys())

In [12]:

def area_data(area_name='湖北', type_='confirmedCount',
              get_total=True, date_list=time_range):
    # 用于pyecharts获取时间序列数据
    data_array = []
    for day in date_list:
        try:
            data_array.append(format_data[day][area_name][type_])
        except KeyError:
            if day + datetime.timedelta(days=-1) in format_data:
                if area_name in format_data[day + datetime.timedelta(days=-1)]:
                    # 当天未更新数据情况时,取前一天数据填充
                    data_array.append(
                        format_data[day + datetime.timedelta(days=-1)][area_name][type_])
                else:
                    data_array.append(0)
            else:
                data_array.append(0)
    # 返回每日新增数据
    if not get_total:
        data_array = [data_array[i+1] - data_array[i]
                      for i in range(len(data_array)-1)]
    return data_array

全国/湖北/武汉疫情趋势折线图

In [13]:

data_type = {'当前确诊': 'currentConfirmedCount',
             '累计确诊': 'confirmedCount',
             '死亡病例': 'deadCount',
             '治愈病例': 'curedCount'}

tab = Tab()

for key_, value_ in data_type.items():
    line = (Line(init_opts=opts.InitOpts(theme='dark', width='1000px'))
            .add_xaxis([day.strftime('%Y-%m-%d') for day in time_range])
            .add_yaxis("全国", area_data('全国', value_), is_smooth=True,
                       areastyle_opts=opts.AreaStyleOpts(opacity=0.5,
                                                         color=JsCode("""new echarts.graphic.LinearGradient(0, 0, 0, 1,
                                                                        [{
                                                                            offset: 0,
                                                                            color: 'rgb(255,99,71)'
                                                                        }, {
                                                                            offset: 1,
                                                                            color: 'rgb(32,178,170)'
                                                                        }])""")))
            .add_yaxis("湖北", area_data('湖北', value_), is_smooth=True,
                       areastyle_opts=opts.AreaStyleOpts(opacity=0))
            .add_yaxis("武汉", area_data('武汉', value_), is_smooth=True,
                       areastyle_opts=opts.AreaStyleOpts(opacity=0))
            .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
            .set_global_opts(
                title_opts=opts.TitleOpts(title="全国{}趋势图".format(key_),
                                          subtitle="更新时间:{}".format(update_date)),
                datazoom_opts=opts.DataZoomOpts(range_start=70, range_end=100),
                xaxis_opts=opts.AxisOpts(
                    splitline_opts=opts.SplitLineOpts(
                        is_show=False)),
    ))
    tab.add(line, key_)

tab.render_notebook()

Out[13]:

当前确诊累计确诊死亡病例治愈病例

全国疫情新增趋势

In [14]:

line = (Line(init_opts=opts.InitOpts(theme='dark', width='1000px'))
        .add_xaxis([day.strftime('%Y-%m-%d') for day in time_range][1:])
        .add_yaxis("全国", area_data('全国', get_total=False), is_smooth=True,
                   areastyle_opts=opts.AreaStyleOpts(opacity=0.5,
                                                     color=JsCode("""new echarts.graphic.LinearGradient(0, 0, 0, 1,
                                                                    [{
                                                                        offset: 0,
                                                                        color: 'rgb(255,99,71)'
                                                                    }, {
                                                                        offset: 1,
                                                                        color: 'rgb(32,178,170)'
                                                                    }])""")),)
        .set_series_opts(label_opts=opts.LabelOpts(is_show=True))
        .set_global_opts(
            datazoom_opts=opts.DataZoomOpts(range_start=70, range_end=100),
            title_opts=opts.TitleOpts(title="全国每日新增确证病例趋势图",
                                      subtitle="更新时间:{}".format(update_date)),
            xaxis_opts=opts.AxisOpts(
                splitline_opts=opts.SplitLineOpts(is_show=False)),
            legend_opts=opts.LegendOpts(is_show=False),
))

line.render_notebook()

Out[14]:

 

全国疑似病例趋势

In [15]:

line = (Line(init_opts=opts.InitOpts(theme='dark', width='1000px'))
        .add_xaxis([day.strftime('%Y-%m-%d') for day in time_range][1:])
        .add_yaxis("全国", area_data('全国', 'suspectedCount', get_total=True), is_smooth=True,
                   areastyle_opts=opts.AreaStyleOpts(opacity=0.5,
                                                     color=JsCode("""new echarts.graphic.LinearGradient(0, 0, 0, 1,
                                                                    [{
                                                                        offset: 0,
                                                                        color: 'rgb(255,99,71)'
                                                                    }, {
                                                                        offset: 1,
                                                                        color: 'rgb(32,178,170)'
                                                                    }])""")),)
        .set_series_opts(label_opts=opts.LabelOpts(is_show=True))
        .set_global_opts(
            datazoom_opts=opts.DataZoomOpts(range_start=70, range_end=100),
            title_opts=opts.TitleOpts(title="全国疑似病例趋势图",
                                      subtitle="更新时间:{}".format(update_date)),
            legend_opts=opts.LegendOpts(is_show=False),
            xaxis_opts=opts.AxisOpts(
                splitline_opts=opts.SplitLineOpts(is_show=False)),
))

line.render_notebook()

Out[15]:

 

全国疫情蔓延趋势

In [16]:

tl = Timeline(init_opts=opts.InitOpts(theme='dark', width='1000px'))
tl.add_schema(axis_type='time', is_auto_play=True, is_timeline_show=False)

for day in time_range:
    geo = (
        Geo(init_opts=opts.InitOpts(theme='dark'))
        .add_schema(maptype="china", zoom=1)
        .add("当前确诊人数",
             [(key_, value_['currentConfirmedCount']) for key_, value_, in format_data[day].items()
              if key_ in pyecharts.datasets.COORDINATES.keys() and value_['is_city'] == 1],
             type_='heatmap',
             symbol_size=3,
             progressive=50)
        .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
        .set_global_opts(
            title_opts=opts.TitleOpts(title="新型冠状病毒全国疫情热力图【自动轮播】",
                                      subtitle="更新时间:{}".format(update_date)),
            legend_opts=opts.LegendOpts(is_show=False),
            visualmap_opts=opts.VisualMapOpts(max_=50000, is_show=False,
                                              is_piecewise=True,
                                              pieces=[{"min": 50000},
                                                      {"min": 5000,
                                                       "max": 50000},
                                                      {"min": 500, "max": 5000},
                                                      {"min": 10, "max": 500},
                                                      {"max": 10}],
                                              range_color=['blue', 'green', 'green', 'yellow', 'red']),
            graphic_opts=[opts.GraphicGroup(
                graphic_item=opts.GraphicItem(
                    rotation=JsCode(
                        "Math.PI / 4"),
                    bounding="raw",
                    right=110,
                    bottom=110,
                    z=100,
                ),
                children=[
                    opts.GraphicRect(
                        graphic_item=opts.GraphicItem(
                            left="center", top="center", z=100
                        ),
                        graphic_shape_opts=opts.GraphicShapeOpts(
                            width=400, height=50
                        ),
                        graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
                            fill="rgba(0,0,0,0.3)"
                        ),
                    ),
                    opts.GraphicText(
                        graphic_item=opts.GraphicItem(
                            left="center", top="center", z=100
                        ),
                        graphic_textstyle_opts=opts.GraphicTextStyleOpts(
                            text=day,
                            font="bold 26px Microsoft YaHei",
                            graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
                                fill="#fff"
                            ),
                        ),
                    ),
                ],
            )
            ],
        )
    )

    tl.add(geo, day)

tl.render_notebook()

Out[16]:

 

海外疫情

新型冠状病毒海外主要国家确诊情况

  • 在国内疫情得到有效控制的时候,海外地区却开始呈现爆发趋势。

In [17]:

def oversea_top(day=date.today(), top=10, chinese=True,
                d_type='confirmedCount', china_involved=False):
    if china_involved:
        oversea_data = filter(
            lambda x: x[0] != '全国' and x[1]['is_city'] == 0,
            format_data[day].items())
    else:
        oversea_data = filter(lambda x: x[0] != '全国' and x[1]['is_city'] == 0 and x[1]['countryName'] != '中国',
                              format_data[day].items())
    if top == 'all':
        oversea_data = sorted(
            oversea_data,
            key=lambda x: x[1][d_type],
            reverse=True)
    else:
        oversea_data = sorted(
            oversea_data,
            key=lambda x: x[1][d_type],
            reverse=True)[
            :top]
    if chinese:
        oversea_data = [(x[0], x[1][d_type]) for x in oversea_data]
    else:
        oversea_data = [(x[1]['countryEnglishName'], x[1][d_type]) for x in oversea_data]
    return oversea_data

In [18]:

tl = Timeline(
    init_opts=opts.InitOpts(
        theme='dark',
        width='1000px',
        height='1000px'))
tl.add_schema(axis_type='time', is_timeline_show=True, is_rewind_play=True, is_inverse=True,
              label_opts=opts.LabelOpts(is_show=False))

for day in time_range[::-3]:
    oversea_data = oversea_top(day, top=20)[::-1]
    if oversea_data:
        bar = (
            Bar(init_opts=opts.InitOpts(theme='dark'))
            .add_xaxis([x[0] for x in oversea_data])
            .add_yaxis("", [x[1] for x in oversea_data])
            .set_series_opts(label_opts=opts.LabelOpts(is_show=True,
                                                       position='right',
                                                       font_style='italic'),
                             itemstyle_opts=opts.ItemStyleOpts(
                color=JsCode("""new echarts.graphic.LinearGradient(1, 0, 0, 0,
                                             [{
                                                 offset: 0,
                                                 color: 'rgb(255,99,71)'
                                             }, {
                                                 offset: 1,
                                                 color: 'rgb(32,178,170)'
                                             }])"""))
            )
            .set_global_opts(
                title_opts=opts.TitleOpts(title="新型冠状病毒海外主要国家确诊情况",
                                          subtitle="更新时间:{}".format(update_date)),
                xaxis_opts=opts.AxisOpts(
                    axislabel_opts=opts.LabelOpts(
                        rotate=45)),
                legend_opts=opts.LegendOpts(is_show=True),
                graphic_opts=[opts.GraphicGroup(graphic_item=opts.GraphicItem(
                    rotation=JsCode("Math.PI / 4"),
                    bounding="raw",
                    right=110,
                    bottom=110,
                    z=100),
                    children=[
                    opts.GraphicRect(
                        graphic_item=opts.GraphicItem(
                            left="center", top="center", z=100
                        ),
                        graphic_shape_opts=opts.GraphicShapeOpts(
                            width=400, height=50
                        ),
                        graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
                            fill="rgba(0,0,0,0.3)"
                        ),
                    ),
                    opts.GraphicText(
                        graphic_item=opts.GraphicItem(
                            left="center", top="center", z=100
                        ),
                        graphic_textstyle_opts=opts.GraphicTextStyleOpts(
                            text=day,
                            font="bold 26px Microsoft YaHei",
                            graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
                                fill="#fff"
                            ),
                        ),
                    ),
                ],
                )
                ],)
            .reversal_axis()
        )
        tl.add(bar, day)

tl.render_notebook()

Out[18]:

 

新型冠状病毒海外主要国家死亡情况

In [19]:

tl = Timeline(
    init_opts=opts.InitOpts(
        theme='dark',
        width='1000px',
        height='1000px'))
tl.add_schema(axis_type='time', is_timeline_show=True, is_rewind_play=True, is_inverse=True,
              label_opts=opts.LabelOpts(is_show=False))

for day in time_range[::-3]:
    oversea_data = oversea_top(day, top=20, d_type='deadCount')[::-1]
    if oversea_data:
        bar = (
            Bar(init_opts=opts.InitOpts(theme='dark'))
            .add_xaxis([x[0] for x in oversea_data])
            .add_yaxis("", [x[1] for x in oversea_data])
            .set_series_opts(label_opts=opts.LabelOpts(is_show=True,
                                                       position='right',
                                                       font_style='italic'),
                             itemstyle_opts=opts.ItemStyleOpts(
                color=JsCode("""new echarts.graphic.LinearGradient(1, 0, 0, 0,
                                             [{
                                                 offset: 0,
                                                 color: 'rgb(255,99,71)'
                                             }, {
                                                 offset: 1,
                                                 color: 'rgb(32,178,170)'
                                             }])"""))
            )
            .set_global_opts(
                title_opts=opts.TitleOpts(title="新型冠状病毒海外主要国家死亡情况",
                                          subtitle="更新时间:{}".format(update_date)),
                xaxis_opts=opts.AxisOpts(
                    axislabel_opts=opts.LabelOpts(
                        rotate=45)),
                legend_opts=opts.LegendOpts(is_show=True),
                graphic_opts=[opts.GraphicGroup(graphic_item=opts.GraphicItem(
                    rotation=JsCode("Math.PI / 4"),
                    bounding="raw",
                    right=110,
                    bottom=110,
                    z=100),
                    children=[
                    opts.GraphicRect(
                        graphic_item=opts.GraphicItem(
                            left="center", top="center", z=100
                        ),
                        graphic_shape_opts=opts.GraphicShapeOpts(
                            width=400, height=50
                        ),
                        graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
                            fill="rgba(0,0,0,0.3)"
                        ),
                    ),
                    opts.GraphicText(
                        graphic_item=opts.GraphicItem(
                            left="center", top="center", z=100
                        ),
                        graphic_textstyle_opts=opts.GraphicTextStyleOpts(
                            text=day,
                            font="bold 26px Microsoft YaHei",
                            graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
                                fill="#fff"
                            ),
                        ),
                    ),
                ],
                )
                ],)
            .reversal_axis()
        )
        tl.add(bar, day)

tl.render_notebook()

Out[19]:

 

海外主要国家确诊/治愈率/死亡率趋势

In [20]:

country_list = [x for x, _ in oversea_top(time_range[-1], top=20)]
date_list = [date.today() + datetime.timedelta(days=-i)
             for i in range(14)][::-1]
tab = Tab()

for country in country_list:
    cofirm = area_data(
        area_name=country,
        type_='confirmedCount',
        date_list=date_list)
    dead = area_data(area_name=country, type_='deadCount', date_list=date_list)
    cured = area_data(
        area_name=country,
        type_='curedCount',
        date_list=date_list)
    dead_rate = [i/j if j != 0 else 0. for i, j in zip(dead, cofirm)]
    cure_rate = [i/j if j != 0 else 0. for i, j in zip(cured, cofirm)]

    line = (Line(init_opts=opts.InitOpts(theme='dark'))
            .add_xaxis(date_list)
            .add_yaxis("死亡率", dead_rate, yaxis_index=1, is_smooth=True, z_level=1)
            .add_yaxis("治愈率", cure_rate, yaxis_index=1, is_smooth=True, z_level=1)
            .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
            )

    bar = (Bar(init_opts=opts.InitOpts(theme='dark', width='1000px'))
           .add_xaxis(date_list)
           .add_yaxis("确诊病例", cofirm, yaxis_index=0)
           .extend_axis(yaxis=opts.AxisOpts(
               name="",
               type_="value",
               min_=0,
               max_=round(max([max(cure_rate), max(dead_rate)])*1.2, 2),
               position="right",
               axislabel_opts=opts.LabelOpts(
                        formatter=JsCode("""function (value)
                                                    {return Number(value *100)+'%';}""")),))
           .set_series_opts(label_opts=opts.LabelOpts(is_show=True,
                                                      position='top',
                                                      font_style='italic'),
                            itemstyle_opts=opts.ItemStyleOpts(opacity=1,
                                                              color=JsCode("""new echarts.graphic.LinearGradient
                                                (0, 0, 0, 1,
                                                 [{
                                                     offset: 0,
                                                     color: 'rgb(255,99,71)'
                                                 }, {
                                                     offset: 1,
                                                     color: 'rgb(32,178,170)'
                                                 }])"""))
                            )
           .set_global_opts(
                    title_opts=opts.TitleOpts(title="【{}】确诊/治愈率/死亡率 趋势".format(country),
                                              subtitle="更新时间:{}".format(update_date)),
                    tooltip_opts=opts.TooltipOpts(formatter=JsCode("""function (params) {
                                                                    if (!isNaN(params.value[1])) {return params.seriesName +':'+ Number(params.value[1] *100).toFixed(3)+'%';}
                                                                    else {return params.seriesName +':' + params.value;}
                                                                    }""")),
                    xaxis_opts=opts.AxisOpts(
                        axislabel_opts=opts.LabelOpts(rotate=45)),
                    legend_opts=opts.LegendOpts(is_show=True)
    )
    )
    bar.overlap(line)

    tab.add(bar, country)

tab.render_notebook()

Out[20]:

美国巴西俄罗斯英国西班牙意大利印度德国秘鲁土耳其伊朗法国智利墨西哥沙特阿拉伯加拿大巴基斯坦卡塔尔孟加拉国比利时

海外疫情蔓延趋势图

In [21]:

tl = Timeline(
    init_opts=opts.InitOpts(
        theme='dark',
        width='1000px',
        height='700px'))
tl.add_schema(axis_type='time', is_timeline_show=True, is_rewind_play=True, is_inverse=True,
              label_opts=opts.LabelOpts(is_show=False))

for day in time_range[::5][::-1]:
    
    t_data = oversea_top(day, top='all', chinese=False,
                         d_type='confirmedCount', china_involved=True)
    t_data = [[c.replace('United States of America', 'United States'), n] for c, n in t_data if c]
    
    
    _map = (
        Map(init_opts=opts.InitOpts(theme='dark', width='1000px'))
        .add("累计确诊人数", t_data, "world", is_map_symbol_show=False,  is_roam=False)
        .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
        .set_global_opts(
            title_opts=opts.TitleOpts(title="新型冠状病毒全球疫情蔓延地图",
                                      subtitle="更新时间:{}".format(update_date)),
            legend_opts=opts.LegendOpts(is_show=False),
            visualmap_opts=opts.VisualMapOpts(is_show=True, max_=10000,
                                              is_piecewise=False,
                                              range_color=['#FFFFE0', '#FFA07A', '#CD5C5C', '#8B0000']),
            graphic_opts=[opts.GraphicGroup(graphic_item=opts.GraphicItem(
                        rotation=JsCode("Math.PI / 4"),
                        bounding="raw",
                        right=110,
                        bottom=110,
                        z=100),
                        children=[
                        opts.GraphicRect(
                            graphic_item=opts.GraphicItem(
                                left="center", top="center", z=100
                            ),
                            graphic_shape_opts=opts.GraphicShapeOpts(
                                width=400, height=50
                            ),
                            graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
                                fill="rgba(0,0,0,0.3)"
                            ),
                        ),
                        opts.GraphicText(
                            graphic_item=opts.GraphicItem(
                                left="center", top="center", z=100
                            ),
                            graphic_textstyle_opts=opts.GraphicTextStyleOpts(
                                text=day,
                                font="bold 26px Microsoft YaHei",
                                graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
                                    fill="#fff"
                                ),
                            ),
                        ),
                    ],
                    )
                    ],
        )
    )
    
    tl.add(_map, day)

tl.render_notebook()
    

Out[21]:

 

美国疫情地图

In [22]:

# 加载美国地图js资源
register_url("https://echarts-maps.github.io/echarts-countries-js/")

data_us = pd.read_csv('/home/kesci/input/uscovid198505/us-states.csv')

In [23]:

us_case, us_death = [], []
for _, row in data_us[data_us.date == data_us.date.max()].iterrows():
    us_case.append([row.state, row.cases])
    us_death.append([row.state, row.deaths])

tab = Tab()
_map = (
    Map(init_opts=opts.InitOpts(theme='dark', width='1000px'))
    .add("确诊人数", us_case, "美国", is_map_symbol_show=False,  is_roam=False)
    .set_series_opts(label_opts=opts.LabelOpts(is_show=True))
    .set_global_opts(
        title_opts=opts.TitleOpts(title="新型冠状病毒美国疫情确诊地图",
                                  subtitle="更新时间:{}".format(update_date)),
        legend_opts=opts.LegendOpts(is_show=False),
        visualmap_opts=opts.VisualMapOpts(is_show=True, max_=50000,
                                          is_piecewise=False,
                                          range_color=['#FFFFE0', '#FFA07A', '#CD5C5C', '#8B0000'])
    )
)

tab.add(_map, '累计确诊')


_map = (
    Map(init_opts=opts.InitOpts(theme='dark', width='1000px'))
    .add("死亡人数", us_death, "美国", is_map_symbol_show=False,  is_roam=False)
    .set_series_opts(label_opts=opts.LabelOpts(is_show=True))
    .set_global_opts(
        title_opts=opts.TitleOpts(title="新型冠状病毒美国疫情死亡地图",
                                  subtitle="更新时间:{}".format(update_date)),
        legend_opts=opts.LegendOpts(is_show=False),
        visualmap_opts=opts.VisualMapOpts(is_show=True, max_=3000,
                                          is_piecewise=False,
                                          range_color=['#FFFFE0', '#FFA07A', '#CD5C5C', '#8B0000'])
    )
)

tab.add(_map, '死亡')

tab.render_notebook()

Out[23]:

累计确诊死亡

  •  

你可能感兴趣的:(【世界加油⛽️】基于Pyecharts的疫情数据可视化~)