python用cartopy包画地图_python绘制地图的利器Cartopy使用说明
python繪制地圖一般使用Basemap繪圖包,但該包配置相對較繁瑣,自定義性不強,這里介紹一個繪制地圖的利器Cartopy,個人認為該工具方便、快捷,附上一些自己寫的程序。
準備工作,工欲善其事,必先利其器
(1)先下載主角:Cartopy
a)下載地址:
linux平臺直接去官網下載:http://scitools.org.uk/cartopy/download.html
windows平臺下的Cartopy下載地址:
http://www.lfd.uci.edu/~gohlke/pythonlibs/#cartopy
還需要一些必須的軟件包:Shapely、pyshp也都從上面的網址下載
官網自帶的示例網址:
http://scitools.org.uk/cartopy/docs/latest/gallery.html
b)Cartopy下載安裝完畢后,打開python,輸入以下代碼:
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
plt.figure(figsize=(6, 3))
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
ax.coastlines(resolution=’110m’)
ax.gridlines()
復制代碼 運行后,如果順利導入了cartopy包,不管有沒有出現地圖,都不要緊,第二步走起。
(2)再下載配角:地圖數據
下載地址:http://www.naturalearthdata.com/downloads/
里面有三種分辨率的shape地圖數據可選,方便起見,分別下載三種分辨率中的physical數據中的Coastline和Land數據,每種數據下載后都是一個壓縮包,如下載了1:10分辨率的physical中的coastline數據壓縮包:ne_10m_coastline.zip,解壓縮后有6個文件,其中“ne_10m_coastline.README”和“ne_10m_coastline.VERSION”可直接刪除,剩余4個,進行改名操作,擴展名前面的文件名,如“ne_10m_coastline”,修改為“10m_coastline”,即去掉“ne_”,4個文件分別這樣更改。再下載1:50和1:110的文件分別進行此操作。所有地圖文件下載、解壓、更名完畢后,拷貝到一個文件夾下。我的文件夾列表如下圖,把這些文件全選(注意進入文件夾目錄,全選文件,不帶文件夾),復制粘貼到D:\Program Files\WinPython-32bit-2.7.9.3\settings\.local\share\cartopy\shapefiles\natural_earth\physical 目錄下(該目錄根據自己所裝的python而定,運行(1)中的程序后,程序會自動創建physical文件夾,具體該文件夾在哪,搜索電腦文件找找看),我安裝的是winpython2.7.9.3,physical目錄就位于上面這個目錄中,所以我把所有shape地圖文件拷貝到了該physical目錄下。
地圖文件列表.jpg (40.09 KB, 下載次數: 3)
地圖書文件列表
2015-3-25 19:40 上傳
準備工作完成后,進入正題:
(3)繪制地圖
前面兩步雖有些繁瑣,但會一勞永逸,下面是示例程序,scale參數用于調整使用哪種分辨率的地圖,全球建議用1:110的,小區域可以用1:50的或1:10的。
a)繪制全球地圖程序:
#===================================================
#使用cartopy繪制地圖
#需要從http://www.naturalearthdata.com/downloads/下載shape文件
#下載后,解壓縮,文件名統一去掉”ne_”開頭,拷貝至D:\Program Files\
#WinPython-32bit-2.7.9.3\settings\.local\share\cartopy\shapefiles\natural_earth\physical\
#路徑下面,coastline文件對應ax.coastlines命令,land文件對應land命令
#===================================================
scale=’110m’
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
fig=plt.figure(figsize=(8, 10))
ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
ax.set_global()
#===================================================
#需要填充陸地顏色時使用
#ax.add_feature(cfeature.LAND, facecolor=’0.75′) #默認為110m,其它分辨率需用下面命令
land = cfeature.NaturalEarthFeature(‘physical’, ‘land’, scale,edgecolor=’face’,
facecolor=cfeature.COLORS[‘land’])
ax.add_feature(land, facecolor=’0.75′)
#===================================================
#改變ax.add_feature和ax.coastlines的先后使用順序可實現邊界線的顯示或完全填充覆蓋
ax.coastlines(scale)
#===================================================
#標注坐標軸
ax.set_xticks([0, 60, 120, 180, 240, 300, 360], crs=ccrs.PlateCarree())
ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())
#zero_direction_label用來設置經度的0度加不加E和W
lon_formatter = LongitudeFormatter(zero_direction_label=False)
lat_formatter = LatitudeFormatter()
ax.xaxis.set_major_formatter(lon_formatter)
ax.yaxis.set_major_formatter(lat_formatter)
#添加網格線
gl = ax.gridlines()
復制代碼
地圖1.png (49.05 KB, 下載次數: 5)
2015-3-25 19:54 上傳
b)繪制全球地圖(函數形式)
#===================================================
#函數形式,調用cartopy,繪制全球地圖
#===================================================
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
def make_map(scale):
fig=plt.figure(figsize=(8, 10))
ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
ax.set_global()
land = cfeature.NaturalEarthFeature(‘physical’, ‘land’, scale,edgecolor=’face’,
facecolor=cfeature.COLORS[‘land’])
ax.add_feature(land, facecolor=’0.75′)
ax.coastlines(scale)
#標注坐標軸
ax.set_xticks([0, 60, 120, 180, 240, 300, 360], crs=ccrs.PlateCarree())
ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())
#zero_direction_label用來設置經度的0度加不加E和W
lon_formatter = LongitudeFormatter(zero_direction_label=False)
lat_formatter = LatitudeFormatter()
ax.xaxis.set_major_formatter(lon_formatter)
ax.yaxis.set_major_formatter(lat_formatter)
#添加網格線
#gl = ax.gridlines()
ax.grid()
return fig,ax
fig,ax=make_map(scale=’110m’)
復制代碼 此程序結果與上面一樣。
c)繪制區域地圖(函數形式)
#===================================================
#函數形式,調用cartopy,繪制區域地圖
#===================================================
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
def make_map(scale,box,xstep,ystep):
fig=plt.figure(figsize=(8, 10))
ax=plt.axes(projection=ccrs.PlateCarree())
#set_extent需要配置相應的crs,否則出來的地圖范圍不準確
ax.set_extent(box,crs=ccrs.PlateCarree())
land = cfeature.NaturalEarthFeature(‘physical’, ‘land’, scale,edgecolor=’face’,
facecolor=cfeature.COLORS[‘land’])
ax.add_feature(land, facecolor=’0.75′)
ax.coastlines(scale)
#===================================================
#圖像地址D:\Program Files\WinPython-32bit-2.7.9.3\python-2.7.9\Lib\site-packages\
#cartopy\data\raster\natural_earth\50-natural-earth-1-downsampled.png
#如果有其它高精度圖像文件,改名替換即可
ax.stock_img()
#===================================================
#標注坐標軸
ax.set_xticks(np.arange(box[0],box[1]+xstep,xstep), crs=ccrs.PlateCarree())
ax.set_yticks(np.arange(box[2],box[3]+ystep,ystep), crs=ccrs.PlateCarree())
#zero_direction_label用來設置經度的0度加不加E和W
lon_formatter = LongitudeFormatter(zero_direction_label=False)
lat_formatter = LatitudeFormatter()
ax.xaxis.set_major_formatter(lon_formatter)
ax.yaxis.set_major_formatter(lat_formatter)
#添加網格線
ax.grid()
return fig,ax
box=[100,150,0,50]
fig,ax=make_map(scale=’50m’,box=box,xstep=10,ystep=10)
復制代碼
地圖2.png (149.94 KB, 下載次數: 2)
2015-3-25 19:57 上傳
(4)繪制極地投影地圖
繪制該地圖需要使用最新版的cartopy-0.12版本,windows下暫無此版本,可以安裝好0.11后,刪除cartopy安裝目錄下的mpl文件夾下的全部文件,然后拷貝0.12目錄cartopy-0.12.0rc1\lib\cartopy\mpl文件夾下的全部文件進行替換,即可使用新版的功能。此程序長了點,因為Cartopy對極坐標投影沒有自動標注經緯度功能,需要自己設置,調了好久標注位置,請大家切用且珍惜哈。
import matplotlib.path as mpath
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.ticker as mticker
import cartopy.crs as ccrs
import cartopy.feature as cfeature
fig=plt.figure(figsize=(6, 6))
ax=plt.axes(projection=ccrs.NorthPolarStereo())
box=[-180, 180, 55, 90]
xstep,ystep=30,15
# Limit the map to -60 degrees latitude and below.
ax.set_extent(box, crs=ccrs.PlateCarree())
scale=’50m’
land = cfeature.NaturalEarthFeature(‘physical’, ‘land’, scale,edgecolor=’face’,
facecolor=cfeature.COLORS[‘land’])
ocean = cfeature.NaturalEarthFeature(‘physical’, ‘ocean’, scale,edgecolor=’face’,
facecolor=cfeature.COLORS[‘water’])
ax.add_feature(land,facecolor=’0.75′)
ax.add_feature(ocean,facecolor=’blue’)
ax.coastlines(scale,linewidth=0.9)
#標注坐標軸
line=ax.gridlines(draw_labels=False)
line.ylocator=mticker.FixedLocator(np.arange(40,90,20))#手動設置x軸刻度
line.xlocator=mticker.FixedLocator(np.arange(-180,210,30))#手動設置x軸刻度
# Compute a circle in axes coordinates, which we can use as a boundary
# for the map. We can pan/zoom as much as we like – the boundary will be
# permanently circular.
theta = np.linspace(0, 2*np.pi, 100)
center, radius = [0.5, 0.5], 0.5
verts = np.vstack([np.sin(theta), np.cos(theta)]).T
circle = mpath.Path(verts * radius + center)
ax.set_boundary(circle, transform=ax.transAxes)
#創建要標注的labels字符串
ticks=np.arange(0,210,30)
etick=[‘0’]+[‘%d$^\circ$E’%tick for tick in ticks if (tick !=0) & (tick!=180)]+[‘180’]
wtick=[‘%d$^\circ$W’%tick for tick in ticks if (tick !=0) & (tick!=180)]
labels=etick+wtick
#創建與labels對應的經緯度標注位置
#xticks=[i for i in np.arange(0,210,30)]+[i for i in np.arange(-32,-180,-30)]
xticks=[-0.8,28,58,89.1,120,151,182.9,-36,-63,-89,-114,-140]
yticks=[53]+[53]+[54]+[55]*2+[54.5]+[54]+[50]+[49]*3+[50.6]
#標注經緯度
#ax.text(0.01,0.23,’60$^\circ$W’,transform=ax.transAxes,rotation=25)
#ax.text(-63,50,’60$^\circ$W’,transform=ccrs.Geodetic(),rotation=25)
for xtick,ytick,label in zip(xticks,yticks,labels):
ax.text(xtick,ytick,label,transform=ccrs.Geodetic())
x=[180, 180, 0, 0]
y=[50, 90, 90, 50]
ax.plot([-180,0],[80,80],’:’,transform=ccrs.Geodetic(),color=’k’,linewidth=0.4)
ax.plot([-90,90],[80,80],’:’,transform=ccrs.Geodetic(),color=’k’,linewidth=0.5)
#ax.plot([90,0],[50,50],’-.’,transform=ccrs.Geodetic(),color=’r’,linewidth=6)
ax.text(11.9333,78.9166,r’$\bigstar,transform=ccrs.Geodetic(),size=15,color=’r’)
fig.savefig(u’c:\\北極.png’,dpi=300)
復制代碼
北極地圖.png (64.49 KB, 下載次數: 3)
北極投影地圖
2015-3-25 20:24 上傳
注:如果想使用自己的地圖,比如我有一個帶我國法定邊界的地圖shape文件,名為:World.shp、World.shx、World.dbf、World.prj,重新命名為10m_coastline或10m_land文件(這里要根據該shape文件是line型還是polygon型),替換原目錄下的shape文件,畫圖時使用scale為10m即調用到了自己的地圖,不用擔心邊界不準確了。
不知道為什么最后多出來一張圖片,麻煩版主幫忙刪了吧。
總結
以上是生活随笔為你收集整理的python用cartopy包画地图_python绘制地图的利器Cartopy使用说明的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android12华为,谷歌“神助攻”!
- 下一篇: 【区块链】开源社区发力区块链,超级账本会