! s( y2 i; ^# Q 文章目录前言一、基础介绍二、区域地图的绘制总结前言# j4 w; E3 W* z- f# P3 X
常用地图底图的绘制一般由Basemap或者cartopy模块完成,由于Basemap库是基于python2开发的一个模块,目前已经不开发维护。故简单介绍cartopy模块的一些基础操作。 + s1 H4 H- b6 v/ q
1 {4 W0 Z# V+ k* ~9 a 如果大家在学习中遇到困难,想找一个python学习交流环境,可以加入我们的python裙,关注小编,并私信“01”即可进裙,领取python学习资料,会节约很多时间,减少很多遇到的难题。 " |3 ~, u4 T" y
一、基础介绍+ f. W& `, D- c; E
首先导入相关模块。 import numpy as np
2 n L7 W& y0 E& P0 P: z; ?) q- z import matplotlib.pyplot as plt3 u( e6 l2 Z: B& s5 T0 F
import cartopy.crs as ccrs
( Q+ I8 F2 [0 ]2 u! W1 w import cartopy.feature as cfeature$ D8 Y* Q2 Q I1 j$ w% z/ }! h
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter& N/ y' `1 K2 r* u7 @5 `
12345
& s7 T! U; u0 o8 e+ ~ 首先介绍参数projection,该命令可以配合ccrs设置投影类型,此处以方形投影命令为示例。其中central_longitude参数为投影中心位置。其中心设置与Basemap设置规则一样,详情可以看上一篇文章。 ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=0))* l0 G% I0 ^6 B
1在设置好绘制类型后,绘制地图各特征量。其代码如下: #ax.add_feature(cfeature.LAKES.with_scale(scale)): P5 ]* p r2 L' w7 p9 n
ax.add_feature(cfeature.OCEAN.with_scale(scale))& J6 A, V% Y, }% `
#ax.add_feature(cfeature.RIVERS.with_scale(scale))/ ~& F+ y2 U0 W P7 v' \* j# }6 V
#ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)
+ z6 w' J" C, m: |0 j9 a5 x ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)
% u6 P. b$ S9 Y( g! p 12345
. @3 E, D j2 G. |$ h 参数scale为地图分辨率,目前支持10m,50m,110m,参数lw为线条粗细。此处绘制海岸线和海洋,效果图如下:
( Y4 W- w9 R6 ], q% @
9 O& k- I# ]& V# n6 ^5 B% K0 M 1 L0 _! b0 O# o0 C& L2 i. }
在绘制结束后,作为地图。经纬度自然是必不可少的,在该模块中,引进同时设置坐标轴标签改变该标签刻度的表示,具体形式如下: ax.set_xticks(np.arange(0,361,40), crs=ccrs.PlateCarree())1 n* o5 {2 k' d
ax.set_yticks(np.arange(-90,90+30,30), crs=ccrs.PlateCarree())
2 \, X2 n/ {( ] #zero_direction_label用来设置经度的0度加不加E和W
1 y$ ^4 u1 r' {! P lon_formatter = LongitudeFormatter(zero_direction_label=False)! ?3 c/ t- [! W
lat_formatter = LatitudeFormatter()
8 U# o, H4 o& I( Y4 o0 @# b ax.xaxis.set_major_formatter(lon_formatter)+ f0 G8 P% g- _1 }6 x
ax.yaxis.set_major_formatter(lat_formatter)1 D/ \* G! S2 H: c6 K/ v6 ]) l9 E* @
1234567可以看到效果图如下: 6 d/ p4 n: q5 R% j3 ~$ M
# d) ?3 r9 e A' E$ z 9 q8 Q5 H$ N' F4 N
当然如果想对坐标轴粗细变化可以引入一下命令。 ax.outline_patch.set_visible(False)
0 q& w! ^: O4 ]: v! _$ {# S ax.spines[bottom].set_visible(True)
% [1 E; a' t( [* e- q; B. R ax.spines[left].set_visible(True)
, }* F7 U6 P. o( c: n7 w: q+ q0 J3 h ax.spines[right].set_visible(True)/ V: F8 v! J( @; ~
ax.spines[top].set_visible(True)6 a. O0 B" \% r* M) ^* R
ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
" t3 |# ^7 N$ z8 A ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细# _9 q ]2 P9 Q! Q
ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细
1 e7 L4 Y& G& U. j5 h+ }4 t+ P- o ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
: R; v4 }5 J8 D9 b% V% K9 p( q1 s) Y- }) E& U" l
12345678910应该在该模块下,控制坐标轴的命令已经和常规不一样。因此先关闭该控制,然后开启常规坐标轴设置。
0 c9 K8 L! e4 m 二、区域地图的绘制+ X, W9 y1 v" D l0 Z" P: z9 _2 ?
当我们在某一小块区域研究时,需要绘制区域地图。此时我们可以引入命令: ax.set_extent(box,crs=ccrs.PlateCarree())* t6 h( K5 V3 Y5 k2 Q% y8 I
19 b. i1 e9 s# j) g$ ^
其中box为绘制区域,crs为投影类型。其他命令基本不变。设置box为[40,180,0,90],可得到效果图如下: ) T1 [$ v R$ F4 X: S
# T. P, A& `9 x' @$ L& e
- @" L* i" R3 D 总结3 R. m i, p& A5 r; g5 w
为方便各位读者,我书写了绘制地图的函数,大家在使用时可直接调用。此处示例为方形投影,若希望绘制其他投影。只需要修改函数部分参数即可。代码如下: def map_make(scale,box,xstep,ystep):' I7 e' v2 G/ D% f
ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=180))& C/ @! z$ M4 i6 e. l
a = (box[1]-box[0])//xstep
8 R) M) V' V& N x_start = box[1] - a*xstep
6 \3 ~2 F" K" M+ B a = (box[3]-box[2])//ystep
, Z4 F7 P, j5 p& P: L& ~ y_start = box[3] - a*ystep
' r+ M( @) G; ^0 o1 A5 i ax.set_extent(box,crs=ccrs.PlateCarree())" U! l( S& Y5 ^5 V {9 ]
#ax.add_feature(cfeature.LAKES.with_scale(scale))
% Y ?2 L6 G5 X2 |2 M* A/ h6 A #ax.add_feature(cfeature.OCEAN.with_scale(scale))
9 U8 J" }/ }; U/ ?/ @ #ax.add_feature(cfeature.RIVERS.with_scale(scale)), n j, |( w! e( \$ E9 U
#ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)
; K5 ?% X* D2 J, I. R ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)
k7 g2 ?7 E3 X2 A9 ?2 P! c- m
. j# m( [% i, D% a: r; o ax.set_xticks(np.arange(x_start,box[1]+xstep,xstep), crs=ccrs.PlateCarree())" m, K; q# S4 Y, H& _7 B' X; i9 z
ax.set_yticks(np.arange(y_start,box[3]+ystep,ystep), crs=ccrs.PlateCarree())
9 I" p" f3 }) Z$ f" X4 [ #zero_direction_label用来设置经度的0度加不加E和W
- t9 [. B Q* d5 w) t lon_formatter = LongitudeFormatter(zero_direction_label=False)9 L& \2 |1 S. ]
lat_formatter = LatitudeFormatter()
* l& f" Y+ V7 a, i+ F ax.xaxis.set_major_formatter(lon_formatter)
5 m; Y6 f* p, x/ ?! L ax.yaxis.set_major_formatter(lat_formatter)! ]8 |7 \/ g& r8 S2 Q- {
#添加网格线1 d0 F) C1 Z7 Z8 x3 Z& q+ z: A
ax.grid()
) G! C/ k- y' P3 h( K* n+ @8 c _- e$ @( v! @* a
ax.outline_patch.set_visible(False)1 C. c" |7 x3 t5 J# a* r
ax.spines[bottom].set_visible(True)
B- [$ Q' g) w4 P. H ax.spines[left].set_visible(True)
0 Q A. e3 \) f) P, r5 B q ax.spines[right].set_visible(True)
. A4 i$ A# _( |! d0 E ax.spines[top].set_visible(True)
) @( b- \% N Y$ M ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
y6 U: J6 N4 l" Q ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细
2 e6 l& J& X5 N: c* J8 ] ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细
2 I) `; R# `/ f8 j7 t ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
8 K( m% F& [3 @; Q! ~" e
: J4 \7 @) N% I return ax最后多说一句,想学习Python可联系阿喵,这里有我自己整理的整套python学习资料和路线,想要这些资料的都可以关注阿喵,并私信“01”领取。
0 C7 P- I* K! C$ S' U: m: g% u* x9 j7 { Q
0 p& W$ B( t2 l' ? `( u- z3 B/ }7 D
7 F6 u2 ^" N( `. \7 o5 S, B+ b4 Z
|