5 O9 v- a: s+ s5 N* M$ z4 @2 i( r- O 文章目录前言一、基础介绍二、区域地图的绘制总结前言3 |# L! @' m) j. E( p# {
常用地图底图的绘制一般由Basemap或者cartopy模块完成,由于Basemap库是基于python2开发的一个模块,目前已经不开发维护。故简单介绍cartopy模块的一些基础操作。 . C/ F2 f; C2 E8 O4 B6 O
2 ^0 M% k- R$ [4 K% b/ w
如果大家在学习中遇到困难,想找一个python学习交流环境,可以加入我们的python裙,关注小编,并私信“01”即可进裙,领取python学习资料,会节约很多时间,减少很多遇到的难题。 * F& O& `, b" E
一、基础介绍
6 U' o$ C6 E& g0 |! E. X 首先导入相关模块。 import numpy as np
2 c0 U9 y/ M, y, N! J9 L7 ` import matplotlib.pyplot as plt( L4 o( z4 V% D% m
import cartopy.crs as ccrs2 ]! l+ V0 a, [ @" C, k
import cartopy.feature as cfeature& ]+ w$ l- p t/ H( ^
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter' F: ?& n" V# I; w
12345
# m& t1 k, Z$ W, y( d8 S' E 首先介绍参数projection,该命令可以配合ccrs设置投影类型,此处以方形投影命令为示例。其中central_longitude参数为投影中心位置。其中心设置与Basemap设置规则一样,详情可以看上一篇文章。 ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=0))
: H9 m% F. z/ ] a( g% Y0 J 1在设置好绘制类型后,绘制地图各特征量。其代码如下: #ax.add_feature(cfeature.LAKES.with_scale(scale))
% H2 ]8 c/ G# t3 g9 `, K8 w ax.add_feature(cfeature.OCEAN.with_scale(scale))) Z" i' a4 f0 t" t3 |: L3 }
#ax.add_feature(cfeature.RIVERS.with_scale(scale))
1 ^7 |- S# v; N7 Q; i% e #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)' @( o3 s" ?/ K0 L
ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)
! i* U4 ^1 J; G6 r! D2 q 12345
- Q4 w/ S; E3 S8 ^& ^ 参数scale为地图分辨率,目前支持10m,50m,110m,参数lw为线条粗细。此处绘制海岸线和海洋,效果图如下:
+ O1 {/ l# w) R) r) V' t' S$ @ |3 A, U% v* ^6 @* W9 T
0 B& ~: z i2 ^8 C3 }% O* `$ n
在绘制结束后,作为地图。经纬度自然是必不可少的,在该模块中,引进同时设置坐标轴标签改变该标签刻度的表示,具体形式如下: ax.set_xticks(np.arange(0,361,40), crs=ccrs.PlateCarree())
" ?4 y5 M6 ^0 ?3 p ax.set_yticks(np.arange(-90,90+30,30), crs=ccrs.PlateCarree())# V/ Q3 g- h0 @1 _: k8 n8 h
#zero_direction_label用来设置经度的0度加不加E和W
' C) e3 M: G7 M- p5 _3 a( x( c lon_formatter = LongitudeFormatter(zero_direction_label=False)* G5 K; {; t8 o' y5 L
lat_formatter = LatitudeFormatter()
8 C9 U- w! j# g8 x) g" i$ \ ax.xaxis.set_major_formatter(lon_formatter)
0 @* Q5 g8 q* Y& S! D3 K ax.yaxis.set_major_formatter(lat_formatter)+ s# Z) e1 D8 T+ }
1234567可以看到效果图如下:
% Z b6 R1 K- ]; k2 y1 D' W1 K7 j) Y. W
+ e0 I. j5 E ]7 g# ]7 P \1 y 当然如果想对坐标轴粗细变化可以引入一下命令。 ax.outline_patch.set_visible(False)
% G8 `. E/ n' r! P" E ax.spines[bottom].set_visible(True); l$ {9 }% D5 y1 B( \
ax.spines[left].set_visible(True)6 J% N) a3 h6 }0 c/ Z) n. i4 i
ax.spines[right].set_visible(True); ]. ]9 y4 X: D: F
ax.spines[top].set_visible(True)
% f0 K6 h3 H! ?4 W# Y9 m ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细: N# `. k3 P) W* N2 e! V4 r
ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细
& Y4 q, Q; H, u% W6 X ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细
! `' }) ?. D2 N+ l ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
/ q2 q; @, h* w9 s) [7 j3 f
! P' i: l% F/ ]. s! Q1 L; n 12345678910应该在该模块下,控制坐标轴的命令已经和常规不一样。因此先关闭该控制,然后开启常规坐标轴设置。 % z( {0 j. o+ [
二、区域地图的绘制
3 d* Q* \/ S3 j 当我们在某一小块区域研究时,需要绘制区域地图。此时我们可以引入命令: ax.set_extent(box,crs=ccrs.PlateCarree())
0 v. _9 g3 ]! z. F4 n# H 1
3 z2 u; b6 E8 Z 其中box为绘制区域,crs为投影类型。其他命令基本不变。设置box为[40,180,0,90],可得到效果图如下:
9 s( c2 [/ J. h$ |9 x2 [; F# y" `+ Z; r: y( b/ d+ I
0 j/ F1 f4 a7 q5 [: j 总结
. }' W$ j _3 }+ y% K 为方便各位读者,我书写了绘制地图的函数,大家在使用时可直接调用。此处示例为方形投影,若希望绘制其他投影。只需要修改函数部分参数即可。代码如下: def map_make(scale,box,xstep,ystep):/ }! g# w: c) g
ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=180))1 {- c Y/ S3 |/ W
a = (box[1]-box[0])//xstep" ^: H) k3 ?% f- u( R+ `8 ?' }
x_start = box[1] - a*xstep4 H" X2 i+ m7 l6 j0 @1 E9 F5 G
a = (box[3]-box[2])//ystep
1 P# j: Z% T3 T6 a. K" B y_start = box[3] - a*ystep" x# Y/ P; e. F" h' N
ax.set_extent(box,crs=ccrs.PlateCarree())! e8 J% F4 p4 j4 G
#ax.add_feature(cfeature.LAKES.with_scale(scale))7 l* \6 l2 o, c. s) h
#ax.add_feature(cfeature.OCEAN.with_scale(scale))
5 q% S: C8 R1 j #ax.add_feature(cfeature.RIVERS.with_scale(scale))3 L8 q8 |9 d& k% k( `; e! X
#ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)5 K. M* Z6 W( G- d
ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)! C( Z$ l5 f. b) c& j$ _7 J$ i
5 ?, ]" b; E" W1 L5 Q! o2 L# j F
ax.set_xticks(np.arange(x_start,box[1]+xstep,xstep), crs=ccrs.PlateCarree())
$ j. p3 W' p( y9 o ax.set_yticks(np.arange(y_start,box[3]+ystep,ystep), crs=ccrs.PlateCarree())
3 E. U( Z* ]% d4 L; \$ V; n0 r #zero_direction_label用来设置经度的0度加不加E和W! \$ q9 D0 I7 J& w: x8 _
lon_formatter = LongitudeFormatter(zero_direction_label=False)6 u4 t+ `: s8 z. R( f8 p) L0 E2 o$ P0 T
lat_formatter = LatitudeFormatter()2 K, V1 j. m, E7 C+ a0 Q$ W& _
ax.xaxis.set_major_formatter(lon_formatter)
9 n3 @$ R( _' r* P ? ax.yaxis.set_major_formatter(lat_formatter)
. Z3 l, U, d4 k4 D #添加网格线
: m7 s- q6 V0 x- }- ?- |7 } ax.grid()
. b0 r4 n" V$ x
f) O0 m7 d7 l n ax.outline_patch.set_visible(False)
1 B! X: B% a+ s# q5 U1 P0 ` ax.spines[bottom].set_visible(True)
8 {8 N6 x' D+ ^% b/ K, a" U' ^ ax.spines[left].set_visible(True)9 ^1 Q; Q& j; C* g/ \3 o
ax.spines[right].set_visible(True)- R- f6 ?9 I) g5 K! g* x. [* K
ax.spines[top].set_visible(True)' c# U+ q) |& [$ y1 n
ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
) E. j8 v7 a8 s ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细2 y6 b' D" _ D: Q
ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细 M- h; c. y, q( @& v$ @. L( I
ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细$ M j6 K; i# A. {% b$ o
# a- N5 l7 z- k/ }6 p return ax最后多说一句,想学习Python可联系阿喵,这里有我自己整理的整套python学习资料和路线,想要这些资料的都可以关注阿喵,并私信“01”领取。 1 _% K4 e* K+ {8 r
$ T8 W8 {! R5 Q' n
: N- F& \5 F1 |+ [& ?+ ]' h9 g: |5 s% s# q7 Z
7 j" k! r$ w; ]; f |