8 W) z' o# Z+ l. |$ y
文章目录前言一、基础介绍二、区域地图的绘制总结前言! U' j& `; O6 r6 C
常用地图底图的绘制一般由Basemap或者cartopy模块完成,由于Basemap库是基于python2开发的一个模块,目前已经不开发维护。故简单介绍cartopy模块的一些基础操作。 4 P- F0 L7 g4 Z, s* a
/ k' j4 W2 V" X4 H1 I. [ 如果大家在学习中遇到困难,想找一个python学习交流环境,可以加入我们的python裙,关注小编,并私信“01”即可进裙,领取python学习资料,会节约很多时间,减少很多遇到的难题。 9 M f& p4 x6 B& c
一、基础介绍
5 @* v# g- Q( L) _9 {7 T3 A& n6 U( f 首先导入相关模块。 import numpy as np
q5 U$ E, B9 Y2 s import matplotlib.pyplot as plt
w5 W. u: U& _! U( Y5 t, M4 j import cartopy.crs as ccrs
8 a: K% `- N2 u6 v9 N: j9 {/ S import cartopy.feature as cfeature% l: G6 D. W/ c& y& B* Z
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter, u& M) p8 U; w0 j
12345
' q) X6 F" X, s9 v& e- y 首先介绍参数projection,该命令可以配合ccrs设置投影类型,此处以方形投影命令为示例。其中central_longitude参数为投影中心位置。其中心设置与Basemap设置规则一样,详情可以看上一篇文章。 ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=0))( r6 Z ~) r- |$ w6 M/ A: y
1在设置好绘制类型后,绘制地图各特征量。其代码如下: #ax.add_feature(cfeature.LAKES.with_scale(scale))
4 ^: m! @) f1 L! u- | ax.add_feature(cfeature.OCEAN.with_scale(scale))
$ c! v2 A* e2 o) K( t #ax.add_feature(cfeature.RIVERS.with_scale(scale))
|# h: U- L5 s; @( b6 [1 I1 V: A #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)3 ? N# o- ?1 t7 h
ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)( r; F# R f; K7 I' ?3 G
123458 d4 O7 \, R; h. J) [$ I3 v V) j
参数scale为地图分辨率,目前支持10m,50m,110m,参数lw为线条粗细。此处绘制海岸线和海洋,效果图如下:
5 M4 O& [$ C2 E) I! r( x2 V8 C2 [! M/ B( n/ d
3 d$ y: r4 E: l
在绘制结束后,作为地图。经纬度自然是必不可少的,在该模块中,引进同时设置坐标轴标签改变该标签刻度的表示,具体形式如下: ax.set_xticks(np.arange(0,361,40), crs=ccrs.PlateCarree())* u3 y4 p7 D# L! Y1 h8 w- U! y: G
ax.set_yticks(np.arange(-90,90+30,30), crs=ccrs.PlateCarree())1 ]# R+ R2 ^; H, U0 z3 E+ p
#zero_direction_label用来设置经度的0度加不加E和W
6 l% I3 S/ N3 ?5 B5 } V lon_formatter = LongitudeFormatter(zero_direction_label=False)
3 A+ U% r$ L5 x' ~2 F lat_formatter = LatitudeFormatter(), q! f. _" k, Z$ Q* m8 e1 {
ax.xaxis.set_major_formatter(lon_formatter)
6 P' n' R8 Y* U R& b& l ax.yaxis.set_major_formatter(lat_formatter)0 n# N/ Q0 T' a2 R
1234567可以看到效果图如下:
7 @9 L0 j- z5 }$ p- T# r0 x3 N) S3 S1 W- ^" [) y- z
+ ]+ _1 k8 r/ I0 _0 J 当然如果想对坐标轴粗细变化可以引入一下命令。 ax.outline_patch.set_visible(False)
: Q2 V) O; o7 f+ ^/ Q% y ax.spines[bottom].set_visible(True)
( k1 |1 x) d. g- ~2 B* M6 z" o" U: c ax.spines[left].set_visible(True)
5 r4 c5 y# U+ W3 Q+ C) o ax.spines[right].set_visible(True)
: X& x: i% I; n2 r% o1 e ax.spines[top].set_visible(True)
2 A* Y4 L' J( k8 o ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细2 Q* p; @. V. a
ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细' ~/ T/ C M% }% F* c3 U% X( ~
ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细2 R S7 d3 a- L0 x1 q' V
ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
6 D# q, s( H- z- x' c! ] V' A6 i' q' `! M) `
12345678910应该在该模块下,控制坐标轴的命令已经和常规不一样。因此先关闭该控制,然后开启常规坐标轴设置。
# r0 X! {" C1 ]& S 二、区域地图的绘制& r- t& {& _: G( r2 }1 T
当我们在某一小块区域研究时,需要绘制区域地图。此时我们可以引入命令: ax.set_extent(box,crs=ccrs.PlateCarree())
: O: E. u& z' N7 T: J- C 1' U' G8 l+ W \) S
其中box为绘制区域,crs为投影类型。其他命令基本不变。设置box为[40,180,0,90],可得到效果图如下: & F4 a% Z: ]- R8 K
# N: D0 r7 v& o9 H$ n( s
# |1 _. p0 o! x5 d1 Q 总结
& d& h) J, S& z. g/ V- { 为方便各位读者,我书写了绘制地图的函数,大家在使用时可直接调用。此处示例为方形投影,若希望绘制其他投影。只需要修改函数部分参数即可。代码如下: def map_make(scale,box,xstep,ystep):
4 P! I% J; C# a, O% X1 k ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=180))& }, `' a3 ^3 I9 P9 P1 n
a = (box[1]-box[0])//xstep
; d4 s5 a1 Q3 M% l: W5 q x_start = box[1] - a*xstep
1 g* N3 U1 N% Q. c" p% j1 l a = (box[3]-box[2])//ystep
5 Q0 E' l5 Y% D; y1 m8 r y_start = box[3] - a*ystep( [& r. \. \. k
ax.set_extent(box,crs=ccrs.PlateCarree())
3 @ ? s8 z4 Z# f3 s- n! r #ax.add_feature(cfeature.LAKES.with_scale(scale))
1 }" u6 M1 g9 @$ ^0 f3 I: u0 d #ax.add_feature(cfeature.OCEAN.with_scale(scale))
, N' g* A, b. d0 z6 u #ax.add_feature(cfeature.RIVERS.with_scale(scale))
& y# f& n d" f8 a, x& j) I, O Q #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)- _: I4 ~& Q; P) a
ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)
# R; k9 w. e9 e$ f$ o% l8 R
% l, G: a3 v! g: V6 m ax.set_xticks(np.arange(x_start,box[1]+xstep,xstep), crs=ccrs.PlateCarree())
. x* [ Z5 k$ n4 D7 z4 C& y% A ax.set_yticks(np.arange(y_start,box[3]+ystep,ystep), crs=ccrs.PlateCarree())& R$ \. Z* d9 Z
#zero_direction_label用来设置经度的0度加不加E和W
+ T' {8 }1 J4 r8 i" w lon_formatter = LongitudeFormatter(zero_direction_label=False)1 F3 i; d8 b4 U5 z5 T/ @& D1 n
lat_formatter = LatitudeFormatter()1 a6 k) O) h7 K6 g
ax.xaxis.set_major_formatter(lon_formatter)- j& @3 ~# z% R0 U# Z% _+ r
ax.yaxis.set_major_formatter(lat_formatter)
1 R& \! r9 Y6 N' \3 ` #添加网格线% C7 u8 i9 k6 s# n; [) N
ax.grid()
, a$ e0 [- |7 o' F
, I/ Y3 [' s0 ~/ p1 P7 l ax.outline_patch.set_visible(False)/ f1 t0 ~9 L8 T% I% N' b
ax.spines[bottom].set_visible(True): |! [% _1 \! U/ J' h3 E$ d- R
ax.spines[left].set_visible(True)6 U2 L! T( C9 |) t3 X9 X
ax.spines[right].set_visible(True)' ]2 d( g n+ J% _" t
ax.spines[top].set_visible(True)" d: A5 e- o7 S. ~* O( D( v, W
ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
A* {' a& m3 k7 W# u ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细# |1 H5 q$ |, X8 ?# ]
ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细; O2 G" [9 W9 }. A E
ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
! M2 l+ Q$ g+ m% \
* Q/ h5 R$ Z) k: U i9 h return ax最后多说一句,想学习Python可联系阿喵,这里有我自己整理的整套python学习资料和路线,想要这些资料的都可以关注阿喵,并私信“01”领取。 $ S- M1 S M# V# e Y; M
) B( r7 B [; z3 r$ w y6 Y# f* ~) Y; e+ s( d3 t
8 @% ]2 P0 ^; }8 i4 F( T3 P- e/ G5 ] b" j2 w
|