小蛇學python(23)basemap入門與進階
- 2020 年 2 月 18 日
- 筆記
Basemap是matplotlib下的一個庫文件,專門應用於繪製地圖。這一節就來詳細講解該文件的使用。首先來繪製一個最簡單的地圖。程式碼結果如圖1所示。
from mpl_toolkits.basemap import Basemap map = Basemap() #實例化一個對象 map.drawcoastlines() #map調用函數,該函數內置世界地圖海岸線 plt.savefig('image_name',bbox_inches='tight') #去掉圖片邊緣空白區域 plt.show()

圖1
如果覺得這樣的地圖過於單調,還可以給地圖塗色。如圖2所示。
from mpl_toolkits.basemap import Basemap map = Basemap() map.drawmapboundary(fill_color = 'aqua') #將整個地圖塗上藍色的一層 map.fillcontinents(color = 'coral') #將大陸部分塗上黃色 map.drawcoastlines() plt.savefig('image_name',bbox_inches='tight') plt.show()

圖2
你也許覺得這樣的世界地圖有些變形,這是因為投影方式的不同,Basemap內置了24種投影方式,感興趣的讀者可以瀏覽Basemap手冊仔細了解,本書不在這些細節上做過多牽扯。
當你不顯式指定投影方式時,Basemap會默認上圖的投影方式,這也是繪製世界地圖普遍採用的投影方式。其特點就是越接近赤道的地區越真實,維度越高的地區越失真,看起來比真實情況要小。
當你並不想繪製世界地圖時,可以根據顯式指定上下緯度以及左右經度確定具體區域。
map = Basemap(llcrnrlon=73, llcrnrlat=18, urcrnrlon=135, urcrnrlat=55, resolution='i', projection='merc', lat_0=42.5, lon_0=120) #通過經緯度確定中國區域 map.drawmapboundary(fill_color='aqua') map.fillcontinents(color='coral') map.drawcoastlines() map.drawcountries() #畫出國家邊界 plt.savefig('image_name', bbox_inches='tight') plt.show()
一副漂亮的中國地圖就畫出來了。還添加了國家的邊界,也是一句程式碼就可以完成的工作。如圖3所示

圖3
如果想進一步完成繪製中國地圖的工作,添加上中國各省份的邊界,這時候需要下載特定的數據文件。因為Basemap是外國人開發的庫,因此並沒有內置中國各省份的邊界數據。
不過從https://gadm.org/download_country_v3.html中,可以下載到你想要的任何國家的省份邊界數據。如圖4所示。
map = Basemap(llcrnrlon=73, llcrnrlat=18, urcrnrlon=135, urcrnrlat=55, resolution='i', projection='merc', lat_0=42.5, lon_0=120) map.drawmapboundary(fill_color='aqua') map.fillcontinents(color='coral') map.drawcoastlines() map.drawcountries() map.readshapefile('gadm36_CHN_1', 'states', drawbounds=True) #讀取各省邊界數據 plt.savefig('image_name', bbox_inches='tight') plt.show()

圖4
有了以上的基礎,接下來實現一個實例。利用之前的中國各省份GDP的數據文件,結合Basemap畫一幅GDP熱力圖。程式碼如下,效果如圖5所示。
from mpl_toolkits.basemap import Basemap from matplotlib.patches import Polygon from matplotlib.colors import rgb2hex plt.figure(figsize=(16, 8)) map=Basemap(llcrnrlon=77,llcrnrlat=14,urcrnrlon=140,urcrnrlat=51,projection='lcc',lat_1=33,lat_2=45,lon_0=100) map.drawcountries(linewidth=1.5) map.drawcoastlines() map.readshapefile('gadm36_CHN_1', 'states', drawbounds=True) #讀取省份邊界數據 df = pd.read_csv('Chinese_GDP.csv') #讀取GDP數據 df.set_index('地區', inplace=True) #將列名為地區這一列設為索引 provinces = map.states_info #讀取省份資訊 statenames = [] colors = {} cmap = plt.cm.YlOrRd #指定色彩映射種類 GDP_max = max(df['2016年']) GDP_min = min(df['2016年']) for each_province in provinces: #for循環中是對shapefile格式數據的處理,與主要程式邏輯無關 province_name = each_province['NL_NAME_1'] p = province_name.split('|') if len(p) > 1: s = p[1] else: s = p[0] s = s[:2] if s == '黑龍': s = '黑龍江' if s == '內蒙': s = '內蒙古' statenames.append(s) GDP = df['2016年'][s] colors[s] = cmap(np.sqrt((GDP - GDP_min) / (GDP_max - GDP_min)))[:3] #構建色彩映射關係 statenames.append('Taiwan') #將中國台灣的數據單獨添加進去 GDP_Taiwan = df['2016年']['Taiwan'] colors['Taiwam'] = cmap(np.sqrt((GDP_Taiwan - GDP_min) / (GDP_max - GDP_min)))[:3] ax = plt.gca() for nshape, seg in enumerate(map.states): color = rgb2hex(colors[statenames[nshape]]) #將RGB色彩轉為HEX色彩 poly = Polygon(seg, facecolor=color, edgecolor=color) #將每個省份對應的顏色進行填充 ax.add_patch(poly) map.readshapefile('gadm36_TWN_0', 'states', drawbounds=True) for nshape, seg in enumerate(map.states): color = rgb2hex(colors[statenames[nshape]]) #將RGB色彩轉為HEX色彩 poly = Polygon(seg, facecolor=color, edgecolor=color) #將每個省份對應的顏色進行填充 ax.add_patch(poly) ax.set_title('China GDP heatmap') plt.savefig('image_name', bbox_inches='tight') plt.show()

圖5
關鍵步驟已經寫了程式碼注釋,不過還是從整體邏輯角度解釋一下程式碼。
(1)設置展示地圖區域的經緯度參數。
(2)讀取內含中國大陸省份邊界的數據文件,需要注意這些數據文件也是海外人士提供的,因為某些原因缺少中國台灣的數據,所以在後期把中國台灣的相關數據也補充添加進去了。
(3)讀取中國各省份GDP數據,並將地區列設置為索引。
(4)比較關鍵,程式碼量也比較多,其完成了處理shapefile格式數據,設置色彩映射的功能。
(5)是進行色彩填充,以省份行政區域為單位進行循環,依次填充各省份GDP所對應的顏色。GDP越高,顏色越深。
最後案例對應數據可點贊後簡信我索取。