' `. T2 o; a( z
文章目录前言一、基础介绍二、区域地图的绘制总结前言
4 f# D0 s: N' v7 a. v 常用地图底图的绘制一般由Basemap或者cartopy模块完成,由于Basemap库是基于python2开发的一个模块,目前已经不开发维护。故简单介绍cartopy模块的一些基础操作。 ' u/ X& ~+ _: y" H# z, O: {- \! x
/ @7 N# ^$ v; T7 A+ I5 A4 M Q! _ 如果大家在学习中遇到困难,想找一个python学习交流环境,可以加入我们的python裙,关注小编,并私信“01”即可进裙,领取python学习资料,会节约很多时间,减少很多遇到的难题。 ; r2 x+ M, C! a7 S% o9 b
一、基础介绍& e5 P) K: i% T
首先导入相关模块。 import numpy as np
* [2 x4 g/ V5 b; a5 k' \* ~6 l import matplotlib.pyplot as plt
9 n# S1 G1 F: O f: c1 c- U import cartopy.crs as ccrs
* g; V- H7 B4 l/ }& D import cartopy.feature as cfeature
7 l4 R$ h! _4 t, y from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter2 e0 y: _, @6 S& V. d& C
12345% \# X$ e+ x& z/ K) B
首先介绍参数projection,该命令可以配合ccrs设置投影类型,此处以方形投影命令为示例。其中central_longitude参数为投影中心位置。其中心设置与Basemap设置规则一样,详情可以看上一篇文章。 ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=0))* A0 f! p) I8 e$ @) q- q
1在设置好绘制类型后,绘制地图各特征量。其代码如下: #ax.add_feature(cfeature.LAKES.with_scale(scale))
' s) c( w3 J7 w8 {8 S8 v ax.add_feature(cfeature.OCEAN.with_scale(scale))2 V' y: K6 ^5 T; }4 Z
#ax.add_feature(cfeature.RIVERS.with_scale(scale))
/ s8 r2 [ t( Y #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)' ]% z( H1 a6 c: @- v) l( [1 O
ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)$ W2 f1 f* S4 @& }& u; ?! }' y/ c L
12345
1 G+ p! N/ c/ e: `# ~% V' i$ a1 D 参数scale为地图分辨率,目前支持10m,50m,110m,参数lw为线条粗细。此处绘制海岸线和海洋,效果图如下: + ?0 g/ i( i( x' i) i7 X" ^
9 U3 ]6 }8 J" {, q* t: @9 h # I) x& q- \7 K
在绘制结束后,作为地图。经纬度自然是必不可少的,在该模块中,引进同时设置坐标轴标签改变该标签刻度的表示,具体形式如下: ax.set_xticks(np.arange(0,361,40), crs=ccrs.PlateCarree())
& t" j: x. s! C2 [8 ` ax.set_yticks(np.arange(-90,90+30,30), crs=ccrs.PlateCarree())/ {% T$ @( o! V' ? p4 P
#zero_direction_label用来设置经度的0度加不加E和W
9 W1 y% T9 h+ F; l- R lon_formatter = LongitudeFormatter(zero_direction_label=False)
5 B* R Z+ x8 J0 }5 h! Y lat_formatter = LatitudeFormatter()
; O! p% ?; l0 S$ L, b; M w* M, h ax.xaxis.set_major_formatter(lon_formatter)2 Y" X; t4 [1 b, S; h
ax.yaxis.set_major_formatter(lat_formatter)6 u. w' |# o: h" P# R5 [' Z
1234567可以看到效果图如下:
2 a7 e0 E& X H6 h$ Z7 ~: t6 a$ [3 ]: O. ^
& B& p' |% t+ K1 Z$ a- R
当然如果想对坐标轴粗细变化可以引入一下命令。 ax.outline_patch.set_visible(False): v7 c( h2 n3 l* ~6 o7 w
ax.spines[bottom].set_visible(True)6 v9 m2 N7 R- l+ V$ ?( \ y
ax.spines[left].set_visible(True)- w, E3 r! u1 L1 W, w/ S
ax.spines[right].set_visible(True): H) Z5 u. H7 M7 P. m! G
ax.spines[top].set_visible(True)
! D0 m; p# A4 z9 A" ^% k' h' z% ` ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
2 L" H9 m* m0 ^ }9 i- D ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细( g% b' U! Y. B: D, v- W
ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细
3 ^3 B1 ~5 r* K ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
. i' j( k% f3 A3 G
/ |3 j5 F2 X: Z3 x9 s 12345678910应该在该模块下,控制坐标轴的命令已经和常规不一样。因此先关闭该控制,然后开启常规坐标轴设置。
" M6 ^# c% P* S4 B* w7 Z" K* @' o 二、区域地图的绘制
7 c( Z: X4 t$ }0 B7 p 当我们在某一小块区域研究时,需要绘制区域地图。此时我们可以引入命令: ax.set_extent(box,crs=ccrs.PlateCarree())% o0 Y5 C6 j# S }# v) H. F
19 s7 y8 O& `+ @) D \
其中box为绘制区域,crs为投影类型。其他命令基本不变。设置box为[40,180,0,90],可得到效果图如下:
& z6 e7 O6 }% H, w: W( Z, v1 c$ L+ B# q6 W6 T, P6 D+ }
$ O( i7 R( K A1 d- c( P# P1 ]
总结
( `5 k: L, k9 t' @) W+ A- m* O! A 为方便各位读者,我书写了绘制地图的函数,大家在使用时可直接调用。此处示例为方形投影,若希望绘制其他投影。只需要修改函数部分参数即可。代码如下: def map_make(scale,box,xstep,ystep):
. O ~$ b' |' i% z0 v" D; \ B ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
' T. P" Z4 o2 e# U' w- k2 F a = (box[1]-box[0])//xstep
' |. Y& B) E9 N7 P, p+ ]$ p9 J x_start = box[1] - a*xstep5 ]( M1 Q! S2 r5 i2 H
a = (box[3]-box[2])//ystep
! v% L7 l7 F) ^ y_start = box[3] - a*ystep
4 B. \4 N1 E; i8 M H: o ax.set_extent(box,crs=ccrs.PlateCarree())3 L& K6 g2 k) `5 _ ~9 ^$ {
#ax.add_feature(cfeature.LAKES.with_scale(scale))
$ O/ G$ L7 a/ y) z2 f #ax.add_feature(cfeature.OCEAN.with_scale(scale))
2 s" a+ T' g/ @9 y# \ #ax.add_feature(cfeature.RIVERS.with_scale(scale))
. F8 {" n( s1 F+ Z4 y: M6 E1 N #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)' g' Y d) g% K2 ?. X6 L1 F
ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)
2 v# z: E, M' R4 s0 v: N( \2 j7 a0 Z
ax.set_xticks(np.arange(x_start,box[1]+xstep,xstep), crs=ccrs.PlateCarree())
7 P6 N' r g' O6 f/ M; m9 z ax.set_yticks(np.arange(y_start,box[3]+ystep,ystep), crs=ccrs.PlateCarree())
Q3 p b( h/ i #zero_direction_label用来设置经度的0度加不加E和W' S1 x) r7 f. K8 o J
lon_formatter = LongitudeFormatter(zero_direction_label=False)% E7 P1 i5 ~ r8 @( W9 F: i2 H
lat_formatter = LatitudeFormatter()* s* J( S3 m" t' {( F
ax.xaxis.set_major_formatter(lon_formatter)
b) ?4 K7 s% }3 H' n8 K6 E ax.yaxis.set_major_formatter(lat_formatter); H6 }$ S+ D, r9 w
#添加网格线, j/ G& a1 a) R( Z
ax.grid()9 E) g7 c* F0 Y9 v6 h
_+ e$ G, u j4 `9 l
ax.outline_patch.set_visible(False)
7 j' t8 b. h# d4 p7 u ax.spines[bottom].set_visible(True)
) C: e4 q; @$ o0 h) o ax.spines[left].set_visible(True)9 }# Z1 y( H* L( Q7 [
ax.spines[right].set_visible(True)2 a& r: X Q; } `4 [
ax.spines[top].set_visible(True) x6 u N# a: V! E; z$ }: e& M
ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
- ~+ Q7 i, _$ j2 } ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细2 p3 V! m7 P. e) s7 w! u
ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细
5 c+ ~) s @! T ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细4 k2 O6 e j! i- t3 B4 d$ r
7 n. a8 Z) A2 `+ k+ m0 |# w
return ax最后多说一句,想学习Python可联系阿喵,这里有我自己整理的整套python学习资料和路线,想要这些资料的都可以关注阿喵,并私信“01”领取。
' j, C$ i! S+ _! k* [3 r/ x _4 j O0 u9 T, o( u. ^$ d
* h4 C% F( ~& N5 V, e7 f$ f+ m
4 v: b0 [3 E2 ]$ A! Z2 D
) }4 i! D5 U. v2 b: ~9 }# i: s
|