: G. U. L, I9 R* ~ 文章目录前言一、基础介绍二、区域地图的绘制总结前言
1 @ N4 @4 }& a: y2 [0 B0 z: Q# n 常用地图底图的绘制一般由Basemap或者cartopy模块完成,由于Basemap库是基于python2开发的一个模块,目前已经不开发维护。故简单介绍cartopy模块的一些基础操作。
! Z; q/ H: a; L+ K3 |% p# _
0 O0 z1 H+ e/ b8 r 如果大家在学习中遇到困难,想找一个python学习交流环境,可以加入我们的python裙,关注小编,并私信“01”即可进裙,领取python学习资料,会节约很多时间,减少很多遇到的难题。
( Z4 O( u' _4 \6 z' Q" Y 一、基础介绍
0 V, z/ U4 F. {) Q2 B6 S 首先导入相关模块。 import numpy as np& v4 ^( I" F# k. c5 n6 r& n$ R% ? p& w
import matplotlib.pyplot as plt
1 W: k& a% f- ?1 ]' A' q9 k+ C& G import cartopy.crs as ccrs
# w6 H" ?/ E+ Q0 a+ E7 i7 e/ O import cartopy.feature as cfeature6 h- P9 q/ ~; a8 n- B
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter- V- e) J F) r3 c, F- v+ B
12345
* h% r' x" v. k 首先介绍参数projection,该命令可以配合ccrs设置投影类型,此处以方形投影命令为示例。其中central_longitude参数为投影中心位置。其中心设置与Basemap设置规则一样,详情可以看上一篇文章。 ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=0))% d# }% h+ P6 k+ D
1在设置好绘制类型后,绘制地图各特征量。其代码如下: #ax.add_feature(cfeature.LAKES.with_scale(scale))
: ~9 V/ c3 `8 U ax.add_feature(cfeature.OCEAN.with_scale(scale))5 q; i% C: h; x @4 h) N2 o; F$ H
#ax.add_feature(cfeature.RIVERS.with_scale(scale))
4 J d$ n! P, I0 R' D+ V3 I' n+ R' d: C #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)" x: e! O" _0 r3 l
ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)+ e8 ]4 }7 \. Z7 `1 C' o: S
12345" R' W; G$ f* A& A3 I" S0 ~
参数scale为地图分辨率,目前支持10m,50m,110m,参数lw为线条粗细。此处绘制海岸线和海洋,效果图如下:
8 R+ W* J8 H& Q) P3 G
7 K9 T$ r9 P* j! E, M* p . A! s1 t9 f) |4 A
在绘制结束后,作为地图。经纬度自然是必不可少的,在该模块中,引进同时设置坐标轴标签改变该标签刻度的表示,具体形式如下: ax.set_xticks(np.arange(0,361,40), crs=ccrs.PlateCarree())& q: a3 q" I. k
ax.set_yticks(np.arange(-90,90+30,30), crs=ccrs.PlateCarree())) t# x- H; {9 }( o; Y2 S! G
#zero_direction_label用来设置经度的0度加不加E和W3 M5 v V- ~. ?1 p- r
lon_formatter = LongitudeFormatter(zero_direction_label=False): j3 H( U X$ G. b8 }4 f8 h
lat_formatter = LatitudeFormatter()
/ o6 f V, Z7 q' E5 s/ B, S ax.xaxis.set_major_formatter(lon_formatter)
% F' W( b) \/ N7 x ax.yaxis.set_major_formatter(lat_formatter)0 f! S3 @* K+ k D
1234567可以看到效果图如下:
4 E/ j% [& N9 o$ ]7 g$ |; A: c8 x3 t& [' r! q. i/ l% L
8 ~# r; r# ~$ j" m0 L" [9 b 当然如果想对坐标轴粗细变化可以引入一下命令。 ax.outline_patch.set_visible(False)
( ]: t8 s6 L( R) a5 A4 j$ U ax.spines[bottom].set_visible(True)
. O9 N" x. d3 [ ax.spines[left].set_visible(True)
8 W+ p5 A {8 H& b ax.spines[right].set_visible(True)
6 a7 e/ a/ T9 [; T7 F ax.spines[top].set_visible(True)
1 M, n* t) Y. }3 c8 s0 T ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
$ E R: r: ^3 c1 H* _ ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细" c5 {: `" _. J- w
ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细
0 l" ^6 r. k( _2 ?* U ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
% Y! w) o+ c7 _" v" `
; H, K3 N* D6 `5 }( f 12345678910应该在该模块下,控制坐标轴的命令已经和常规不一样。因此先关闭该控制,然后开启常规坐标轴设置。
0 N3 a L6 U- V' w$ p/ j 二、区域地图的绘制1 M6 z' J, N" k! ?
当我们在某一小块区域研究时,需要绘制区域地图。此时我们可以引入命令: ax.set_extent(box,crs=ccrs.PlateCarree())- H5 \+ v$ |% X+ @1 C$ M. a
1! \. x4 o% ]$ A/ U5 y4 N- o+ s0 O8 z
其中box为绘制区域,crs为投影类型。其他命令基本不变。设置box为[40,180,0,90],可得到效果图如下:
- i2 ], r) ]: Z0 s4 n; N! d6 B# Y6 }( S3 L6 n) X- B
& K% e) _* H8 @! I( x 总结
8 S/ C, c( S' G) M% l! t) n# g 为方便各位读者,我书写了绘制地图的函数,大家在使用时可直接调用。此处示例为方形投影,若希望绘制其他投影。只需要修改函数部分参数即可。代码如下: def map_make(scale,box,xstep,ystep):3 S E$ }/ n* y2 y, c# }; O7 t' ]6 E
ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=180))& [+ h, Y% m' x3 H- y) v K
a = (box[1]-box[0])//xstep S, c9 c) d, v4 E/ u. P
x_start = box[1] - a*xstep' G0 z2 U9 ]0 g& z: a' }, y+ Y
a = (box[3]-box[2])//ystep, k% |& k, i: T
y_start = box[3] - a*ystep9 y {8 Y" t2 l6 b
ax.set_extent(box,crs=ccrs.PlateCarree())
# S* S4 N' e" _! Q' H" z! \ #ax.add_feature(cfeature.LAKES.with_scale(scale))
1 r& E+ l9 E/ B4 {6 K/ Y #ax.add_feature(cfeature.OCEAN.with_scale(scale))
& a5 B2 U* U2 C/ f& }. x #ax.add_feature(cfeature.RIVERS.with_scale(scale))
' M$ k9 Y) t8 H' f d #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)* H" L, _5 G! H; S# Z0 E4 L
ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)5 M: E" g2 i5 G, O# b
$ N5 s6 W9 M, {' W1 W
ax.set_xticks(np.arange(x_start,box[1]+xstep,xstep), crs=ccrs.PlateCarree())+ x* b: H8 W$ G0 ~2 j4 a4 P
ax.set_yticks(np.arange(y_start,box[3]+ystep,ystep), crs=ccrs.PlateCarree())
- ?9 T3 p0 v, F1 g+ t6 a8 m #zero_direction_label用来设置经度的0度加不加E和W
. F/ b: Y3 _: F: g9 Y3 K& J9 ~ lon_formatter = LongitudeFormatter(zero_direction_label=False)$ C; \7 L: O& t
lat_formatter = LatitudeFormatter()
, ~% W2 ^9 |! q! H5 [" d5 i ax.xaxis.set_major_formatter(lon_formatter)% c5 i" B6 p' l" w
ax.yaxis.set_major_formatter(lat_formatter)
- Q3 P- L( {4 w, H9 O s #添加网格线
! F# ^( e2 M# U7 {- M ax.grid(). k8 k& m4 `* F* @
( K+ E q+ ?- e$ A ax.outline_patch.set_visible(False)9 G; _0 c: N, @2 ~0 F- T
ax.spines[bottom].set_visible(True)9 Y9 C/ U- U: e0 N
ax.spines[left].set_visible(True)
; T, x# E9 U" s) p c3 d+ m9 e ax.spines[right].set_visible(True); g+ ^6 R L# s! {
ax.spines[top].set_visible(True)- _" w, p6 C% C8 Q' r5 K! v8 t+ t! s
ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细( g& ^8 H8 {3 i1 N. v# D/ h8 U! ]1 R
ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细 Y n9 I) I' g* r' L) c$ |1 d
ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细; S( D9 Q0 c; A1 R9 v
ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细3 K( b0 v1 }( O0 ]& S
4 K3 ~6 L: w3 W
return ax最后多说一句,想学习Python可联系阿喵,这里有我自己整理的整套python学习资料和路线,想要这些资料的都可以关注阿喵,并私信“01”领取。 * F1 B K6 K; W [* }# m3 Q
! i2 p/ Y$ X+ }( T) W0 }. s
% P2 d! f4 Q4 e6 x8 ~
. c' y* s' E( ^+ Y) `: K% D& l8 [8 m R! L
( H8 k3 V! @, U0 e( u |