1. 程式人生 > >python畫新冠肺炎國內和世界各國累計確診數量熱圖

python畫新冠肺炎國內和世界各國累計確診數量熱圖

新冠肺炎國內疫情基本控制住,很多地方都開始摘下口罩了。但是國外的疫情依然處於爆發期,特別是美國,截止目前其累計確診數量已突破110w。五一節北京柳絮楊絮滿天飛,不適合外出。在家心血來潮,獻醜畫一下各地區新冠肺炎累計確診數量熱圖。

廢話不多說,程式碼如下:

一、中國

1、獲取資料:

import requests as rq
import re
import numpy as np
import pandas as pd

# 資料來源:新華網
# http://my-h5news.app.xinhuanet.com/h5activity/yiqingchaxun/index.html
url = 'http://fms.news.cn/swf/2020_sjxw/2_1_xgyq/js/data.js'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36'
}

# 網頁資料
home_rt = rq.get(url, headers=headers).text

# 提取日期
dates = re.search('_g_map_data_days = \[(.*?)\]', home_rt).group(1)
dates = re.findall('\'(.*?)\'', dates)
# # 日更日期
# dates = re.search('_g_dt_date = \[(.*?)\]', home_rt).group(1)
# dates = re.findall('\'(.*?)\'', dates)

# 提取省份
provinces = re.search('_g_map_data_province = \[(.*?)\];', home_rt).group(1)
provinces = re.findall('\'(.*?)\'', provinces)

# 提取資料
data = re.search('_g_map_data_data =\[(.*?)\];', home_rt, re.S).group(1)
data = re.findall('\[(.*?)\]', data, re.S)
data = [i.split(',') for i in data]
data = np.array(data).T

# 生成表格
data = pd.DataFrame(data, columns=dates, index=provinces)
data = data.astype('int')  # 轉換str型別為int型
last_colum = data.columns[-1]
data = data.sort_values(last_colum, ascending=False)

得到如下dataframe格式資料:

2、畫圖

本次畫圖採用的是pyecharts:

pyecharts是基於echarts,是百度的開源視覺化工具,包含多種酷炫工具,並且是互動式的,影象可以用滑鼠進行拖動放大縮小等,強烈推薦。

1、github原始碼(包含安裝方式,最好選擇原始碼安裝)。2、介紹文件。3、官方示例程式碼

from pyecharts import options as opts
from pyecharts.charts import Map
from pyecharts.faker import Faker

province_data = []  # 生成pyecharts資料格式
for p_i, pro_name in enumerate(data.index):
    province_data.append([pro_name, int(data.iloc[p_i, -1])])

c = (
    Map(opts.InitOpts(width='600px', height='400px', bg_color='white'))  # 建立地圖物件
    .add('累計確診', province_data, "china", is_map_symbol_show=False)  # 新增資料,選擇中國地圖
#     .set_series_opts(label_opts=opts.LabelOpts(is_show=False))  # 用於顯示各省份名字
    .set_global_opts(title_opts=opts.TitleOpts(title="中國各省新冠肺炎累計確診數量", pos_left='center'),  # 設定標題圖例等資訊
                     legend_opts=opts.LegendOpts(is_show=False),
                     visualmap_opts=opts.VisualMapOpts(is_piecewise = True,
                                                       pieces = [{"max": 100, 'color': '#ffeead', 'label': '小於100人'},
                                                                 {"min": 100, "max": 500, 'color': '#f29c2b', 'label': '100-500人'},
                                                                 {"min": 500, "max": 1000, 'color': '#d9534f', 'label': '500-1000人'},
                                                                 {"min": 1000, "max": 2000, "color": '#de4307', 'label': '1000-2000人'},
                                                                 {"min": 2000, 'color': '#dd0a35', 'label': '2000人以上'}])
                     )
)
c.render_notebook() 

輸出影象如下:

 二、世界地圖

1、世界各國中英文對映關係(點選展開)

nameMap = {
        'Singapore':'新加坡',
        'Dominican Rep.':'多明尼加',
        'Palestine':'巴勒斯坦',
        'Bahamas':'巴哈馬',
        'Timor-Leste':'東帝汶',
        'Afghanistan':'阿富汗',
        'Guinea-Bissau':'幾內亞比索',
        "Côte d'Ivoire":'象牙海岸',
        'Siachen Glacier':'錫亞琴冰川',
        "Br. Indian Ocean Ter.":'英屬印度洋領土',
        'Angola':'安哥拉',
        'Albania':'阿爾巴尼亞',
        'United Arab Emirates':'阿聯酋',
        'Argentina':'阿根廷',
        'Armenia':'亞美尼亞',
        'French Southern and Antarctic Lands':'法屬南半球和南極領地',
        'Australia':'澳大利亞',
        'Austria':'奧地利',
        'Azerbaijan':'亞塞拜然',
        'Burundi':'蒲隆地',
        'Belgium':'比利時',
        'Benin':'貝南',
        'Burkina Faso':'布吉納法索',
        'Bangladesh':'孟加拉國',
        'Bulgaria':'保加利亞',
        'The Bahamas':'巴哈馬',
        'Bosnia and Herz.':'波斯尼亞和黑塞哥維那',
        'Belarus':'白俄羅斯',
        'Belize':'貝里斯',
        'Bermuda':'百慕大',
        'Bolivia':'玻利維亞',
        'Brazil':'巴西',
        'Brunei':'汶萊',
        'Bhutan':'不丹',
        'Botswana':'波札那',
        'Central African Rep.':'中非',
        'Canada':'加拿大',
        'Switzerland':'瑞士',
        'Chile':'智利',
        'China':'中國',
        'Ivory Coast':'象牙海岸',
        'Cameroon':'喀麥隆',
        'Dem. Rep. Congo':'剛果民主共和國',
        'Congo':'剛果',
        'Colombia':'哥倫比亞',
        'Costa Rica':'哥斯大黎加',
        'Cuba':'古巴',
        'N. Cyprus':'北塞普勒斯',
        'Cyprus':'塞普勒斯',
        'Czech Rep.':'捷克',
        'Germany':'德國',
        'Djibouti':'吉布提',
        'Denmark':'丹麥',
        'Algeria':'阿爾及利亞',
        'Ecuador':'厄瓜多',
        'Egypt':'埃及',
        'Eritrea':'厄利垂亞',
        'Spain':'西班牙',
        'Estonia':'愛沙尼亞',
        'Ethiopia':'衣索比亞',
        'Finland':'芬蘭',
        'Fiji':'斐',
        'Falkland Islands':'福克蘭群島',
        'France':'法國',
        'Gabon':'加彭',
        'United Kingdom':'英國',
        'Georgia':'喬治亞',
        'Ghana':'迦納',
        'Guinea':'幾內亞',
        'Gambia':'甘比亞',
        'Guinea Bissau':'幾內亞比索',
        'Eq. Guinea':'赤道幾內亞',
        'Greece':'希臘',
        'Greenland':'格陵蘭',
        'Guatemala':'瓜地馬拉',
        'French Guiana':'法屬蓋亞那',
        'Guyana':'蓋亞那',
        'Honduras':'宏都拉斯',
        'Croatia':'克羅埃西亞',
        'Haiti':'海地',
        'Hungary':'匈牙利',
        'Indonesia':'印度尼西亞',
        'India':'印度',
        'Ireland':'愛爾蘭',
        'Iran':'伊朗',
        'Iraq':'伊拉克',
        'Iceland':'冰島',
        'Israel':'以色列',
        'Italy':'義大利',
        'Jamaica':'牙買加',
        'Jordan':'約旦',
        'Japan':'日本',
        'Kazakhstan':'哈薩克',
        'Kenya':'肯亞',
        'Kyrgyzstan':'吉爾吉斯斯坦',
        'Cambodia':'柬埔寨',
        'Korea':'韓國',
        'Kosovo':'科索沃',
        'Kuwait':'科威特',
        'Lao PDR':'寮國',
        'Lebanon':'黎巴嫩',
        'Liberia':'賴比瑞亞',
        'Libya':'利比亞',
        'Sri Lanka':'斯里蘭卡',
        'Lesotho':'賴索托',
        'Lithuania':'立陶宛',
        'Luxembourg':'盧森堡',
        'Latvia':'拉脫維亞',
        'Morocco':'摩洛哥',
        'Moldova':'摩爾多瓦',
        'Madagascar':'馬達加斯加',
        'Mexico':'墨西哥',
        'Macedonia':'馬其頓',
        'Mali':'馬裡',
        'Myanmar':'緬甸',
        'Montenegro':'黑山',
        'Mongolia':'蒙古',
        'Mozambique':'莫三比克',
        'Mauritania':'茅利塔尼亞',
        'Malawi':'馬拉維',
        'Malaysia':'馬來西亞',
        'Namibia':'奈米比亞',
        'New Caledonia':'新喀里多尼亞',
        'Niger':'尼日',
        'Nigeria':'奈及利亞',
        'Nicaragua':'尼加拉瓜',
        'Netherlands':'荷蘭',
        'Norway':'挪威',
        'Nepal':'尼泊爾',
        'New Zealand':'紐西蘭',
        'Oman':'阿曼',
        'Pakistan':'巴基斯坦',
        'Panama':'巴拿馬',
        'Peru':'祕魯',
        'Philippines':'菲律賓',
        'Papua New Guinea':'巴布亞紐幾內亞',
        'Poland':'波蘭',
        'Puerto Rico':'波多黎各',
        'Dem. Rep. Korea':'朝鮮',
        'Portugal':'葡萄牙',
        'Paraguay':'巴拉圭',
        'Qatar':'卡達',
        'Romania':'羅馬尼亞',
        'Russia':'俄羅斯',
        'Rwanda':'盧安達',
        'W. Sahara':'西撒哈拉',
        'Saudi Arabia':'沙烏地阿拉伯',
        'Sudan':'蘇丹',
        'S. Sudan':'南蘇丹',
        'Senegal':'塞內加爾',
        'Solomon Is.':'索羅門群島',
        'Sierra Leone':'獅子山',
        'El Salvador':'薩爾瓦多',
        'Somaliland':'索馬利亞蘭',
        'Somalia':'索馬利亞',
        'Serbia':'塞爾維亞',
        'Suriname':'蘇利南',
        'Slovakia':'斯洛伐克',
        'Slovenia':'斯洛維尼亞',
        'Sweden':'瑞典',
        'Swaziland':'史瓦濟蘭',
        'Syria':'敘利亞',
        'Chad':'查德',
        'Togo':'多哥',
        'Thailand':'泰國',
        'Tajikistan':'塔吉克',
        'Turkmenistan':'土庫曼',
        'East Timor':'東帝汶',
        'Trinidad and Tobago':'特里尼達和多巴哥',
        'Tunisia':'突尼西亞',
        'Turkey':'土耳其',
        'Tanzania':'坦尚尼亞',
        'Uganda':'烏干達',
        'Ukraine':'烏克蘭',
        'Uruguay':'烏拉圭',
        'United States':'美國',
        'Uzbekistan':'烏茲別克',
        'Venezuela':'委內瑞拉',
        'Vietnam':'越南',
        'Vanuatu':'萬那杜',
        'West Bank':'西岸',
        'Yemen':'葉門',
        'South Africa':'南非',
        'Zambia':'尚比亞',
        'Zimbabwe':'辛巴威'
    }
