使用geopandas 制作中国疫情地图
最近要做一個中國地圖,以前用pyecharts,最近接觸了geopandas 覺得很強大,改用geopandas作圖。比如我制作一個疫情分布地圖,效果應(yīng)該是這樣的。最終效果。
首先導(dǎo)入需要用的庫:
import pandas as pd import matplotlib.pyplot as plt import requests import geopandas as gpd plt.rcParams['font.family'] = 'SimHei'?然后使用爬蟲把疫情數(shù)據(jù)怕取下來,我使用的是 手機端的網(wǎng)易數(shù)據(jù)接口,地址是,
實時更新|新冠肺炎疫情動態(tài)地圖https://wp.m.163.com/163/page/news/virus_report/index.html用瀏覽器打開是這樣的。
打開檢查工具,找到XHR,看請求的內(nèi)容。
第一個地址就是,
可以看一下它的相應(yīng),
?
?
?
是json數(shù)據(jù),沒有問題,還是選擇用curl工具生成,直接生成的代碼是這樣的。
?
?
headers = {'User-Agent': 'Mozilla/5.0 (Linux; Android 11) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.120 Mobile Safari/537.36','Accept': '*/*','Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2','Origin': 'https://wp.m.163.com','Connection': 'keep-alive','Referer': 'https://wp.m.163.com/','Sec-Fetch-Dest': 'empty','Sec-Fetch-Mode': 'cors','Sec-Fetch-Site': 'same-site','TE': 'trailers', }params = (('t', '326609897543'), )response = requests.get('https://c.m.163.com/ug/api/wuhan/app/data/list-total', headers=headers, params=params)然后就是數(shù)據(jù)提取。
使用這個網(wǎng)站,解析一下json數(shù)據(jù)。
這個網(wǎng)站對json的解析比較魯棒。
可以看到,我們需要省:每個省的確診數(shù)。
接下來,代碼提取。
rj = response.json() rj.keys()rjdata = rj['data'] data.keys() areaTree = data['areaTree'] areaTree.keys() chinaData = areaTree[2] chinaData.keys() children = chinaData['children'] len(children)#用一個試試 c1 = children[0] c1.keys() c1['name']prov = [c['name'] for c in children]print(prov)c1['total']['confirm']confirm = [c['total']['confirm'] for c in children] print(confirm)做成一個dataframe,以便后面使用
china_prov = pd.DataFrame({"prov":prov,"confirm":confirm }) china_provgeopandas使用
接下來,使用geopandas,看了一個大神的博客,寫得很詳細了。
這里是網(wǎng)址:
(數(shù)據(jù)科學(xué)學(xué)習(xí)手札74)基于geopandas的空間數(shù)據(jù)分析——數(shù)據(jù)結(jié)構(gòu)篇 - 費弗里 - 博客園
https://www.cnblogs.com/feffery/p/11898190.html
這位高人,介紹很系統(tǒng)了。分成好幾篇博客,看完對geo的理解更深刻一些。
這里我直接讀取中國地圖的數(shù)據(jù),
china = gpd.read_file("region_map/MLgis/feifuli3_geometry/china_provinces/china_provinces.shp")fig, ax = plt.subplots(figsize=(12, 8)) ax = china.geometry.plot(ax = ax )這個地圖做出來,是不太常見的投影方式或者坐標(biāo)系,因此不好看,所以把投影方式改成:
albers_proj = '+proj=aea +lat_1=25 +lat_2=47 +lon_0=105'fig, ax = plt.subplots(figsize=(12, 8)) ax = china.geometry.to_crs(albers_proj).plot(ax=ax)fig, ax = plt.subplots(figsize=(12, 8)) ax = china.geometry.to_crs(albers_proj).plot(ax=ax,facecolor = 'grey',edgecolor = 'whit這樣基本就得到了中國地圖。
其中 shp文件,我從網(wǎng)上下載的。如有必要可以上傳。
另外 各地區(qū)的疫情數(shù)據(jù)為了防止邊,轉(zhuǎn)成json格式的。貼上無所謂:
china_prov china_prov.to_json()china_prov2 = pd.read_json('{"prov":{"0":"\\u6e56\\u5317","1":"\\u53f0\\u6e7e","2":"\\u9999\\u6e2f","3":"\\u5e7f\\u4e1c","4":"\\u4e0a\\u6d77","5":"\\u9ed1\\u9f99\\u6c5f","6":"\\u6c5f\\u82cf","7":"\\u6cb3\\u5357","8":"\\u6d59\\u6c5f","9":"\\u4e91\\u5357","10":"\\u6cb3\\u5317","11":"\\u798f\\u5efa","12":"\\u56db\\u5ddd","13":"\\u6e56\\u5357","14":"\\u5317\\u4eac","15":"\\u5b89\\u5fbd","16":"\\u65b0\\u7586","17":"\\u6c5f\\u897f","18":"\\u5c71\\u4e1c","19":"\\u9655\\u897f","20":"\\u91cd\\u5e86","21":"\\u5409\\u6797","22":"\\u5929\\u6d25","23":"\\u8fbd\\u5b81","24":"\\u5185\\u8499\\u53e4","25":"\\u5e7f\\u897f","26":"\\u5c71\\u897f","27":"\\u7518\\u8083","28":"\\u6d77\\u5357","29":"\\u8d35\\u5dde","30":"\\u5b81\\u590f","31":"\\u6fb3\\u95e8","32":"\\u9752\\u6d77","33":"\\u897f\\u85cf"},"confirm":{"0":68298,"1":16223,"2":12217,"3":3177,"4":2603,"5":1702,"6":1599,"7":1540,"8":1448,"9":1424,"10":1317,"11":1282,"12":1208,"13":1182,"14":1124,"15":1008,"16":980,"17":937,"18":933,"19":671,"20":603,"21":574,"22":487,"23":455,"24":419,"25":298,"26":260,"27":199,"28":190,"29":147,"30":77,"31":71,"32":18,"33":1}}') china_prov2然后接下來就是合并數(shù)據(jù)了。
使用geopandas讀入的china 是一個geoDataFrame格式的。
但是可以當(dāng)做普通數(shù)據(jù)表對待,直接合并就可以。
合并之前注意到,china 的 NAME 是各省名字,和我們原有的疫情數(shù)據(jù)的prov 不一樣。
?
?所以要先處理成統(tǒng)一昂的數(shù)據(jù)。
china['prov_name'] = china['NAME'].str.replace('省', '') china['prov_name'] = china['prov_name'].str.replace('市', '') china['prov_name'] = china['prov_name'].str.replace('自治區(qū)', '') china['prov_name'] = china['prov_name'].str.replace(r'壯族|回族|維吾爾', '') china['prov_name']生成一個“prov_name”,和疫情數(shù)據(jù)中“prov”對應(yīng)。這樣合并。
data_with_geometry = pd.merge(left = china_prov,right = china,left_on='prov',right_on = 'prov_name',how = 'left')合并之后,還要改變投影方式,
data_with_geometry = gpd.GeoDataFrame(data_with_geometry, crs = 'EPSG:4326')接下來就可以作圖了。
fig, ax =plt.subplots(figsize=(12, 8)) ax = data_with_geometry.to_crs(albers_proj).plot(ax=ax,column = 'confirm',cmap = 'Reds',missing_kwds = {"color":"lightgrey","edgecolor":"black","hatch":"///"})只不過這樣的作圖方式,湖北省顏色唯一最深的,其他地區(qū)都一樣,沒有層次。
所以設(shè)置一下scheme。
fig, ax = plt.subplots(figsize=(12, 8)) ax = data_with_geometry.to_crs(albers_proj).plot(ax=ax,column = 'confirm',cmap = 'Reds',legend = True,scheme = 'NaturalBreaks',k = 5 ,legend_kwds = {"loc":"lower left","title":'確診數(shù)量分級',"shadow":True})這樣就ok了。
這個過程關(guān)鍵就是合并地圖數(shù)據(jù)和分析數(shù)據(jù)。geopandas就是強,直接和。非常方便。
總結(jié)
以上是生活随笔為你收集整理的使用geopandas 制作中国疫情地图的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 请求时的编码问题 Use body.en
- 下一篇: 基金净值越高越好吗 主要关注这一点就可