[Python從零到壹] 十八.可視化分析之Basemap地圖包入門詳解
一.Basemap安裝
這里作者只做簡單介紹,我們從非官網網站下載下面兩個擴展包,cp36表示Python3.6版本,Windows下64位環境加amd64,你需要找到適合自己環境的文件。
- basemap-1.2.2-cp36-cp36m-win_amd64.whl
- pyproj-3.0.1-cp36-cp36m-win_amd64.whl
下載地址為:
- https://www.lfd.uci.edu/~gohlke/pythonlibs/

接下來使用PIP命令去到whl文件所在目錄,然后分別進行安裝。先安裝Pyproj,再安裝Basemap擴展包,命令如下:
pip install basemap-1.2.2-cp36-cp36m-win_amd64.whl
安裝過程如下圖所示:


Successfully installed basemap-1.2.2 cycler-0.11.0 kiwisolver-1.3.1 matplotlib-3.3.4 numpy-1.19.5 pillow-8.4.0 pyparsing-3.0.5 pyproj-3.0.1 pyshp-2.1.3 python-dateutil-2.8.2 six-1.16.0
接下來調用該擴展包,不再報錯即表示安裝成功。
二.地圖繪制官方案例
首先作者給出官方文檔的介紹以及簡單案例,讓讀者體會下Basemap的魅力。官方網址:
- https://matplotlib.org/basemap
1.Basemap簡介
Basemap工具包是Matplotlib包的子包,一個用于在Python繪制2D數據至地圖的庫,它提供了將坐標轉化為25中不同地圖投影的功能,然后調用Matplotlib擴展包繪制輪廓、圖像和坐標點等。
該擴展包提供了海岸線、河流、政治邊界數據集以及繪制方法。其中GEOS庫在內部用于將海岸線和邊界特征剪切到所需的地圖投影區域。下面給出官網的翻譯示例,源地址:
- https://matplotlib.org/basemap/users/geography.html
Basemap包括GSSH(現在是GSHHG)海岸線數據集以及GMT格式的河流、州和國家邊界的數據集。這些數據集可以用來以不同的分辨率繪制海岸線、河流和政治邊界地圖。相關方法如下:
- drawcoastlines(): 繪制海岸線。
- fillcontinents(): 通過填充海岸線多邊形為地圖著色。
- drawcountries(): 繪制國家邊界。
- drawstates(): 在北美繪制狀態邊界。
- drawrivers(): 繪制河流。
此外,可以將圖像用作地圖背景,而不是繪制海岸線和政治邊界。Basemap提供了以下幾個選項:
- drawlsmask(): 繪制高分辨率的海陸圖像,指定陸地和海洋的顏色,數據源于GSHHS海岸線。
- bluemarble(): 繪制NASA藍色大理石圖像作為地圖背景。
- shadedrelief(): 繪制陰影浮雕圖像作為地圖背景。
- etopo(): 繪制一張etopo浮雕圖像作為地圖背景。
- warpimage(): 使用abitrary圖像作為地圖背景,必須是全球新的,從國際日東線向東和南極以北覆蓋世界。
2.案例分析
(1) 繪制海岸線、填充海洋和陸地區域
# -*- coding: utf-8 -*-# By:Eastmount CSDNfrom mpl_toolkits.basemap import Basemapimport matplotlib.pyplot as plt # 設置basemap-Lambert Conformal m = Basemap(width=12000000,height=9000000,projection='lcc', resolution='c',lat_1=45.,lat_2=55,lat_0=50,lon_0=-107.) # 繪制海岸線m.drawcoastlines()# 在地圖周圍繪制邊界并填充背景aqua(這個背景最終成為海洋的顏色)# 將大洲繪制在最上面m.drawmapboundary(fill_color='aqua') # 填充大陸coral顏色,并設置湖泊顏色為bluem.fillcontinents(color='coral',lake_color='blue')plt.show()
繪制圖形如下所示:

(2) 繪制一幅海陸罩(land-sea mask)圖像
# -*- coding: utf-8 -*-# By:Eastmount CSDNfrom mpl_toolkits.basemap import Basemapimport matplotlib.pyplot as plt # 設置basemap Lambert-Conformal # 設置分辨率參數resolution=None 跳過處理邊界數據集m = Basemap(width=12000000,height=9000000,projection='lcc', resolution=None,lat_1=45.,lat_2=55,lat_0=50,lon_0=-107.) # 為地圖背景繪制海陸罩# lakes=True 意味著內陸湖和海洋顏色一致m.drawlsmask(land_color='coral',ocean_color='aqua',lakes=True)plt.show()
繪制如下圖所示:

