- n" I3 s- l2 J$ @$ V, _) n
文章目录前言一、基础介绍二、区域地图的绘制总结前言+ d* ]& L4 e/ d3 t
常用地图底图的绘制一般由Basemap或者cartopy模块完成,由于Basemap库是基于python2开发的一个模块,目前已经不开发维护。故简单介绍cartopy模块的一些基础操作。
3 B. h2 z: G1 s; m
5 z5 q& x4 b0 Y0 x: p& C/ H6 { 如果大家在学习中遇到困难,想找一个python学习交流环境,可以加入我们的python裙,关注小编,并私信“01”即可进裙,领取python学习资料,会节约很多时间,减少很多遇到的难题。
6 W2 u5 s! O% M ~2 o* |# ^# i 一、基础介绍
' f% R( J, d# K x. i 首先导入相关模块。 import numpy as np! W8 ~% ]) J6 z
import matplotlib.pyplot as plt6 c. Z6 d8 B' K- i
import cartopy.crs as ccrs
: l0 ?+ q8 |) S" m import cartopy.feature as cfeature
* S: K# e" |, X9 @3 y$ g from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
& m: K* S1 \: G/ p: V9 q 12345
+ f& J( E. Z, t( _/ u, I' W 首先介绍参数projection,该命令可以配合ccrs设置投影类型,此处以方形投影命令为示例。其中central_longitude参数为投影中心位置。其中心设置与Basemap设置规则一样,详情可以看上一篇文章。 ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=0))- |4 s7 N0 r% j$ A8 a
1在设置好绘制类型后,绘制地图各特征量。其代码如下: #ax.add_feature(cfeature.LAKES.with_scale(scale))6 N4 O1 i% @) u" L3 t
ax.add_feature(cfeature.OCEAN.with_scale(scale))5 r, m M0 Y+ W% x, X" k
#ax.add_feature(cfeature.RIVERS.with_scale(scale))
9 _1 R- U& Z: Z, u #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)
, g0 l( e% O' K% k% c ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)0 |; q# _. D2 [) v
123456 E) M7 S7 V. a) w
参数scale为地图分辨率,目前支持10m,50m,110m,参数lw为线条粗细。此处绘制海岸线和海洋,效果图如下: 1 p3 a5 t8 L' M% ?7 n
2 P. Q7 V4 k" N4 t% m6 `- \
% Z3 W: Z' I; _& E5 `
在绘制结束后,作为地图。经纬度自然是必不可少的,在该模块中,引进同时设置坐标轴标签改变该标签刻度的表示,具体形式如下: ax.set_xticks(np.arange(0,361,40), crs=ccrs.PlateCarree()). y0 H7 t0 {5 O- a$ w! s
ax.set_yticks(np.arange(-90,90+30,30), crs=ccrs.PlateCarree())+ O* ~. h) Y6 @
#zero_direction_label用来设置经度的0度加不加E和W' {1 @) P. e- y( Y0 c* {; v0 @
lon_formatter = LongitudeFormatter(zero_direction_label=False)1 ~( c, q% q/ C5 v7 ^* O
lat_formatter = LatitudeFormatter()
( M' f1 ?& ]0 a$ ~: s3 p2 U( o ax.xaxis.set_major_formatter(lon_formatter)% v+ U8 _* x! b2 w0 y& {6 T
ax.yaxis.set_major_formatter(lat_formatter)) K/ f3 f) W& l4 h- c* o
1234567可以看到效果图如下: : [. O4 f$ S- ^ C% a. v6 }
0 q, y2 ?& f _ / v& d' [2 \! y/ `
当然如果想对坐标轴粗细变化可以引入一下命令。 ax.outline_patch.set_visible(False)
* D/ g$ [" n" O, b% q ax.spines[bottom].set_visible(True)
- b+ T$ a. L2 i( K$ B ax.spines[left].set_visible(True)- K/ S1 s* w& d7 d9 o
ax.spines[right].set_visible(True)
, n% O$ t, F$ S0 A# f9 Z9 P ax.spines[top].set_visible(True)
. a* ^! u! C7 X7 e t ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细2 U* Z6 ^( c. b- H* H
ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细1 }# ]' k R3 _ w
ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细4 E5 A' c* \9 _9 p( x
ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细" ` t) g$ W( p" ` O
" i- |! r& H; L3 U" w& d+ E
12345678910应该在该模块下,控制坐标轴的命令已经和常规不一样。因此先关闭该控制,然后开启常规坐标轴设置。
. t( t: m b- G7 U1 [2 a 二、区域地图的绘制
+ p# k% t' T9 H& k5 D 当我们在某一小块区域研究时,需要绘制区域地图。此时我们可以引入命令: ax.set_extent(box,crs=ccrs.PlateCarree())
; E: F1 {; j6 E" c. m- d" A 1
3 d2 X! N. [* Z4 P) |) A8 y# w7 m; M 其中box为绘制区域,crs为投影类型。其他命令基本不变。设置box为[40,180,0,90],可得到效果图如下: } m) z! D7 B
6 n( p2 P G A& \. Q( r . T* l7 J( ~7 Q1 y7 D
总结0 |- s4 e+ ~# ^9 d3 F
为方便各位读者,我书写了绘制地图的函数,大家在使用时可直接调用。此处示例为方形投影,若希望绘制其他投影。只需要修改函数部分参数即可。代码如下: def map_make(scale,box,xstep,ystep):, |# k$ ^0 I8 ~
ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=180)); L$ c5 h" b A9 X Z
a = (box[1]-box[0])//xstep( c& }5 ^6 D; C2 ?
x_start = box[1] - a*xstep
' s; A6 `# o6 g& C' ~- d a = (box[3]-box[2])//ystep( H+ _% H' `4 s8 ~9 S+ Q, z* x
y_start = box[3] - a*ystep( N3 p/ Q2 v0 p& x, v) n
ax.set_extent(box,crs=ccrs.PlateCarree())
, a5 ~7 p8 N5 k" C p, K3 u #ax.add_feature(cfeature.LAKES.with_scale(scale))
( }6 E, U- ?$ Y2 s# v* _9 c #ax.add_feature(cfeature.OCEAN.with_scale(scale))
% ^% w: p' C! r3 Y$ m0 e #ax.add_feature(cfeature.RIVERS.with_scale(scale))% k8 o; L7 I/ @( v5 J7 ?9 [
#ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)
3 ]" Q8 b9 U% W: }. I4 H ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)
, T* u1 X& ^8 Q" P" g
" h' p6 L* U8 g5 }, d+ e7 d+ W( s4 K ax.set_xticks(np.arange(x_start,box[1]+xstep,xstep), crs=ccrs.PlateCarree())7 N, h$ m Y, Q
ax.set_yticks(np.arange(y_start,box[3]+ystep,ystep), crs=ccrs.PlateCarree()): D6 i5 N1 c) Y
#zero_direction_label用来设置经度的0度加不加E和W
+ H. [3 H$ L6 g* j8 r lon_formatter = LongitudeFormatter(zero_direction_label=False)
# v# C% Y0 `. u9 z/ Z6 T3 Z6 @. [# a lat_formatter = LatitudeFormatter()
/ G5 x3 s( f* W% d4 D) } ax.xaxis.set_major_formatter(lon_formatter)9 R/ G$ d* X" L: P f
ax.yaxis.set_major_formatter(lat_formatter)# p' H: F1 Y6 O- H6 G. p ?
#添加网格线! q9 g8 o$ `, t) Q8 U/ H, b1 a7 v- L
ax.grid()
: U* j% p) O% W
4 M/ x" U+ M2 G. j ax.outline_patch.set_visible(False)* p6 F" @/ w2 m! w' Y! ?
ax.spines[bottom].set_visible(True)
3 t; U" c5 j, t0 F" N ax.spines[left].set_visible(True)
# c- u$ A9 e7 [) H5 j* y ax.spines[right].set_visible(True)0 a% k7 o- F ]- W( |9 {7 }/ E% c3 ^
ax.spines[top].set_visible(True)
@+ h( H* S! N( i4 h- W" n ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细- h/ w+ j1 O/ K( e/ S
ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细9 b1 c3 o) q8 Y9 P
ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细
5 `" n C9 E/ z+ K3 D% O y# ~) H% j ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细2 ?4 N2 L6 m/ X9 W) O
) _7 U8 l2 H& N return ax最后多说一句,想学习Python可联系阿喵,这里有我自己整理的整套python学习资料和路线,想要这些资料的都可以关注阿喵,并私信“01”领取。 * D, [ e+ E8 p6 j2 o$ H% m5 u
, h) A7 X" ]0 |
. l8 k6 e$ g" G) s3 o% m: L, [" H' W6 W) h1 O
) r4 T. }& Z5 v/ O7 d |