記錄一下
之前畫地理地圖相關的東西時都是用basemap
但是basemap已經停止更新了,維護工作也只會持續到2020
而官方之後的心力都會放在cartopy上
雖然就算停止維護了還是可以正常使用basemap啦
但是保險起見,再加上既然官方都那樣建議了
看來還是先乖乖學一下cartopy比較好
basemap的流程大概是這樣:
利用Basemap(...)建立basemap物件
然後利用這個物件的各種method作圖
而cortopy則不一樣
將cortopy import進來後
只需要在平常使用的matplotlib函式中加個'projection'轉換成cartopy的格式
之後就可以跟平常一樣的方式畫圖
(有點類似用matploblib畫3D圖那樣)
所以原本用basemap的話會像這樣:
m = Basemap(....)
m.contourf(...)
m.quiver(....)
....
cartopy則會是這樣
fig, ax = plt.subplots(subplot_kw={'projection': .....})
ax.conourf(.....)
ax.quiver(......)
就不需要再透過其他物件來畫了
---
拿以前的例子來試試
這三張沒什麼特別的
就跟之前那篇basemap的差不多
只是import變成cartopy
這張就是開始用cartopy去畫了
可以看到在subplots()裡面,利用subplot_kw,傳入一個dictionary
其中包含了{'projection' : ccrs.PlateCarree()}
而ccrs.PlateCarree當然就是要畫的地圖投影方式了
另外我這邊是用subplots來做
不過只要任何可以建立axes、而且包含project選項的函數都可以
像是這樣也是可以的:
ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree())
轉換成cartopy的座標後
再利用ax.set_extent將範圍限制在我們想要的範圍內
也就是cartopy會先建立一個全世界的地圖,再依照想要的範圍去限制
不像basemap是一開始就會需要給定範圍才能建立地圖
不過有趣的是雖然cartopy一開始會先建出全世界,但是執行速度似乎不會因此比較慢
剩下就蠻直觀的
ax.coastlines()就是畫出海岸線,設定解析度是用'110m'、'50m'、'10m'這樣
ax.gridlines()是畫出經緯度線,draw_labels就是設定要不要順便畫出xy的tickslabel
不過畫出來會整個圖四個邊都有label
我自己希望只要左邊和下面有就好,所以特別設為False
(不過預設也是False就是了)
換個例子看看,這次是溫度
再看一個例子,這次是風場
用箭頭(風向風速)疊contourf(風速)
--------------------------------------------------------------------------------
接下來是看要怎麼樣清除圖上已經畫的資料
因為常常會遇到一種情況,就是需要畫非常多不同但是類似的圖
比方說同樣畫降雨,但是要把0~60個時間的降雨畫出來,所以共61張圖這樣
那最簡單的作法就是直接寫個迴圈
每一張圖就重畫一次
但是這樣其實蠻浪費時間的
畢竟每跑一次就要重新畫地圖、海岸線、格線之類的
偏偏這些東西其實每張圖都是一樣的,但是卻要一直重畫
所以如果想要把已經畫的資料清掉
可以利用ax.collections.clear()去清掉
ax.collections是一個list,包含了當下圖上已畫出來的東西
像是這樣
以這個前面畫風速的為例子
這個colletions包含了10個已經畫出來的東西
前7個都是contourf相關的
第8個是quiver
後面兩個則是x和y方向的格線
所以如果利用ax.collections.clear()
這整個list會被清空
所以像contourf、quiver之類的也會從圖上消失
但是像地圖、海岸線等等都還會留著
像是這樣
清掉之後就像這樣
原本的contourf都不見了
所以如果要畫各個時間的圖
就不需要一直全部重畫了
只需要最開始先畫完地圖、海岸線等等
之後每畫完一次資料就清掉,一直重複到結束就可以了
最後比較一下
如果用原本的方式,畫完一張就關掉再全部重畫一次 (作法1)
或是用ax.collections.clear()的方式清掉資料 (作法2)
這兩種方法的速度會差多少
可以看到一直重畫的做法1,需要31秒來畫61張圖
相較之下,利用ax.collections.clear()來處理,則只需要18.9秒
這個差距在圖的內容更多、圖片張數更多,或是更精細時會差更多
-------
整體來說
cartopy的使用上有比basemap更簡潔一點
而且執行效率也明顯比較高
不過cartopy看起來還是有缺一些東西
但是之後basemap的開發改成去做cartopy
應該還是會越來越完整的