View Code

2、處理資料(新華網資料)

foreigh_rt = re.search('國外表格(.*)', home_rt, re.S).group(1)
foreigh_data = re.findall('cityName"\>(.*?)\</p\>.*?cityQZ"\>(.*?)\</p\>.*?cityXZQZ"\>(.*?)\</p\>.*?citySWSJ"\>(.*?)\</p\>', foreigh_rt, re.S)
foreigh_data = pd.DataFrame(foreigh_data)
foreigh_data.columns = ['國家', '累計確診', '新增', '累計死亡']
foreigh_data[foreigh_data=='-'] = 0

country_name = pd.DataFrame([nameMap.values(), nameMap.keys()]).T
country_name.columns = ['國家', 'name']
foreigh_data = pd.merge(foreigh_data, country_name, on='國家', how='outer')  # 替換中文名字為英文
foreigh_data = foreigh_data.fillna(0)

indexes = list(foreigh_data.iloc[:, -1])
foreigh_data = foreigh_data.drop(['國家', 'name'], axis=1)
foreigh_data.index = indexes

country_data = []
for cou_i, coun_index in enumerate(foreigh_data.index):
    country_data.append([coun_index, int(foreigh_data.iloc[cou_i, 0])])
country_data.append(['China', int(data.iloc[:, -1].sum())])  # 新增中國資料

3、畫圖

c = (
    Map(opts.InitOpts(width='800px', height='400px', bg_color='white'))
    .add("累計確診", country_data, "world", is_map_symbol_show=False)
    .set_series_opts(label_opts=opts.LabelOpts(is_show=False))  # 不顯示國家名字
    .set_global_opts(
        title_opts=opts.TitleOpts(title="世界新冠肺炎累計確診熱圖", pos_left='center'),
        legend_opts=opts.LegendOpts(is_show=False),
        visualmap_opts=opts.VisualMapOpts(is_piecewise = True,
                                           pieces = [{"max": 1000, 'color': '#ffeead', 'label': '1k人以下'},
                                                     {"min": 1000, "max": 50000, 'color': '#f29c2b', 'label': '1k~5w人'},
                                                     {"min": 50000, "max": 200000, 'color': '#d9534f', 'label': '5w-20w人'},
                                                     {"min": 200000, "max": 1000000, "color": '#F71E35', 'label': '20w-100w人'},
                                                     {"min": 1000000, 'color': '#C00000', 'label': '100w以上'}])

    )
)

c.render_notebook()  

輸出影象如下:

&n