(3) 繪制美國宇航局藍色大理石圖像(the NASA Blue Marble)
# -*- coding: utf-8 -*-# By:Eastmount CSDNfrom mpl_toolkits.basemap import Basemapimport matplotlib.pyplot as plt m = Basemap(width=12000000,height=9000000,projection='lcc', resolution=None,lat_1=45.,lat_2=55,lat_0=50,lon_0=-107.)m.bluemarble()plt.show()
繪制如下圖所示:

(4) 繪制帶陰影的浮雕圖像
# -*- coding: utf-8 -*-# By:Eastmount CSDNfrom mpl_toolkits.basemap import Basemapimport matplotlib.pyplot as plt m = Basemap(width=12000000,height=9000000,projection='lcc', resolution=None,lat_1=45.,lat_2=55,lat_0=50,lon_0=-107.)m.shadedrelief()plt.show()
繪制如下圖所示:

(5) 繪制etopo浮雕圖像
# -*- coding: utf-8 -*-# By:Eastmount CSDNfrom mpl_toolkits.basemap import Basemapimport matplotlib.pyplot as plt m = Basemap(width=12000000,height=9000000,projection='lcc', resolution=None,lat_1=45.,lat_2=55,lat_0=50,lon_0=-107.)m.etopo()plt.show()
繪制如下圖所示:

三.Basemap繪制地圖
1.地圖投影
可能讀者已經發現了,Basemap擴展包是繪制地圖最重要的庫之一,所以作者先講解該庫函數。同時,由于作者沒有找到系統的參數介紹,只能摸著石頭過河學習,也希望對您有點幫助。
為方便呈現,需要將三維球坐標系轉換為二維笛卡爾坐標系,利用地圖投影(Map Projection)實現。官網給出的25種映射方式如下:
- https://matplotlib.org/basemap/users/mapsetup.html

lcc類型的核心代碼如下:
m = Basemap(width=12000000, height=9000000, projection='lcc', resolution=None, lat_1=45., lat_2=55, lat_0=50, lon_0=-107.)
參數介紹如下:
- width:寬度
- height:高度
- projection=‘lcc’:表示規定的投影方法,改變投影方法繪制的結果也將不同,25種方式
- resolution=None:表示跳過處理邊界數據集
- lat_0=50:維度設置為50(Latitude,值為-90到90)
- lon_0=-107:經度設置為-107( Longitude,值為-180到180)
示例代碼如下:
- https://matplotlib.org/basemap/users/aeqd.html
# -*- coding: utf-8 -*-# By:Eastmount CSDNfrom mpl_toolkits.basemap import Basemapimport numpy as npimport matplotlib.pyplot as plt width = 28000000; lon_0 = -105; lat_0 = 40m = Basemap(width=width,height=width,projection='aeqd', lat_0=lat_0,lon_0=lon_0) # 填充背景m.drawmapboundary(fill_color='aqua')
# 繪制海岸線并填充大陸m.drawcoastlines(linewidth=0.5)m.fillcontinents(color='coral',lake_color='aqua')
# 20度經緯度,范圍-80到81 -180到180m.drawparallels(np.arange(-80,81,20))m.drawmeridians(np.arange(-180,180,20))
# 在中心繪制一個黑點xpt, ypt = m(lon_0, lat_0)m.plot([xpt],[ypt],'ko')
# 繪制標題plt.title('Azimuthal Equidistant Projection')plt.show()
運行結果如下圖所示:

