2 [, f- m5 M0 J: Y
文章目录前言一、基础介绍二、区域地图的绘制总结前言( @ T. `9 G/ a: s1 o( h/ l
常用地图底图的绘制一般由Basemap或者cartopy模块完成,由于Basemap库是基于python2开发的一个模块,目前已经不开发维护。故简单介绍cartopy模块的一些基础操作。 / u! I$ _; b- Q
! ]6 r, U; _& A: q8 F) q. j$ z) d `
如果大家在学习中遇到困难,想找一个python学习交流环境,可以加入我们的python裙,关注小编,并私信“01”即可进裙,领取python学习资料,会节约很多时间,减少很多遇到的难题。 / ^6 R; D; ?- L
一、基础介绍; E& b, K% |6 O4 z
首先导入相关模块。 import numpy as np
) l; X, M* k, _ import matplotlib.pyplot as plt
8 P+ B+ X6 B5 u import cartopy.crs as ccrs5 y* p3 _) G& j# X0 J
import cartopy.feature as cfeature
: s6 v) I) n! g- N; K' @: y from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
# Y9 o& `& s6 R% y) M 12345
% g# c$ z3 ^$ {! B# T7 ~6 h* ? 首先介绍参数projection,该命令可以配合ccrs设置投影类型,此处以方形投影命令为示例。其中central_longitude参数为投影中心位置。其中心设置与Basemap设置规则一样,详情可以看上一篇文章。 ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=0))$ d& A8 \2 r$ a- A; A) Q
1在设置好绘制类型后,绘制地图各特征量。其代码如下: #ax.add_feature(cfeature.LAKES.with_scale(scale))
' [$ y1 a' L' u. d! d5 I: u( I ax.add_feature(cfeature.OCEAN.with_scale(scale))6 c0 t( h5 ~0 H. H
#ax.add_feature(cfeature.RIVERS.with_scale(scale))- e5 K# [& ?9 b8 `0 y
#ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)4 k1 |+ L) L4 G4 U0 ?0 z
ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)
' P! X+ ?2 ^( D8 R 12345
- [; U3 B* y1 K; R' D7 T3 L5 ~) r 参数scale为地图分辨率,目前支持10m,50m,110m,参数lw为线条粗细。此处绘制海岸线和海洋,效果图如下: , v7 T: n7 K. Z: H. S' M7 J3 I
5 \* O; d! K# ?1 b2 _( K3 `
1 y/ b" }# h: j
在绘制结束后,作为地图。经纬度自然是必不可少的,在该模块中,引进同时设置坐标轴标签改变该标签刻度的表示,具体形式如下: ax.set_xticks(np.arange(0,361,40), crs=ccrs.PlateCarree())3 A4 w8 X( H2 a! S# [" y
ax.set_yticks(np.arange(-90,90+30,30), crs=ccrs.PlateCarree())
: C# I7 w2 a- C #zero_direction_label用来设置经度的0度加不加E和W2 x" E; j) T. _$ n* K \" p
lon_formatter = LongitudeFormatter(zero_direction_label=False). y& a: I9 f# o( L- l
lat_formatter = LatitudeFormatter()& o+ i1 s3 g& P7 Z" Y- `: Y
ax.xaxis.set_major_formatter(lon_formatter)
2 w' R) I. l3 X- \7 W Z ax.yaxis.set_major_formatter(lat_formatter)
3 K0 ^% x* y( ? 1234567可以看到效果图如下: 4 M+ b# N% h0 M9 S* f, k h$ ~. j7 S
* ]4 G- o3 M7 u
1 Z7 T/ n0 q1 Q- {+ x7 Q; r- T 当然如果想对坐标轴粗细变化可以引入一下命令。 ax.outline_patch.set_visible(False): z f1 b2 X& Z% z2 w" }8 E! d
ax.spines[bottom].set_visible(True)0 a7 h- k' `7 @. [8 U
ax.spines[left].set_visible(True)
0 j$ p9 R7 U/ Z( [% u2 |6 g2 V ax.spines[right].set_visible(True), c6 U- i- A) ^" `+ ?1 a5 L
ax.spines[top].set_visible(True)
! A _' k: {9 y/ ~3 V' Y ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细5 U/ K+ ~$ b6 R$ Z6 g5 X
ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细
1 E" U, V# ], c* d' M! n ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细
8 a' B( Y0 K/ P' g O' X) K ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细& V+ p2 R( A9 }3 J& q3 }
! y1 i; l; A) S0 m) Y3 b 12345678910应该在该模块下,控制坐标轴的命令已经和常规不一样。因此先关闭该控制,然后开启常规坐标轴设置。
- [" P1 P1 Y z 二、区域地图的绘制5 W5 X4 @; e1 C. J, \: a
当我们在某一小块区域研究时,需要绘制区域地图。此时我们可以引入命令: ax.set_extent(box,crs=ccrs.PlateCarree())
7 C' F. U, e' }! }% J$ R 1
9 ?7 `4 ^& [/ x' F& y# e# _ 其中box为绘制区域,crs为投影类型。其他命令基本不变。设置box为[40,180,0,90],可得到效果图如下: ' t( X& A0 P: ~7 H8 r$ |5 E& k
/ Z& G* h( t: l" w/ d! W
; g: q/ [4 @, g) g& p/ p 总结
( `& i9 \7 h# U' n% a2 \ 为方便各位读者,我书写了绘制地图的函数,大家在使用时可直接调用。此处示例为方形投影,若希望绘制其他投影。只需要修改函数部分参数即可。代码如下: def map_make(scale,box,xstep,ystep):
+ W7 g) L' l0 Z! A8 T ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=180))% [; d9 M1 L! w2 b. O, b
a = (box[1]-box[0])//xstep
# w* o' h# N/ U. y) K. z x_start = box[1] - a*xstep
! ?) b0 i" B9 J3 H6 _3 A. a a = (box[3]-box[2])//ystep
5 r2 I' T D- V5 W# @) } y_start = box[3] - a*ystep, O1 {2 P; x/ S3 l( u' I: d
ax.set_extent(box,crs=ccrs.PlateCarree())
5 S; U% n; _9 |3 X1 Q #ax.add_feature(cfeature.LAKES.with_scale(scale))
/ g7 W8 S! [5 |- A #ax.add_feature(cfeature.OCEAN.with_scale(scale))! e& f5 @, ]0 ^7 G5 P) w
#ax.add_feature(cfeature.RIVERS.with_scale(scale))" N8 m% g1 \; V
#ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)
& t7 E5 x' I' S+ y' \ ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)
* d- R3 C. ^8 c8 @. ?5 F3 e7 d
2 D4 v; q# P" e2 |1 Z# z/ f: a ax.set_xticks(np.arange(x_start,box[1]+xstep,xstep), crs=ccrs.PlateCarree())
# v3 J7 X( {0 g: d, G# F% o ax.set_yticks(np.arange(y_start,box[3]+ystep,ystep), crs=ccrs.PlateCarree())
; h& B2 I* {9 P" B$ g #zero_direction_label用来设置经度的0度加不加E和W
. d4 ~8 k/ x8 r. d5 A! R lon_formatter = LongitudeFormatter(zero_direction_label=False)
$ _ y9 ]; k0 V* Q lat_formatter = LatitudeFormatter()# @: D9 a& M% j$ P ^; z) n
ax.xaxis.set_major_formatter(lon_formatter)
* l% I8 g/ g; { ax.yaxis.set_major_formatter(lat_formatter)4 ^" W3 `. `* u6 p; C0 T
#添加网格线, R/ l. F' w7 o& z
ax.grid()+ d8 w) q. u% U7 X8 \' L F x" l
- w5 F+ B# g3 O# S" U ax.outline_patch.set_visible(False)3 `# R4 U' w0 g$ S0 C3 L& ]0 n
ax.spines[bottom].set_visible(True)
* u0 I6 k& n. Y6 H+ ~2 q/ d ax.spines[left].set_visible(True)+ G3 N* Q; F1 B5 Y6 M- ^5 s; b
ax.spines[right].set_visible(True). z5 ~# ]$ Z7 r2 ^" a
ax.spines[top].set_visible(True)9 E" U/ ~" z4 U6 K" x& p
ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
. w" a+ V, E7 @/ h% G2 O ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细% p% S' R; ^; o7 E5 A; N; d
ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细
% \7 a; c4 v3 B) _: q ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
: b* t$ m. J# e) w7 v# U* k
7 k; q4 g8 f) D" I$ M: i8 m return ax最后多说一句,想学习Python可联系阿喵,这里有我自己整理的整套python学习资料和路线,想要这些资料的都可以关注阿喵,并私信“01”领取。
1 R9 \- K) i; l! Q2 z& @
6 O& [+ B4 H; M8 c( E. F) Z; [/ q, h" ?
9 B0 M6 y; L: v) Y% L
/ x4 w5 r- k. T5 F( n" O |