- U& V/ C0 |" e 文章目录前言一、基础介绍二、区域地图的绘制总结前言
: N3 g1 F/ w, x2 { 常用地图底图的绘制一般由Basemap或者cartopy模块完成,由于Basemap库是基于python2开发的一个模块,目前已经不开发维护。故简单介绍cartopy模块的一些基础操作。 % u% Z' E6 c% i- @: i5 _1 Z; t
, j4 R' I/ Z/ J, I+ `! G 如果大家在学习中遇到困难,想找一个python学习交流环境,可以加入我们的python裙,关注小编,并私信“01”即可进裙,领取python学习资料,会节约很多时间,减少很多遇到的难题。 / M3 X- L$ T }3 Q, n' N
一、基础介绍
- y! d$ L F8 }# P& v) | 首先导入相关模块。 import numpy as np3 {& l+ d& U) v1 e
import matplotlib.pyplot as plt9 E# f: n" A7 R( K# M
import cartopy.crs as ccrs) m% A+ A; ~$ P- Z) m
import cartopy.feature as cfeature
* S5 c# V0 S! m from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
7 s5 C; {/ F5 D, b! \6 G! T' j 123458 A |- k8 u1 z- {" z$ @
首先介绍参数projection,该命令可以配合ccrs设置投影类型,此处以方形投影命令为示例。其中central_longitude参数为投影中心位置。其中心设置与Basemap设置规则一样,详情可以看上一篇文章。 ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=0))
. }! C/ r- h$ X4 z- u 1在设置好绘制类型后,绘制地图各特征量。其代码如下: #ax.add_feature(cfeature.LAKES.with_scale(scale))
* o; o1 @: l' T+ [ ax.add_feature(cfeature.OCEAN.with_scale(scale))
& s1 M9 V- T! ^ #ax.add_feature(cfeature.RIVERS.with_scale(scale))
8 J. _3 ]& Y& [& b. L$ c #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)
+ V; f+ T/ ?3 F& \. a ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)
+ O6 C3 e# T+ Q3 v3 F 12345
9 z1 F& @3 P7 C; a9 w; C5 s 参数scale为地图分辨率,目前支持10m,50m,110m,参数lw为线条粗细。此处绘制海岸线和海洋,效果图如下:
/ A4 B0 S9 d5 M4 K% t! Q- z( c. R; _7 n* N7 ]# V
7 @9 I8 w, D" a5 u; k' V) g5 F( q 在绘制结束后,作为地图。经纬度自然是必不可少的,在该模块中,引进同时设置坐标轴标签改变该标签刻度的表示,具体形式如下: ax.set_xticks(np.arange(0,361,40), crs=ccrs.PlateCarree())
C" Z7 i5 `$ P! Z! ] ax.set_yticks(np.arange(-90,90+30,30), crs=ccrs.PlateCarree())
" w, _# y1 U* P# ?7 A #zero_direction_label用来设置经度的0度加不加E和W: t) ^8 c0 d& r9 l5 h' k9 C* {$ @2 }
lon_formatter = LongitudeFormatter(zero_direction_label=False)& e9 I1 \7 p& J, @) n: D. ?8 l
lat_formatter = LatitudeFormatter()9 c9 g \$ r3 t8 g
ax.xaxis.set_major_formatter(lon_formatter)1 ~2 C" w9 N5 A* h6 u' w+ R
ax.yaxis.set_major_formatter(lat_formatter)$ h/ v6 t# q! m1 k& E/ \2 {2 E+ z2 |
1234567可以看到效果图如下:
0 g/ W! x0 O2 I. K6 F2 K* X! F1 b- t T& j# [) a0 \
0 _+ R- I6 ^) U( p) d1 c 当然如果想对坐标轴粗细变化可以引入一下命令。 ax.outline_patch.set_visible(False). f( O4 y* e7 c
ax.spines[bottom].set_visible(True)
. ?; Z& g7 ~! I7 o/ _2 S, q ax.spines[left].set_visible(True)
9 R7 m2 L" N& p ax.spines[right].set_visible(True)
' ^7 h+ F& s# Y' o @; w' t ax.spines[top].set_visible(True)8 M! x3 ]9 m8 p6 }
ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
6 ?- T* K( n/ g8 g& O ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细3 R; j) T* a/ i& Q @" g8 ~
ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细
* K" _3 s1 U+ j# J1 D$ f. Y ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
( }0 M O8 b3 d. [3 B) F5 A9 c/ V! E; ]4 d3 P
12345678910应该在该模块下,控制坐标轴的命令已经和常规不一样。因此先关闭该控制,然后开启常规坐标轴设置。
2 h6 O% c; ~4 Z. o: L 二、区域地图的绘制/ `; H w5 a# H+ N7 j$ D+ a \, _& S) h
当我们在某一小块区域研究时,需要绘制区域地图。此时我们可以引入命令: ax.set_extent(box,crs=ccrs.PlateCarree())
. I1 `: D4 [1 M6 S* ~3 ?0 m 1$ |4 l. h p1 r& W4 H" J; y N
其中box为绘制区域,crs为投影类型。其他命令基本不变。设置box为[40,180,0,90],可得到效果图如下: ; H7 W' Z+ {" j# I4 S
. {1 e$ W4 i7 p! x, S5 Q. p- Z
; m, Y. Y- H1 T9 A3 M- I- x- A 总结
- S4 l7 W; |: _0 d# _- J: V 为方便各位读者,我书写了绘制地图的函数,大家在使用时可直接调用。此处示例为方形投影,若希望绘制其他投影。只需要修改函数部分参数即可。代码如下: def map_make(scale,box,xstep,ystep):
: Z6 U ~; E4 v& B% j" @ ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=180))" d/ z; J' G0 W$ {* s
a = (box[1]-box[0])//xstep3 G" O9 |, E" ]+ Q5 w9 k3 E7 {* o
x_start = box[1] - a*xstep
; m5 `/ B2 c3 Z& g, K a = (box[3]-box[2])//ystep
0 K6 V: L, O0 ^ G8 ~ y_start = box[3] - a*ystep% D2 D! t; C( s
ax.set_extent(box,crs=ccrs.PlateCarree())& E# T' D& G& p9 E, R8 V
#ax.add_feature(cfeature.LAKES.with_scale(scale))
$ B5 D" A! Z. U- A2 ~- f #ax.add_feature(cfeature.OCEAN.with_scale(scale))
+ K3 x% F/ f. v3 I- |0 f" X #ax.add_feature(cfeature.RIVERS.with_scale(scale))( H! J$ [3 a* y. R: ?! ]
#ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)5 p& s: ]& x$ ?& R% S
ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)3 e) P9 s/ q. r/ u1 J$ X! k2 C( @
! ~1 [" ~3 ^0 i& J ax.set_xticks(np.arange(x_start,box[1]+xstep,xstep), crs=ccrs.PlateCarree())
0 v! |6 o: D* s7 J! m8 @' z ax.set_yticks(np.arange(y_start,box[3]+ystep,ystep), crs=ccrs.PlateCarree())
5 L4 {& Y( H8 d) V, E) z #zero_direction_label用来设置经度的0度加不加E和W
v! P5 p( C$ c! \. P9 @* t. [ lon_formatter = LongitudeFormatter(zero_direction_label=False)
7 N2 {6 d1 `5 I$ p1 T K lat_formatter = LatitudeFormatter() k% [5 Q/ k& b4 w, w
ax.xaxis.set_major_formatter(lon_formatter)& o6 g) L9 D) C" [8 F) L! R t! S9 _
ax.yaxis.set_major_formatter(lat_formatter)
: }; `* H/ A8 a# z" I! d #添加网格线( V4 O7 ~8 c$ I
ax.grid()
# E- |, d$ n- o a. R3 o1 {, _3 f
4 |- a L& D& M0 ~$ V8 ~ ax.outline_patch.set_visible(False)
* P- a9 ~2 L. \( v: B1 d ax.spines[bottom].set_visible(True)! U' l* \ u# |5 Y
ax.spines[left].set_visible(True)# K+ B4 S. p1 ~* F# v6 U0 H
ax.spines[right].set_visible(True); Z& H3 D% ?6 A1 s0 f$ ^
ax.spines[top].set_visible(True)
# l# E5 \; L( }& z0 p ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
/ H2 \3 r* v# k/ @' ^+ j/ y2 M ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细# d8 R. C* A, k, ~5 b% Q( t2 u6 F* y
ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细( L8 ~4 b( ]3 e! ^ F4 I: w: w
ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
. k0 W5 j( j! h( o3 d) ~0 n# D7 I' |/ ]' q; y( `0 ]
return ax最后多说一句,想学习Python可联系阿喵,这里有我自己整理的整套python学习资料和路线,想要这些资料的都可以关注阿喵,并私信“01”领取。 2 V6 H2 n6 e$ N- |$ f: X
& U2 M. m8 I) M) v% C
$ P* O, n1 n1 n% O
# G3 y5 `2 i5 @* s) @- ~
$ b0 {: z& y, f0 \
|