merc類型的核心代碼如下:
m = Basemap(projection='merc', llcrnrlat=-80, urcrnrlat=80, llcrnrlon=-180, urcrnrlon=180)
參數介紹如下:
- projection=merc’:表示規定的投影方法,墨卡托投影(Mercator Projection),廣泛應用谷歌地圖
- llcrnrlat=-80:所需地圖域左下角的緯度(度)Latitude
- urcrnrlat=80:所需地圖域的右上角的緯度(度)Latitude
- llcrnrlon=-180:所需地圖域左下角的經度(度)Longitude
- urcrnrlon=180:所需地圖域(度)的右上角的經度Longitude
示例:
# -*- coding: utf-8 -*-# By:Eastmount CSDNfrom mpl_toolkits.basemap import Basemapimport matplotlib.pyplot as plt m = Basemap(projection='merc', llcrnrlat=-80, urcrnrlat=80, llcrnrlon=-180, urcrnrlon=180)m.drawcoastlines()plt.show()
繪制圖形如下所示:

同時,繪制一個城市點代碼的常見兩種方式如下:
# 上海經緯度 (31.23N,121.47E)x = 31.23y = 121.47xpt, ypt = m(x,y)m.scatter(xpt,ypt,s=2) x = 31.23y = 121.47xpt, ypt = m(x,y)m.plot([xpt],[ypt],'ko')
2.繪制全球主要城市地球儀
接下來我們學習vamei老師繪制全球主要城市的地球儀,其數據保存于major_city.txt文件中,內容如下:
- 城市名
- 人口名
- 維度
- 經度
- 國家
Shanghai 23019148 31.23N 121.47E ChinaMumbai 12478447 18.96N 72.82E IndiaKarachi 13050000 24.86N 67.01E PakistanDelhi 16314838 28.67N 77.21E IndiaManila 11855975 14.62N 120.97E PhilippinesSeoul 23616000 37.56N 126.99E Korea(South)Jakarta 28019545 6.18S 106.83E IndonesiaTokyo 35682460 35.67N 139.77E JapanPeking 19612368 39.91N 116.39E China
接著調用Basemap繪制圖形,代碼如下:
- http://www.cnblogs.com/vamei
# -*- coding: utf-8 -*-# Written by Vamei, http://www.cnblogs.com/vamei/# Feel free to use or modify this script.from mpl_toolkits.basemap import Basemapimport matplotlib.pyplot as pltimport numpy as np #============================================# read datanames = []pops = []lats = []lons = []countries = []for line in open("major_city.txt","r"): info = line.split() names.append(info[0]) pops.append(float(info[1])) lat = float(info[2][:-1]) if info[2][-1] == 'S': lat = -lat lats.append(lat) lon = float(info[3][:-1]) if info[3][-1] == 'W': lon = -lon + 360.0 lons.append(lon) country = info[4] countries.append(country) #============================================# set up map projection with# use low resolution coastlines.map = Basemap(projection='ortho',lat_0=35,lon_0=120,resolution='l')# draw coastlines, country boundaries, fill continents.map.drawcoastlines(linewidth=0.25)map.drawcountries(linewidth=0.25)# draw the edge of the map projection region (the projection limb)map.drawmapboundary(fill_color='#689CD2')# draw lat/lon grid lines every 30 degrees.map.drawmeridians(np.arange(0,360,30))map.drawparallels(np.arange(-90,90,30))# Fill continent wit a different colormap.fillcontinents(color='#BF9E30',lake_color='#689CD2',zorder=0)# compute native map projection coordinates of lat/lon grid.x, y = map(lons, lats)max_pop = max(pops)# Plot each city in a loop.# Set some parameterssize_factor = 80.0y_offset = 15.0rotation = 30for i,j,k,name in zip(x,y,pops,names): size = size_factor*k/max_pop cs = map.scatter(i,j,s=size,marker='o',color='#FF5600') plt.text(i,j+y_offset,name,rotation=rotation,fontsize=10) plt.title('Major Cities in Asia & Population')plt.show()
繪制圖形如下圖所示:

四.總結
最后給出比較好的參考資料,供自己和大家后面學習。希望文章對大家有所幫助,該篇文章主要是個安裝引入,后面還將結合項目深入介紹,推薦大家盡量結合實戰進行學習,比如航班預測、中國GPD區域分析等。如果存在錯誤或不足之處,還請海涵。
- Basemap可視化地圖信息 - zm
- [經驗總結] 一點總結:Ubuntu+anaconda+Python+basemap(+WRF) - 氣象家園
- 繪圖: matplotlib Basemap簡介 - Vamei
- Creating a Choropleth Map of the World in Python using Basemap
- Basemap繪制中國地圖 - 落葉小唱
- 用Python畫一個中國地圖 - 張京



