4 j1 y9 ~, m( {* h8 R+ i/ i. v/ y
文章目录前言一、基础介绍二、区域地图的绘制总结前言* f6 \- q& i/ _. |* I% l: _& S6 ]
常用地图底图的绘制一般由Basemap或者cartopy模块完成,由于Basemap库是基于python2开发的一个模块,目前已经不开发维护。故简单介绍cartopy模块的一些基础操作。 7 a1 e6 v9 ^ t7 ^
7 H2 R8 k2 o2 f# b' W% T2 ~
如果大家在学习中遇到困难,想找一个python学习交流环境,可以加入我们的python裙,关注小编,并私信“01”即可进裙,领取python学习资料,会节约很多时间,减少很多遇到的难题。
& {* M0 V9 {7 E3 E 一、基础介绍7 t9 b/ n1 U5 L( u* W! q/ T
首先导入相关模块。 import numpy as np
9 |4 `7 K+ `$ a3 i8 Z- w7 ~! Y- h import matplotlib.pyplot as plt
( z8 |5 @- a- }0 ^' l0 d) [4 g import cartopy.crs as ccrs
/ T6 I, m2 `7 U8 i1 E! a# N& } import cartopy.feature as cfeature- ]; i. ?8 Z3 ^4 X |6 D. N
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
7 N& h0 U9 B W3 ? 12345. o$ @8 p5 B5 ^+ I- c+ h
首先介绍参数projection,该命令可以配合ccrs设置投影类型,此处以方形投影命令为示例。其中central_longitude参数为投影中心位置。其中心设置与Basemap设置规则一样,详情可以看上一篇文章。 ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=0)): A) ?$ n' J+ ~2 m$ Z( k" Q
1在设置好绘制类型后,绘制地图各特征量。其代码如下: #ax.add_feature(cfeature.LAKES.with_scale(scale))
) W. V0 U0 i/ `5 u2 t3 I ax.add_feature(cfeature.OCEAN.with_scale(scale))& p, M1 R4 S W
#ax.add_feature(cfeature.RIVERS.with_scale(scale))
7 I* k2 n" ~5 G8 ~( B+ | #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)! ^+ S& f/ c, A; P1 b4 A" }% l
ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)1 m) K2 X' W2 M5 i
12345
U3 O( S* T2 B% d% P6 A/ O: E( { 参数scale为地图分辨率,目前支持10m,50m,110m,参数lw为线条粗细。此处绘制海岸线和海洋,效果图如下:
. S0 V+ X# g8 w+ L, L
. h1 j w1 B) u e3 L
; I" B" ~$ u. u0 J' T6 [ 在绘制结束后,作为地图。经纬度自然是必不可少的,在该模块中,引进同时设置坐标轴标签改变该标签刻度的表示,具体形式如下: ax.set_xticks(np.arange(0,361,40), crs=ccrs.PlateCarree())% ]1 y& C' T: O* B& M
ax.set_yticks(np.arange(-90,90+30,30), crs=ccrs.PlateCarree())
* E3 \* X |" R V #zero_direction_label用来设置经度的0度加不加E和W
9 p5 ~: a0 j5 |+ e4 L( i lon_formatter = LongitudeFormatter(zero_direction_label=False)
; V$ `$ l4 F3 G& ]$ D lat_formatter = LatitudeFormatter()7 S/ m' Z$ Q k; t7 N9 v+ a8 J; S# o" a
ax.xaxis.set_major_formatter(lon_formatter)- }- Z0 Q1 M/ Q4 }; J
ax.yaxis.set_major_formatter(lat_formatter)
8 o. v* A9 ^% R! P6 k3 E- R0 D$ T 1234567可以看到效果图如下: # ~ E4 s; s, H0 p% a! p/ N3 w
8 [1 q Q E1 e/ X) I& z8 n
2 u* t: ?- i N. K: z7 ^
当然如果想对坐标轴粗细变化可以引入一下命令。 ax.outline_patch.set_visible(False)7 a$ N; c" q+ _/ V4 l4 ^/ n
ax.spines[bottom].set_visible(True)6 f S" |' i( [( O8 d% ?
ax.spines[left].set_visible(True)+ y: s$ z; b- ?& n
ax.spines[right].set_visible(True)2 a7 j: p% i3 b. x3 c( n
ax.spines[top].set_visible(True)7 z. u/ I, R- D% q L
ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
6 \: \ P8 F6 I& j ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细( \3 N$ V3 @6 u5 L% I2 A
ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细' q* h! X& g# Y* z' q: S7 X* U
ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细9 f, T9 H' t4 l u) d2 @
. H' l' m9 i9 Y3 U' U0 h
12345678910应该在该模块下,控制坐标轴的命令已经和常规不一样。因此先关闭该控制,然后开启常规坐标轴设置。
. d' K9 H- J* ?% L, |2 Q; f 二、区域地图的绘制
7 _! `, F$ }( I$ n" K 当我们在某一小块区域研究时,需要绘制区域地图。此时我们可以引入命令: ax.set_extent(box,crs=ccrs.PlateCarree())
- K- R! M! l, ~3 T/ a H. O6 k 1* @/ e% b7 J4 V# B% D% d& s
其中box为绘制区域,crs为投影类型。其他命令基本不变。设置box为[40,180,0,90],可得到效果图如下:
% D0 U* z- z K2 }5 g" L. O
+ U/ O) k1 l( j" y& n& a ; Y! ~2 H" Y; H& U$ G3 j2 W
总结
# h4 |( L. x* A* r 为方便各位读者,我书写了绘制地图的函数,大家在使用时可直接调用。此处示例为方形投影,若希望绘制其他投影。只需要修改函数部分参数即可。代码如下: def map_make(scale,box,xstep,ystep):
9 H0 o. l3 A) e5 }3 U5 _ ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=180))# j0 z) Y+ _" N7 a, f
a = (box[1]-box[0])//xstep( M8 r5 S- J. f' F& N
x_start = box[1] - a*xstep
, _, m# v% Y- I- K W0 r7 a" S( h1 z a = (box[3]-box[2])//ystep
, E+ n. S% ~* U' } y_start = box[3] - a*ystep* n6 |6 {8 k* j- O
ax.set_extent(box,crs=ccrs.PlateCarree())
7 s+ `, c6 b8 M# ]8 w6 @0 j) { #ax.add_feature(cfeature.LAKES.with_scale(scale)): O& z2 a% h7 W+ v# b0 m
#ax.add_feature(cfeature.OCEAN.with_scale(scale))
0 M, r( z! b1 r4 v, W4 M. I #ax.add_feature(cfeature.RIVERS.with_scale(scale))
& q9 B; I9 S) D- \( a2 z1 V; { #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)
T2 G' K; L8 ?0 b+ j$ {' ^ ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)( C4 x! p0 y/ l; c, S' d) Y
5 c: c" I) f; j! y6 {
ax.set_xticks(np.arange(x_start,box[1]+xstep,xstep), crs=ccrs.PlateCarree()); }1 d# L" J3 l' f1 S8 q6 }
ax.set_yticks(np.arange(y_start,box[3]+ystep,ystep), crs=ccrs.PlateCarree())
7 L. ~( g9 H! n #zero_direction_label用来设置经度的0度加不加E和W6 {5 Y3 }8 k' Z
lon_formatter = LongitudeFormatter(zero_direction_label=False): R1 L& M0 \, n* ^& K# t
lat_formatter = LatitudeFormatter()
. j$ g6 D6 \- B; c2 a, m- f ax.xaxis.set_major_formatter(lon_formatter)# R2 U6 N2 D% f- a& j" B; ~
ax.yaxis.set_major_formatter(lat_formatter)
$ Y) H2 Q- \0 q$ t: } [4 T$ f$ { k #添加网格线
+ t+ \1 B! `: x0 R# L ax.grid()" [! i; N. x5 |2 ]% B
- u1 x- G( p; m) ? ax.outline_patch.set_visible(False)0 C/ D6 h0 T# j: ~' v
ax.spines[bottom].set_visible(True)
4 u* T& G" a) g5 g9 }* S) W ax.spines[left].set_visible(True)* M2 Y$ ^) }" ]1 j5 ^0 r
ax.spines[right].set_visible(True)3 c/ A7 z8 e5 v* t0 p
ax.spines[top].set_visible(True)
+ |0 f9 D, O Q" \ ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
+ T# t- ^8 I2 U i5 g4 l6 O5 o! e ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细
) l1 u- C/ d2 Z ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细" `8 F, g+ j, z. N$ w
ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
6 r7 [ b: d7 o' p, k t
6 i* j/ O$ h% C) o- O M1 K return ax最后多说一句,想学习Python可联系阿喵,这里有我自己整理的整套python学习资料和路线,想要这些资料的都可以关注阿喵,并私信“01”领取。
. H+ }1 c$ @# }) D2 @/ Z. O) I
, j( W# Y/ W# ^+ _7 X( A. q0 G7 p; D/ _8 ~( u
) Y' f' o* I/ B2 h2 S2 H% \4 _) E$ e2 j- y) O7 N
|