Python模組---製作新冠疫情世界地圖()
阿新 • • 發佈:2020-04-28
[TOC]
##pyecharts模組
###簡介
Echarts 是一個由百度開源的資料視覺化,憑藉著良好的互動性,精巧的圖表設計,得到了眾多開發者的認可。而 Python 是一門富有表達力的語言,很適合用於資料處理。當資料分析遇上資料視覺化時,pyecharts 誕生了。
如果想要掌握pyecharts,可以閱讀[pyecharts中文文件](https://pyecharts.org/#/zh-cn/intro),裡面的圖表型別和配置項寫的非常詳細,我就不過多的贅述了
###安裝pyecharts
安裝的命令也非常簡單:
```
pip install pyecharts
```
安裝成功:
![](https://img2020.cnblogs.com/blog/1971945/202004/1971945-20200428193045671-1853913251.png)
###測試pyecharts模組
我們可以嘗試執行官方文件所給出的幾個小例子來測試一下pyecharts模組是否成功安裝
開啟編輯器,輸入並執行以下程式碼:
```
from pyecharts.charts import Bar
from pyecharts import options as opts
# 內建主題型別可檢視 pyecharts.globals.ThemeType
from pyecharts.globals import ThemeType
bar = (
Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))
.add_xaxis(["襯衫", "羊毛衫", "雪紡衫", "褲子", "高跟鞋", "襪子"])
.add_yaxis("商家A", [5, 20, 36, 10, 75, 90])
.add_yaxis("商家B", [15, 6, 45, 20, 35, 66])
.set_global_opts(title_opts=opts.TitleOpts(title="主標題", subtitle="副標題"))
)
bar.render() #儲存為html檔案
```
若此時在當前目錄下生成了一個名為render.html的檔案
![](https://img2020.cnblogs.com/blog/1971945/202004/1971945-20200428201222710-224724027.png)
開啟此檔案,看到如下的圖片則證明安裝模組成功
![](https://img2020.cnblogs.com/blog/1971945/202004/1971945-20200428201234947-1189003310.png)
##pyecharts實戰:繪製新冠肺炎疫情地圖
###需求分析
想要製作全球疫情的地圖(空氣質量圖,人口分佈圖也是同理),首先需要的就是每個國家的疫情資料,比如人數,治癒數,增長數...... 那麼我們該如何獲取到這些資訊呢?
###請求資料
我們發現很多app和網頁上都會有最新的疫情資訊公佈,我選取的資料來源是騰訊地圖。
首先開啟[騰訊地圖的疫情資訊頁](https://news.qq.com/zt2020/page/feiyan.htm#/global),可以發現疫情的資訊展現在這一頁中
![](https://img2020.cnblogs.com/blog/1971945/202004/1971945-20200428122538840-2036862265.png)
獲取這些資訊的方法有很多種,可以是用表示式提取,也可以抓包分析,我更喜歡的一種方法是抓包分析。
右擊《檢查》,點選《network》選項卡並重新整理介面,看到加載出來很多資料包,找到裡面最像列表的一個list資料包
![](https://img2020.cnblogs.com/blog/1971945/202004/1971945-20200428123841422-258150398.png)
此時發現,這個list資料包正式我們要提取的資料列表,裡面的每個鍵值對都代表著相應的資料,提取到這些鍵值對就可以獲取到所有的資料資訊了,再次回到headers,選項卡下面對應的網址就是我們即將請求的網址,這裡我們需要注意的是,這個網址對應的請求是post而不是我們經常使用的get
![](https://img2020.cnblogs.com/blog/1971945/202004/1971945-20200428124442815-384401241.png)
向網頁請求資料:
```
import requests
url = 'https://api.inews.qq.com/newsqa/v1/automation/foreign/country/ranklist'
response = requests.post(url).text
print(response)
```
可以看到這個網頁並沒有設定反爬蟲,可以輕鬆的獲取到資料
![](https://img2020.cnblogs.com/blog/1971945/202004/1971945-20200428124703908-1859571469.png)
###提取資料
我們剛剛請求到的資料格式是字元格式,並不能被我們直接提取到,必須想將字元格式的資料轉換為字典格式才可以開始下一步的提取
```
resp = json.loads(response) #使用變數resp來接收字典格式的資料
```
將變數轉化為字典格式後,就要開始提取資料了 提取json型別的資料可以使用取出列表元素的方法來提取,即先遍歷列表將每個國家的資訊提取出來,再分別從這些條資訊中提取到我們想要的資料
提取資料:
```
import json
resp = json.loads(response) #使用變數resp來接收字典格式的資料
for data in resp['data']: #遍歷提取每個國家的疫情資料
name = data['name'] #國家名
confirm = data['confirm'] #該國家疫情人數
print(name,confirm)
```
列印資料:
![](https://img2020.cnblogs.com/blog/1971945/202004/1971945-20200428132158871-965155416.png)
###處理資料
在得到了國家和人數資訊之後,還需要將資料儲存到字典中才能傳入圖表中,這就需要我們手動的轉換資料,並儲存到字典中
```
map_version = {} #定義空字典
for data in resp['data']: #遍歷提取每個國家的疫情資料
name = data['name'] #國家名
confirm = data['confirm'] #該國家疫情人數
map_version[name] = int(confirm) #將國家和人數以鍵值對的形式傳入字典
```
輸出字典:
![](https://img2020.cnblogs.com/blog/1971945/202004/1971945-20200428140324895-1654645914.png)
此時打印出來的字典是標準的字典格式,但是這種格式並不是pyecharts所要求的格式,所以還需要一行程式碼來進行轉換
```
element = list(map_version.items())
```
然後就可以輸出傳入資料的標準格式:
![](https://img2020.cnblogs.com/blog/1971945/202004/1971945-20200428170401241-595200422.png)
###製作視覺化地圖
在將資料爬取、變換、整理後,所有準備工作都已經做完,下面我們來呼叫資料實現資料視覺化
先寫出一個初步的框架來接收內容
```
from pyecharts.charts import Map,Geo
map = Map().add(series_name="世界疫情分佈圖", #名稱
data_pair=element, #傳入資料
maptype='world', #地圖型別
)
map.render('map.html') #命名並儲存
```
執行程式碼,發現當前資料夾下出現了一個map.html檔案,雙擊執行
![](https://img2020.cnblogs.com/blog/1971945/202004/1971945-20200428173457314-1138208178.png)
看到這個圖表之後,發現程式碼的執行並沒有問題,但是資料卻沒有傳到地圖中,這是由於pyecharts預設的世界地圖中的國家名是英文,所以我們就要傳入一個字典來替代掉這些英文
###設定視覺化地圖
生成了地圖之後,接下來就是要保證地圖的正確性和美觀,所以我們要來設定世界地圖
地圖上顯示國家名太多,影響可讀性,所以設定為不顯示國家名
```
from pyecharts import options
map.set_series_opts(label_opts=options.LabelOpts(is_show=False)) #不顯示國家名
```
按照感染人數的不同,給地圖新增不同的顏色
```
#設定全域性配置項
map.set_global_opts(visualmap_opts=options.VisualMapOpts(max_=1100000,is_piecewise=True,pieces=[
{"min": 500000},
{"min": 200000, "max": 499999},
{"min": 100000, "max": 199999},
{"min": 50000, "max": 99999},
{"min": 10000, "max": 49999},
{"max": 9999},]))
```
代表國家首都的圓點不美觀,去掉紅點:
```
map = Map().add(
is_map_symbol_show=False, #不顯示標記
)
```
設定背景顏色併為網頁取名:
```
map = Map(options.InitOpts(bg_color="#87CEFA",page_title='世界疫情分佈')).add()
```
到了現在所有的配置已經完成,但是圖表要想顯示資料還需要傳入一個字典來替換掉預設的英文名,具體實現請看下面的完整程式碼。
##完整程式碼
```
import requests
import json
from pyecharts.charts import Map
from pyecharts import options
url = 'https://api.inews.qq.com/newsqa/v1/automation/foreign/country/ranklist'
response = requests.post(url).text
resp = json.loads(response) #使用變數resp來接收字典格式的資料
map_version = {} #定義空字典
for data in resp['data']: #遍歷提取每個國家的疫情資料
name = data['name'] #國家名
confirm = data['confirm'] #該國家疫情人數
map_version[name] = int(confirm) #將國家和人數以鍵值對的形式傳入字典
element = list(map_version.items()) #將字典值調整為可以傳入地圖的格式
name_map = {
'Singapore Rep.': '新加坡',
'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': '辛巴威',
'Comoros': '葛摩'
}
map = Map(options.InitOpts(bg_color="#87CEFA",page_title='世界疫情分佈')).\
add(series_name="世界疫情分佈圖", #名稱
data_pair=element, #傳入資料
is_map_symbol_show=False, #不顯示標記
maptype='world', #地圖型別
name_map=name_map,
)
#設定全域性配置項
map.set_global_opts(visualmap_opts=options.VisualMapOpts(max_=1100000,is_piecewise=True,pieces=[
{"min": 500000},
{"min": 200000, "max": 499999},
{"min": 100000, "max": 199999},
{"min": 50000, "max": 99999},
{"min": 10000, "max": 49999},
{"max": 9999},]))
#設定系列配置項
map.set_series_opts(label_opts=options.LabelOpts(is_show=False)) #不顯示國家名
map.render('map.html') #命名並儲存
```
##實現結果
這個結果可以動態的顯示在網頁中,可以根據人數來篩選地圖的板塊,而且方便縮放
![](https://img2020.cnblogs.com/blog/1971945/202004/1971945-20200428200028487-1746263