+ H2 a2 Y4 W3 W' c6 R
文章目录前言一、基础介绍二、区域地图的绘制总结前言. E6 I2 V! J4 _, H
常用地图底图的绘制一般由Basemap或者cartopy模块完成,由于Basemap库是基于python2开发的一个模块,目前已经不开发维护。故简单介绍cartopy模块的一些基础操作。
, I# V5 X; E9 V. \2 ^7 o 6 V( K4 S4 `# r5 a2 I6 d
如果大家在学习中遇到困难,想找一个python学习交流环境,可以加入我们的python裙,关注小编,并私信“01”即可进裙,领取python学习资料,会节约很多时间,减少很多遇到的难题。
! e, U* i- Q; g% \ 一、基础介绍
5 {' k6 g, k E8 W% I' ] 首先导入相关模块。 import numpy as np
7 y9 ^! o1 K ~+ I import matplotlib.pyplot as plt$ ^% C8 C! K0 p& j
import cartopy.crs as ccrs/ C5 A( t5 \: Y8 q! Y0 k
import cartopy.feature as cfeature' \. n4 g2 ]! ]% a4 }
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter. c" e* ~# \) @. f
12345
" g; j) `4 q5 P0 u7 [3 z+ N 首先介绍参数projection,该命令可以配合ccrs设置投影类型,此处以方形投影命令为示例。其中central_longitude参数为投影中心位置。其中心设置与Basemap设置规则一样,详情可以看上一篇文章。 ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=0))
/ g/ C' C1 j: F 1在设置好绘制类型后,绘制地图各特征量。其代码如下: #ax.add_feature(cfeature.LAKES.with_scale(scale))
- m( z, n0 i% d ax.add_feature(cfeature.OCEAN.with_scale(scale))3 ?- o) p. ^. h
#ax.add_feature(cfeature.RIVERS.with_scale(scale))( C9 @5 M9 T5 N) j* S8 B& k
#ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)
+ v/ Y8 q5 v# M2 |' l ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)
; V& ~, d# I% K9 @0 e 12345
! k6 l: ?- f) }0 F3 `# ^ 参数scale为地图分辨率,目前支持10m,50m,110m,参数lw为线条粗细。此处绘制海岸线和海洋,效果图如下:
2 d% r8 [7 f e; F& G0 [: J( k; G, H/ u0 l4 D( z: Y
2 L3 E$ {+ f0 A: G6 A) |
在绘制结束后,作为地图。经纬度自然是必不可少的,在该模块中,引进同时设置坐标轴标签改变该标签刻度的表示,具体形式如下: ax.set_xticks(np.arange(0,361,40), crs=ccrs.PlateCarree())8 W$ v. y* p- `0 i3 p4 Y
ax.set_yticks(np.arange(-90,90+30,30), crs=ccrs.PlateCarree())+ @- ` W" M% t" X
#zero_direction_label用来设置经度的0度加不加E和W
9 i* S. d1 d4 F) d2 c lon_formatter = LongitudeFormatter(zero_direction_label=False)
0 \5 J. H! O1 r% ^% t* N- O8 O$ M* p& Y lat_formatter = LatitudeFormatter()- i4 ^- P R$ d7 @% l: s1 Q
ax.xaxis.set_major_formatter(lon_formatter)
2 h3 w$ U% k7 p* l ax.yaxis.set_major_formatter(lat_formatter)
$ c& G" Q/ H3 g9 n% x) u9 j 1234567可以看到效果图如下: ' t. T3 ~0 P5 t/ ?9 Q
! o! y4 O& E% z6 D$ C " o+ D; R8 h: A: I5 T6 c
当然如果想对坐标轴粗细变化可以引入一下命令。 ax.outline_patch.set_visible(False)& b6 {. z- S9 W' X) m1 m
ax.spines[bottom].set_visible(True)
0 g8 {, G: w$ q9 S! G5 z ax.spines[left].set_visible(True)
J& x1 ~1 ?( ^+ Y9 i ax.spines[right].set_visible(True)
^) F }! g' E$ G+ {4 s ax.spines[top].set_visible(True)
$ X0 c, b6 X: m$ s' ~6 i1 Q ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
9 v" p2 @" I7 C7 P5 J1 C ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细4 i6 g# \& \) B" y% {1 f
ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细
. d) T( H( r3 a: k7 e* Y ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
% |9 R$ k! Q0 `3 s3 y( s9 D, f# p! s1 M1 c7 ?1 E6 |# g( l
12345678910应该在该模块下,控制坐标轴的命令已经和常规不一样。因此先关闭该控制,然后开启常规坐标轴设置。
' y. O2 d- ?+ }7 T8 F 二、区域地图的绘制! N; Q U( Y- {1 [' Y. e
当我们在某一小块区域研究时,需要绘制区域地图。此时我们可以引入命令: ax.set_extent(box,crs=ccrs.PlateCarree())# H- p, A5 {4 P
14 p e; [- A3 Z9 l
其中box为绘制区域,crs为投影类型。其他命令基本不变。设置box为[40,180,0,90],可得到效果图如下: + t; s' m8 P9 g+ G ]6 L. z
* V* O6 W6 \7 Q% c" s* ]: B
: v9 ~- c' X% V% s4 M' y# | 总结
6 B$ n$ O. B% P. o" F$ U 为方便各位读者,我书写了绘制地图的函数,大家在使用时可直接调用。此处示例为方形投影,若希望绘制其他投影。只需要修改函数部分参数即可。代码如下: def map_make(scale,box,xstep,ystep):" [6 Z/ |1 }- J" i5 B6 m
ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=180))7 z7 i7 {1 W0 I' E2 `
a = (box[1]-box[0])//xstep
. M$ @) x% f$ i& u x_start = box[1] - a*xstep
7 ~' k$ c$ x# S a = (box[3]-box[2])//ystep6 v2 N; P1 v5 D8 Y3 }( X4 l1 h5 N3 e
y_start = box[3] - a*ystep* O+ c8 N# K& e2 P
ax.set_extent(box,crs=ccrs.PlateCarree())+ i& i) e( H! _
#ax.add_feature(cfeature.LAKES.with_scale(scale))
5 s" Z& m) j2 f1 ] #ax.add_feature(cfeature.OCEAN.with_scale(scale))' ^. h i3 ?1 U6 O
#ax.add_feature(cfeature.RIVERS.with_scale(scale))
: r. F k& A+ P. t #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)) V0 N$ z: \3 {6 U1 ^$ ]
ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)' T! L0 u# S& l' U2 C6 [5 g. z- v
) J+ Q$ O6 L% M! X; Y5 R! W
ax.set_xticks(np.arange(x_start,box[1]+xstep,xstep), crs=ccrs.PlateCarree()). o% s0 T/ V- c* M. s) A
ax.set_yticks(np.arange(y_start,box[3]+ystep,ystep), crs=ccrs.PlateCarree())1 D% ]5 h2 f. `3 R
#zero_direction_label用来设置经度的0度加不加E和W% ~( _$ s, t( A* X3 [6 b
lon_formatter = LongitudeFormatter(zero_direction_label=False)/ P' E/ o) f; j
lat_formatter = LatitudeFormatter()) e! w4 v) y" u! p
ax.xaxis.set_major_formatter(lon_formatter)7 _$ ?7 `( J4 `. j! J
ax.yaxis.set_major_formatter(lat_formatter)
[0 w+ l( @; q y2 Y #添加网格线
% ]) P9 d" a' f8 n ax.grid()4 f1 C, Y- \6 S+ z: i
1 [. z0 [- y; i7 D
ax.outline_patch.set_visible(False)
0 p. C1 \ D0 z6 ~" m, a, w. V" v ax.spines[bottom].set_visible(True)
4 \2 b5 }9 z2 S, {, l ax.spines[left].set_visible(True)" H9 E: K4 _( {
ax.spines[right].set_visible(True)9 Y- |; r1 Q W
ax.spines[top].set_visible(True)
2 K7 L) Z8 \; ~% G ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
. A' R* c& j; V ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细
* _; F$ c# o/ J1 b$ H ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细
& `( k" g2 Y9 j u* i ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细; E6 k2 n n5 x4 l5 t0 K: i9 G- t
3 A) {& [; b- }+ u2 ?% g
return ax最后多说一句,想学习Python可联系阿喵,这里有我自己整理的整套python学习资料和路线,想要这些资料的都可以关注阿喵,并私信“01”领取。
{! q1 P9 r8 ], M7 t3 @% U3 p, C" v5 s0 ^9 L4 Q
# U L( i5 G7 @/ l3 \$ t8 U
/ F: a4 l, G4 E/ d9 ~7 a- P$ g% q( c! U5 h
|