Python繪制全球疫情變化地圖的實(shí)例代碼
目前全球疫情仍然比較嚴(yán)重,為了能清晰地看到疫情爆發(fā)以來(lái)至現(xiàn)在全球疫情的變化趨勢(shì),我繪制了一張疫情變化地圖。 廢話(huà)不多說(shuō),先上圖
下面就來(lái)重點(diǎn)介紹下上面這張圖的繪制過(guò)程,主要分為以下三個(gè)步驟:
- 數(shù)據(jù)收集
- 數(shù)據(jù)處理
- 畫(huà)圖
下面一個(gè)一個(gè)來(lái)說(shuō)。
數(shù)據(jù)收集
這是萬(wàn)里長(zhǎng)城的第一步,俗話(huà)說(shuō)“巧婦難為無(wú)米之炊”,既然是變化圖,當(dāng)然需要每個(gè)國(guó)家、每天的現(xiàn)有確診病例數(shù)。好在現(xiàn)在各大網(wǎng)站都有疫情相關(guān)的專(zhuān)題頁(yè),我們可以直接抓數(shù)據(jù)。以網(wǎng)易為例
我們選擇 XHR,重新刷新下網(wǎng)頁(yè)可以看到有幾個(gè)接口,其中 list-total 接口是獲取當(dāng)前所有有疫情的國(guó)家,以及對(duì)應(yīng)的國(guó)家id。另外,我們看到還有一個(gè) list-by-area-code 接口,它是獲取每個(gè)國(guó)家歷史上每天的疫情數(shù)據(jù),請(qǐng)求這個(gè)接口需要帶 areaCode 參數(shù),這個(gè)參數(shù)就是我們剛剛說(shuō)的國(guó)家id。所以對(duì)我們來(lái)說(shuō)這兩個(gè)接口是最重要的。下面我們就看看請(qǐng)求 list-total 接口的代碼
def get_and_save_all_countries(): """ 獲取所有的國(guó)家名以及對(duì)應(yīng)的id,保存為文件 """ url = 'https://c.m.163.com/ug/api/wuhan/app/data/list-total?t=317452696323' list_total_req = requests.get(url, headers=headers) if list_total_req.status_code == 200: area_tree = list_total_req.json()['data']['areaTree'] area_dict = {} for area in area_tree: country_id = area['id'] name = area['name'] area_dict[country_id] = name area_json = json.dumps(area_dict, ensure_ascii=False) # ensure_ascii=False 防止json編碼后中文編程\u開(kāi)頭的字符 write_file('./config/countries_id2name.json', area_json)
這里將請(qǐng)求下來(lái)的數(shù)據(jù)臨時(shí)存放在文件里。有了所有的疫情國(guó)家的id,我們就可以請(qǐng)求 list-by-area-code 接口來(lái)獲取每個(gè)國(guó)家的疫情數(shù)據(jù)了。代碼與上面的類(lèi)似,不同的是將請(qǐng)求結(jié)果存在了 mongodb 而不是文件,目的是為了方便增刪改查。當(dāng)然為了大家方便使用,我將mongodb中的數(shù)據(jù)導(dǎo)入了文件 counties_daily.json 中,大家可以在源碼根目錄找到它。
數(shù)據(jù)處理
這一步的處理主要是為第三步畫(huà)圖做準(zhǔn)備的。因?yàn)槲覀儺?huà)圖用的是pyecharts框架,它繪制世界地圖需要輸入的國(guó)家名是英文的,而我們收集的國(guó)家名是中文的,所以要將中文國(guó)家名對(duì)應(yīng)到英文國(guó)家名。最終的效果如下
網(wǎng)上能找到這樣的對(duì)應(yīng)關(guān)系,但想要用起來(lái)還需要解決兩個(gè)問(wèn)題。第一,兩邊中文名統(tǒng)一,比如:我們收集的國(guó)家名是中非共和國(guó),而對(duì)應(yīng)關(guān)系里是中非,那還是對(duì)應(yīng)不上。第二,需要自己增加映射關(guān)系,網(wǎng)上找的一般都不全,我們需要根據(jù)收集的數(shù)據(jù)自行增加。經(jīng)過(guò)上面兩個(gè)步驟處理后,我們就可以將大部分國(guó)家名對(duì)應(yīng)到pyechars能識(shí)別的英文名了。相關(guān)代碼如下
def get_cy_properties(): # 獲取配置文件信息 countries_id2name = read_file('./config/countries_id2name.json') cy_id2name_dict = json.loads(countries_id2name) cy_ch2en = {v: k for k, v in countries_dict.items()} # 調(diào)整國(guó)家的名字與配置文件一致 cy_id2name_dict['879'] = '波斯尼亞和黑塞哥維那' cy_id2name_dict['8102'] = '多哥' cy_id2name_dict['8143'] = '剛果民主共和國(guó)' cy_id2name_dict['95983'] = '剛果' cy_id2name_dict['8144'] = '中非' cy_id2name_dict['95000011'] = '多米尼加' cy_props = {} for key in cy_id2name_dict: cy_name = cy_id2name_dict[key] if cy_name in cy_ch2en: cy_props[cy_name] = {} cy_props[cy_name]['id'] = key cy_props[cy_name]['en_name'] = cy_ch2en[cy_name] return cy_props
畫(huà)圖
這一步涉及到兩個(gè)核心過(guò)程——構(gòu)造數(shù)據(jù)結(jié)構(gòu)和畫(huà)圖。首先,我構(gòu)造了3個(gè)數(shù)據(jù)結(jié)構(gòu),分別是date_list、cy_name_list 和 ncov_data。date_list存放的是日期列表,因?yàn)槲覀儺?huà)動(dòng)圖,所以需要一段時(shí)間;cy_name_list 存放收集的所有國(guó)家列表(英文名);ncov_data是一個(gè)字典,key是日期,value是數(shù)組,存放各個(gè)國(guó)家當(dāng)天的確診病例數(shù)。生成這三個(gè)數(shù)據(jù)結(jié)構(gòu)的代碼如下
def parse_ncov_data(start_date, end_date, records): if not records: return date_list = get_date_range(start_date, end_date) cy_name_list = [] res = {} # 獲取各國(guó)每天現(xiàn)有確認(rèn)病例 for i, record in enumerate(records): cy_name = record['cy_en_name'] cy_name_list.append(cy_name) # 解析每天數(shù)據(jù)并計(jì)算現(xiàn)有確認(rèn)病例 existing_case_dict = {} for ncov_daily in record['data']['list']: date_str = ncov_daily['date'] confirm = ncov_daily['total']['confirm'] # 累計(jì)確診 heal = ncov_daily['total']['heal'] # 累計(jì)確診 dead = ncov_daily['total']['dead'] # 累計(jì)死亡 existing_case = confirm - heal - dead existing_case_dict[date_str] = existing_case last_existing_case = 0 # 將每天確診病例數(shù)合并到res中 for date_str in date_list: if date_str not in res: # 初始化 res[date_str] = [] existing_case = existing_case_dict.get(date_str) if existing_case is None: existing_case = last_existing_case res[date_str].append(existing_case) last_existing_case = existing_case return date_list, cy_name_list, res
參數(shù) records 是一個(gè)數(shù)組,數(shù)組每個(gè)元素代表一個(gè)國(guó)家,內(nèi)容便是我們?cè)诘谝徊秸?qǐng)求 list-by-area-code 接口的數(shù)據(jù)。最后,用 pyecharts 來(lái)畫(huà)圖,直接上代碼
def render_map(date_list, cy_name_list, ncov_data): tl = Timeline() # 創(chuàng)建時(shí)間線(xiàn)輪播多圖,可以讓圖形按照輸入的時(shí)間動(dòng)起來(lái) # is_auto_play:自動(dòng)播放 # play_interval:播放時(shí)間間隔,單位:毫秒 # is_loop_play:是否循環(huán)播放 tl.add_schema(is_auto_play=True, play_interval=50, is_loop_play=False) for date_str in date_list: # 遍歷時(shí)間列表 map0 = ( Map() # 創(chuàng)建地圖圖表 # 將國(guó)家名 cy_name_list 以及各國(guó)當(dāng)天確診病例 ncov_data[date_str] 加入地圖中 .add("全球疫情趨勢(shì)", [list(z) for z in zip(cy_name_list, ncov_data[date_str])], "world", is_map_symbol_show=False) .set_series_opts(label_opts=opts.LabelOpts(is_show=False)) # 不顯示國(guó)家名 .set_global_opts( title_opts=opts.TitleOpts(title="%s日" % date_str), # 圖表標(biāo)題 visualmap_opts=opts.VisualMapOpts(max_=80), # 當(dāng)確診病例大于80 ,地圖顏色是紅色 ) ) tl.add(map0, "%s" % date_str) # 將當(dāng)天的地圖狀態(tài)加入時(shí)間線(xiàn)中 tl.render() # 生成最終輪播多圖,會(huì)在當(dāng)前目錄創(chuàng)建 render.html 文件
代碼里加了注釋?zhuān)@里就不再贅述了。
運(yùn)行 render_map 函數(shù)會(huì)在當(dāng)前目錄生成 render.html 文件,打開(kāi)后便自動(dòng)播放疫情變化趨勢(shì),如文章開(kāi)頭 gif。另外,有些朋友可能會(huì)問(wèn),能不能直接輸出 gif。這一點(diǎn)我也嘗試過(guò),百度、谷歌、GitHub上的教程基本上都試了一遍,比較遺憾沒(méi)有找到靠譜的方法。所以勸大家還是放棄這條路,曲線(xiàn)救國(guó),錄制一個(gè)視頻轉(zhuǎn)成 gif 即可,方便快捷。畢竟人生苦短,Python 為我們節(jié)省下的時(shí)間不能再被這些無(wú)謂的坑再填回去。這樣整個(gè)過(guò)程就介紹完了,雖然思路不復(fù)雜,但局部細(xì)節(jié)上還是需要花一些時(shí)間處理的。
完整代碼共 230 行,需要的點(diǎn)擊下載。
鏈接: https://pan.baidu.com/s/17nIHelAGviyNhftskB-rdA 提取碼: at9z
最近國(guó)內(nèi)某些地方出現(xiàn)了反彈的跡象,希望大家無(wú)論是在工作還是生活上都能繼續(xù)保持警惕。希望這次疫情早點(diǎn)過(guò)去,等待全球地圖變白的那一天。
到此這篇關(guān)于Python繪制全球疫情變化地圖的實(shí)例代碼的文章就介紹到這了,更多相關(guān)Python全球疫情變化地圖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Pandas處理時(shí)間序列數(shù)據(jù)操作詳解
這篇文章主要介紹了Pandas處理時(shí)間序列數(shù)據(jù)操作詳解,文章首先利用python自帶datetime庫(kù),通過(guò)調(diào)用此庫(kù)可以獲取本地時(shí)間展開(kāi)內(nèi)容說(shuō)明具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-06-06Python爬蟲(chóng)之超級(jí)鷹驗(yàn)證碼應(yīng)用
眾所周知python是一個(gè)很強(qiáng)大的語(yǔ)言,它擁有眾多的庫(kù),今天我嘗試了使用超級(jí)鷹第三方平臺(tái)進(jìn)行驗(yàn)證碼的開(kāi)發(fā),需要的朋友可以參考下2022-08-08python的pandas工具包,保存.csv文件時(shí)不要表頭的實(shí)例
今天小編小編就為大家分享一篇python的pandas工具包,保存.csv文件時(shí)不要表頭的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-06-06Python安裝Selenium報(bào)錯(cuò)解決之全方位排錯(cuò)指南
pip是一個(gè)安裝Python包的管理工具,很多功能強(qiáng)大、使用方便的Python框架、插件、工具等,都是通過(guò)pip來(lái)進(jìn)行安裝的,這篇文章主要給大家介紹了關(guān)于Python安裝Selenium報(bào)錯(cuò)解決之全方位排錯(cuò)的相關(guān)資料,需要的朋友可以參考下2024-08-08Python中循環(huán)依賴(lài)問(wèn)題及其解決方案
在軟件開(kāi)發(fā)中,循環(huán)依賴(lài)是一個(gè)常見(jiàn)的問(wèn)題,尤其是在使用 Python 這樣的動(dòng)態(tài)語(yǔ)言時(shí),循環(huán)依賴(lài)指的是兩個(gè)或多個(gè)模塊或組件相互依賴(lài),形成一個(gè)閉環(huán),本文將探討 Python 中循環(huán)依賴(lài)的問(wèn)題,并提供一些解決方案,需要的朋友可以參考下2024-06-06