Basemap入坑手冊
前面的廢話
本來只是想畫個熱點圖,然後一路 百度地圖API —> folium —> Basemap,因爲前兩個要html的知識,而我並沒有,所以最後入坑了Basemap。
然而網上的資源雖然很多,但是比較零散,不過找到英文版的tutorial,全英文的怕自己讀不下去,決定邊學邊記筆記,以及有好用的教程和資源也在這裏馬克一下。
0. 介紹
Python裏畫地圖的。
1. 安裝
每逢非pip可以安裝的包就有點頭大。
安裝部分官方也有指南,大概的意思就是先裝python (廢話)、matplotlib、numpy、PROJ4、GEOS、Pillow(可選)再安裝Basemap。
我是Mac的Anaconda,所以直接在下載了Source Code (tar.gz),解壓後在終端安裝。
具體過程:
解壓後文件夾裏會有setup.py的文件;
打開終端,輸入
cd ./desktop/..
(Change Directory到setup.py的位置);- 輸入
python setup.py install
; - 在python裏輸入
from mpl_toolkits.basemap import Basemap
,如果沒有報錯說明安裝成功。
更詳細的教程可以參考:
Mac:Mac Python+basemap安裝
Linux:python番外(2)——Basemap安裝
Windows:window下安裝basemap
2. 畫第一張圖
最基礎的圖代碼如下:
# 導入包
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
# 新建地圖
map = Basemap() #Basemap類有很多屬性,這裏全都使用默認參數
# 畫圖
map.drawcoastlines()
# 顯示結果
plt.show()
# 存儲結果
plt.savefig('test.png')
得到這樣的圖
一丟丟進階的圖代碼如下:
# 導入包
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
# 更改投影方式
map = Basemap(projection = 'ortho', lat_0 = 0, lon_0 = 0) #’ortho’指正射投影,具體參數後面再討論;後面兩個參數是設置中心點
# 給整個地圖上藍色
map.drawmapboundary(fill_color = 'aqua')
# 給陸地塗上珊瑚色,湖泊塗上藍色
map.fillcontinents(color = 'coral', lake_color = 'aqua')
# 畫圖
map.drawcoastlines()
# 顯示結果
plt.show()
得到這樣的圖
如果遇到error請點這裏看看。
3. 地圖投影專題
地圖投影是利用一定數學法則把地球表面的經、緯線轉換到平面上的理論和方法。——百度百科
tutorial指出Basemap裏的投影方式跟其他庫不太一樣(如GDAL),所以要好好學一學。
3.1 地圖投影基礎
Basemap的投影方式是由Basemap類中projection
這一屬性控制的,默認爲cyl
,可選項如下:
選項 | 描述 | 解釋 |
---|---|---|
cyl | Cylindrical Equidistant | 默認,圓柱投影 |
merc | Mercator | 墨卡託投影,是正軸等角圓柱投影 |
tmerc | Transverse Mercator | 橫軸墨卡託 |
omerc | Oblique Mercator | |
mill | Miller Cylindrical | |
gall | Gall Stereographic | |
cea | Cylindrical Equal-Area | |
lcc | Lambert Conformal | |
laea | Lambert Azimuthal Equal Area | |
nplaea | North-Polar Lambert | |
splaea | South-Polar Lambert | |
eqdc | Equidistant Conic | |
aeqd | Azimuthal Equidistant | |
npaeqd | North-Polar Azimuthal | |
spaeqd | South-Polar Azimuthal | |
aea | Albers Equal | |
stere | Stereographic | |
npstere | North-Polar Stereographic | |
spstere | South-Polar Stereographic | |
cass | Cassini-Soldner | |
poly | Polyconic | |
ortho | Orthographic | |
geos | Geostationary | |
nsper | Near-Sided Perspective | |
sinu | Sinusoidal | |
moll | Mollweide | |
hammer | Hammer | |
robin | Robinson | |
kav7 | Kavrayskiy VII | |
eck4 | Eckert IV | |
vandg | van der | |
mbtfpq | McBryde-Thomas Flat-Polar | |
gnom | Gnomonic | |
rotpole | Rotated Pole |
對應的具體效果見附錄(點擊鏈接查看對應例子,或Ctrl+F查找)。
解釋部分的參考:
- Matplotlib: Setting up the map
- 地圖投影種類-中英文對照
- 地圖投影的N種姿勢
- 以及百度百科
3.1.1 Using epsg to set the projection
3.2 地圖投影拓展
如果不想展示整個地圖,可以通過修改地圖邊界或中心來展示部分區域。
除了cyl、merc、mill、cea和gall默認顯示整個地球llcrnrlon = -180, llcrnrlat = -90, urcrnrlon = 180, urcrnrlat=90
,其他投影方式都要手動設置Basemap類的參數來設置所展示的區域。主要有三種方法:
方法一:設置邊界的經緯度
參數 | 解釋 |
---|---|
llcrnrlon | longitude of lower left hand corner of the desired map domain (degrees). 地圖左邊經度 |
llcrnrlat | latitude of lower left hand corner of the desired map domain (degrees). 地圖下方緯度 |
urcrnrlon | longitude of upper right hand corner of the desired map domain (degrees). 地圖右邊經度 |
urcrnrlat | latitude of upper right hand corner of the desired map domain (degrees). 地圖上方緯度 |
方法二:設置邊界的座標
參數 | 解釋 |
---|---|
llcrnrx | x value of lower left hand corner of the selected map domain in map projection coordinates. 地圖左下角的x值 |
llcrnry | y value of lower left hand corner of the selected map domain in map projection coordinates. 地圖左下角的y值 |
urcrnrx | x value of upper right hand corner of the selected map domain in map projection coordinates. 地圖右上角的x值 |
urcrnry | y value of upper right hand corner of the selected map domain in map projection coordinates. 地圖右上角的y值 |
方法三:設置中心點和高與寬
參數 | 解釋 |
---|---|
width | width of desired map domain in projection coordinates (meters). 寬 |
height | height of desired map domain in projection coordinates (meters). 高 |
lon_0 | center of desired map domain (in degrees). 中心點的經度 |
lat_0 | center of desired map domain (in degrees). 中心點的緯度 |
附錄
附錄一:地圖投影示例
- Cylindrical Equidistant
代碼:
# 導入包
from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
# 投影方式選擇
m = Basemap(projection = 'cyl')
# 畫海岸線
m.drawcoastlines()
# 上色
m.fillcontinents(color = 'coral', lake_color = 'aqua')
m.drawmapboundary(fill_color = 'aqua')
# 畫經緯度線
m.drawparallels(np.arange(-90.,91.,30.))
m.drawmeridians(np.arange(-180.,181.,60.))
# 送上標題
plt.title("Cylindrical Equidistant Projection")
plt.show()
結果:
返回地圖投影專題
- Mercator
代碼:
# 導入包
from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
# 投影方式選擇
m = Basemap(projection = 'merc', llcrnrlat = -80, urcrnrlat = 80, llcrnrlon = -180, urcrnrlon = 180, lat_ts = 20, resolution = 'c')
# 畫海岸線
m.drawcoastlines()
# 上色
m.fillcontinents(color = 'coral', lake_color = 'aqua')
m.drawmapboundary(fill_color = 'aqua')
# 畫經緯度線
m.drawparallels(np.arange(-90.,91.,30.))
m.drawmeridians(np.arange(-180.,181.,60.))
# 送上標題
plt.title("Mercator Projection")
plt.show()
結果:
返回地圖投影專題
- Transverse Mercator
代碼:
# 導入包
from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
# 投影方式選擇
m = Basemap(projection = 'tmerc', llcrnrlat = 49.5, urcrnrlat = 59.5, llcrnrlon = -10.5, urcrnrlon = 3.5, lon_0 = -4.36, lat_0 = 54.7, resolution = 'i')
# 畫海岸線
m.drawcoastlines()
# 上色
m.fillcontinents(color = 'coral', lake_color = 'aqua')
m.drawmapboundary(fill_color = 'aqua')
# 畫經緯度線
m.drawparallels(np.arange(-40,61.,2.))
m.drawmeridians(np.arange(-20.,21.,2.))
# 送上標題
plt.title("Transverse Mercator Projection")
plt.show()
結果:
返回地圖投影專題
- Oblique Mercator
代碼:
# 導入包
from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
# 投影方式選擇
m = Basemap(projection = 'omerc', height = 16700000, width = 12000000, area_thresh = 1000., lon_0 = -100, lat_0 = 15, lon_1 = -50, lat_1 = -55, lon_2 = -120, lat_2 = 65, resolution = 'l')
# 畫海岸線
m.drawcoastlines()
# 上色
m.fillcontinents(color = 'coral', lake_color = 'aqua')
m.drawmapboundary(fill_color = 'aqua')
# 畫經緯度線
m.drawparallels(np.arange(-80.,81.,20.))
m.drawmeridians(np.arange(180.,181.,20.))
# 送上標題
plt.title("Oblique Mercator Projection")
plt.show()
結果:
返回地圖投影專題
- Miller Cylindrical
代碼:
# 導入包
from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
# 投影方式選擇
m = Basemap(projection = 'mill', llcrnrlat = -90, urcrnrlat = 90, llcrnrlon = -180, urcrnrlon = 180, resolution = 'c')
# 畫海岸線
m.drawcoastlines()
# 上色
m.fillcontinents(color = 'coral', lake_color = 'aqua')
m.drawmapboundary(fill_color = 'aqua')
# 畫經緯度線
m.drawparallels(np.arange(-90.,91.,30.))
m.drawmeridians(np.arange(-180.,181.,60.))
# 送上標題
plt.title("Miller Cylindrical Projection")
plt.show()
結果:
返回地圖投影專題
- Gall Stereographic
代碼:
# 導入包
from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
# 投影方式選擇
m = Basemap(projection = 'gall', llcrnrlat = -90, urcrnrlat = 90, llcrnrlon = -180, urcrnrlon = 180, resolution = 'c')
# 畫海岸線
m.drawcoastlines()
# 上色
m.fillcontinents(color = 'coral', lake_color = 'aqua')
m.drawmapboundary(fill_color = 'aqua')
# 畫經緯度線
m.drawparallels(np.arange(-90.,91.,30.))
m.drawmeridians(np.arange(-180.,181.,60.))
# 送上標題
plt.title("Gall Stereographic Projection")
plt.show()
結果:
返回地圖投影專題
- Cylindrical Equal-Area
代碼:
# 導入包
from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
# 投影方式選擇
m = Basemap(projection = 'cea', llcrnrlat = -90, urcrnrlat = 90, llcrnrlon = -180, urcrnrlon = 180, resolution = 'c')
# 畫海岸線
m.drawcoastlines()
# 上色
m.fillcontinents(color = 'coral', lake_color = 'aqua')
m.drawmapboundary(fill_color = 'aqua')
# 畫經緯度線
m.drawparallels(np.arange(-90.,91.,30.))
m.drawmeridians(np.arange(-180.,181.,60.))
# 送上標題
plt.title("Cylindrical Equal-Area Projection")
plt.show()
結果:
返回地圖投影專題
- Lambert Conformal
代碼:
# 導入包
from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
# 投影方式選擇
m = Basemap(projection = 'lcc', lat_0 = 50, lon_0 = -107., lat_1 = 45., lat_2 = 55, width = 12000000, height = 9000000, rsphere = (6378137.00, 6356752.3142), resolution = 'l')
# 畫海岸線
m.drawcoastlines()
# 上色
m.fillcontinents(color = 'coral', lake_color = 'aqua')
m.drawmapboundary(fill_color = 'aqua')
# 畫經緯度線
m.drawparallels(np.arange(-80.,81.,20.))
m.drawmeridians(np.arange(-180.,181.,20.))
# 送上標題
plt.title("Lambert Conformal Projection")
plt.show()
結果:
返回地圖投影專題
- Lambert Azimuthal Equal Area
代碼:
# 導入包
from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
# 投影方式選擇
m = Basemap(projection = 'laea', lat_0 = 50, lon_0 = -107., lat_ts = 50, width = 12000000, height = 8000000, resolution = 'l')
# 畫海岸線
m.drawcoastlines()
# 上色
m.fillcontinents(color = 'coral', lake_color = 'aqua')
m.drawmapboundary(fill_color = 'aqua')
# 畫經緯度線
m.drawparallels(np.arange(-80.,81.,20.))
m.drawmeridians(np.arange(-180.,181.,20.))
# 送上標題
plt.title("Lambert Azimuthal Equal Area Projection")
plt.show()
結果:
返回地圖投影專題
- North-Polar Lambert
代碼:
結果:
- South-Polar Lambert
代碼:
結果:
- Equidistant Conic
代碼:
結果:
- Azimuthal Equidistant
代碼:
結果:
- North-Polar Azimuthal
代碼:
結果:
- South-Polar Azimuthal
代碼:
結果:
- Albers Equal
代碼:
結果:
- Stereographic
代碼:
結果:
- ??
代碼:
結果:
- ??
代碼:
結果:
- ??
代碼:
結果:
- ??
代碼:
結果:
- ??
代碼:
結果:
- ??
代碼:
結果:
- ??
代碼:
結果:
- ??
代碼:
結果: