- \0 T" O: I# g0 B6 `5 ^* a$ x
文章目录前言一、基础介绍二、区域地图的绘制总结前言
/ @" c6 q3 ? b8 R- A& h! T! N 常用地图底图的绘制一般由Basemap或者cartopy模块完成,由于Basemap库是基于python2开发的一个模块,目前已经不开发维护。故简单介绍cartopy模块的一些基础操作。 , u1 v6 | R0 P, e2 E
; [8 ?$ A% T+ ~# k) j
如果大家在学习中遇到困难,想找一个python学习交流环境,可以加入我们的python裙,关注小编,并私信“01”即可进裙,领取python学习资料,会节约很多时间,减少很多遇到的难题。 ! S- C# T9 A, Y! h9 K7 w9 s9 n
一、基础介绍
4 J" t* b9 O; x: j& d$ F/ O. T 首先导入相关模块。 import numpy as np7 A& F R3 s: R; f# w2 \- B
import matplotlib.pyplot as plt9 n V4 H' I& e2 p3 E3 A# t: i. i
import cartopy.crs as ccrs
% [( M; [% }& x0 w; K; f import cartopy.feature as cfeature$ m$ W* Z$ B5 l# t4 a/ h0 J
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
8 R6 ` a+ X, g. F* U 123455 q2 d: A' a% m7 W
首先介绍参数projection,该命令可以配合ccrs设置投影类型,此处以方形投影命令为示例。其中central_longitude参数为投影中心位置。其中心设置与Basemap设置规则一样,详情可以看上一篇文章。 ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=0))
1 b: f V% F: V. k# _ 1在设置好绘制类型后,绘制地图各特征量。其代码如下: #ax.add_feature(cfeature.LAKES.with_scale(scale))
) _2 ]+ Q; W3 x4 F6 p( P: L ax.add_feature(cfeature.OCEAN.with_scale(scale))
1 m7 n, K8 w" p #ax.add_feature(cfeature.RIVERS.with_scale(scale))
/ c) N( W# |6 E- @ #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)9 v' o1 f; D h; o5 ?; A) h( L
ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)3 O, L$ \. i7 h. K$ t1 |0 D
12345! ~% M2 d. h( q8 k
参数scale为地图分辨率,目前支持10m,50m,110m,参数lw为线条粗细。此处绘制海岸线和海洋,效果图如下: . I |3 o- V7 R3 |9 [6 e
! x4 L. j( [' V, K
5 E; L- l1 T/ q( @# M& z 在绘制结束后,作为地图。经纬度自然是必不可少的,在该模块中,引进同时设置坐标轴标签改变该标签刻度的表示,具体形式如下: ax.set_xticks(np.arange(0,361,40), crs=ccrs.PlateCarree())7 |) L. U2 W6 r! s) E/ x
ax.set_yticks(np.arange(-90,90+30,30), crs=ccrs.PlateCarree())
6 t/ f& K7 \0 m1 E& z) j #zero_direction_label用来设置经度的0度加不加E和W
: b% M0 g+ m) s4 b& C" z lon_formatter = LongitudeFormatter(zero_direction_label=False)
1 i+ b0 l0 U. J, F" R9 X lat_formatter = LatitudeFormatter()) X; P# b6 b$ M* s0 h
ax.xaxis.set_major_formatter(lon_formatter)# g0 _ x3 G) X( J; X
ax.yaxis.set_major_formatter(lat_formatter)
! j# f1 x5 c: b. j 1234567可以看到效果图如下:
5 H/ ^4 U$ f, z& c# T. K6 S6 P
3 N# a- u C5 t4 J& s/ M5 p
! f- V" M8 r! M" R" v0 S 当然如果想对坐标轴粗细变化可以引入一下命令。 ax.outline_patch.set_visible(False). I- I0 L7 ^8 u; ~) h
ax.spines[bottom].set_visible(True)# i1 E$ J1 \0 p2 e9 o$ L3 @ E
ax.spines[left].set_visible(True)/ f1 Y" K/ j5 r0 K6 C% A Z& X5 N
ax.spines[right].set_visible(True)
, y- R' R( `' H# G ax.spines[top].set_visible(True)
* W' f( ]& L5 [+ m& {+ t' m ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细! }& B% Y9 Z: H8 s0 ]& e
ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细
, y7 y/ J: u) M( @/ r2 P6 n ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细
: a! j+ T( B! Y ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
# _7 Y/ O# R( [5 A3 t8 D% e- v. k( ~9 _8 Y" J i
12345678910应该在该模块下,控制坐标轴的命令已经和常规不一样。因此先关闭该控制,然后开启常规坐标轴设置。
2 C: X/ A) @, Y4 J6 r$ } 二、区域地图的绘制
( o. O8 }0 w* U# S6 L4 `! y4 w) Q 当我们在某一小块区域研究时,需要绘制区域地图。此时我们可以引入命令: ax.set_extent(box,crs=ccrs.PlateCarree())7 Z, B8 e& I, J- `; ]
14 d6 t; h2 J7 C. D) h6 Q; l
其中box为绘制区域,crs为投影类型。其他命令基本不变。设置box为[40,180,0,90],可得到效果图如下: ( u. ~; J0 U% I, g6 r, l
7 f, R0 Q5 d% z2 u! R& m- a4 i
5 S4 D5 z" B# {* o; j! | 总结# ?4 s) W1 e) ?$ h; k1 s% y
为方便各位读者,我书写了绘制地图的函数,大家在使用时可直接调用。此处示例为方形投影,若希望绘制其他投影。只需要修改函数部分参数即可。代码如下: def map_make(scale,box,xstep,ystep):
" q2 L, Z5 }% I# }1 H, j ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
- y! [' `" T" H z+ D a = (box[1]-box[0])//xstep
+ Q# A# E" L1 O' a9 U+ E" f0 A x_start = box[1] - a*xstep) W* h" Y! z8 A0 `6 z. b2 z' @
a = (box[3]-box[2])//ystep
! c/ d- m) m1 B. p3 `& A y_start = box[3] - a*ystep) l0 l+ M z6 e( S4 M
ax.set_extent(box,crs=ccrs.PlateCarree())1 Q$ q7 e; ]+ \$ `
#ax.add_feature(cfeature.LAKES.with_scale(scale))
, J% l- [. c# n0 w2 @9 I5 m #ax.add_feature(cfeature.OCEAN.with_scale(scale))
6 ^* s5 ]7 ]6 R& g- K8 u$ E7 ~; A #ax.add_feature(cfeature.RIVERS.with_scale(scale)); s( m: u9 Z! T2 h' J
#ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)
2 _, @8 S( Q) S- _- e" i ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)- f: y+ s, ]% J
% b3 Z$ q* w# F7 f S ?! d
ax.set_xticks(np.arange(x_start,box[1]+xstep,xstep), crs=ccrs.PlateCarree())8 D/ m2 e7 o: b3 v$ L' p
ax.set_yticks(np.arange(y_start,box[3]+ystep,ystep), crs=ccrs.PlateCarree())7 l. B1 V; ?" }% \* ^4 w$ |+ |$ k, T2 M
#zero_direction_label用来设置经度的0度加不加E和W
" N5 I5 e# n7 U, p1 g- f lon_formatter = LongitudeFormatter(zero_direction_label=False)8 n- _4 E2 Y8 W' E/ Z
lat_formatter = LatitudeFormatter()
; `9 g) J, A' `8 E ax.xaxis.set_major_formatter(lon_formatter)
' {/ `" e8 S: s# q ax.yaxis.set_major_formatter(lat_formatter)
* u' T5 M; B b" @2 L1 u9 y* n #添加网格线
. ~" ?5 ^7 ]$ X, N5 O ax.grid()! Q. O* M5 u9 H& W
8 B t( \2 b1 u- y5 `7 ~$ [ ax.outline_patch.set_visible(False)8 O* Y" B% F P4 H3 b2 o
ax.spines[bottom].set_visible(True)
; U- C9 f1 x S( ^. J4 P- v% X, v& Y3 R ax.spines[left].set_visible(True)
! Q, E7 m7 F$ V5 U% _5 ?; m ax.spines[right].set_visible(True)+ V% z2 L9 h" i/ {9 i8 c9 Q8 q( t$ B
ax.spines[top].set_visible(True)
: ~! q) W" c1 ], }9 _# A ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
* Q* e/ u" |! h ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细
$ k1 c% A% ~: |# k' o- M ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细
1 M5 y5 o7 O" d4 o ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细; y- u8 W+ q+ c* E
0 V2 R! r/ J' f6 D5 J2 m3 f return ax最后多说一句,想学习Python可联系阿喵,这里有我自己整理的整套python学习资料和路线,想要这些资料的都可以关注阿喵,并私信“01”领取。 : V# h- q1 k5 K8 Q- T
# X1 k- A" f, q l, E* i1 ?/ i$ P& b7 h8 P# M4 _
1 g( s' E1 x, O+ S# L( U: m1 b9 z
/ `1 w8 w* g6 a( @% i |