1. 程式人生 > >Python模組---製作新冠疫情世界地圖()

Python模組---製作新冠疫情世界地圖()

[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