" p1 g" S; p% `; F. I. r 文章目录前言一、基础介绍二、区域地图的绘制总结前言
) I, u! }$ ~+ y( o 常用地图底图的绘制一般由Basemap或者cartopy模块完成,由于Basemap库是基于python2开发的一个模块,目前已经不开发维护。故简单介绍cartopy模块的一些基础操作。
( M6 V: K7 d2 s9 [ : ~. \' g- m2 } _- J" l8 D
如果大家在学习中遇到困难,想找一个python学习交流环境,可以加入我们的python裙,关注小编,并私信“01”即可进裙,领取python学习资料,会节约很多时间,减少很多遇到的难题。 . t. X" l' _! ?
一、基础介绍
1 g" C; c: ^1 l+ L3 [" a! S 首先导入相关模块。 import numpy as np* X+ M$ h0 M7 l2 q' p: f
import matplotlib.pyplot as plt/ `9 ^3 S8 Y: Y* F i
import cartopy.crs as ccrs
4 C6 {! [1 _4 U import cartopy.feature as cfeature \) X1 F* I9 r+ U
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
3 Q$ R* a8 E2 N2 _( J) r: P0 z 12345! t/ I9 y* Z2 a9 S% v/ k
首先介绍参数projection,该命令可以配合ccrs设置投影类型,此处以方形投影命令为示例。其中central_longitude参数为投影中心位置。其中心设置与Basemap设置规则一样,详情可以看上一篇文章。 ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=0))# Z! T$ b/ c+ ?
1在设置好绘制类型后,绘制地图各特征量。其代码如下: #ax.add_feature(cfeature.LAKES.with_scale(scale))
4 i& P+ |% z6 v$ T ax.add_feature(cfeature.OCEAN.with_scale(scale))/ h8 p% {4 \/ y# D3 W r2 W% V
#ax.add_feature(cfeature.RIVERS.with_scale(scale))8 b4 I4 @1 F" {
#ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)' U' g7 i" j$ J( k; H
ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)
0 R# F) z; D2 o' p |4 L 123457 ~/ P; Q9 }, r& H* Y; i
参数scale为地图分辨率,目前支持10m,50m,110m,参数lw为线条粗细。此处绘制海岸线和海洋,效果图如下:
# X6 V) i4 k, Z" g' ^0 n
( Z: c$ _: [0 Z
3 y6 T8 u) | A7 q j7 M 在绘制结束后,作为地图。经纬度自然是必不可少的,在该模块中,引进同时设置坐标轴标签改变该标签刻度的表示,具体形式如下: ax.set_xticks(np.arange(0,361,40), crs=ccrs.PlateCarree())
0 W; @2 T) B6 ~* q5 C/ {6 l' m ax.set_yticks(np.arange(-90,90+30,30), crs=ccrs.PlateCarree())
* n- ]) L+ ^; } #zero_direction_label用来设置经度的0度加不加E和W( V& c+ b6 [4 i7 z$ j% t
lon_formatter = LongitudeFormatter(zero_direction_label=False)
% z7 S3 D! _' y, H lat_formatter = LatitudeFormatter()7 R2 H! N1 ]$ S. D+ x0 ~+ s
ax.xaxis.set_major_formatter(lon_formatter)
6 L( I1 [' b0 k! A ax.yaxis.set_major_formatter(lat_formatter)
" x9 R6 Y3 `" |# @9 R 1234567可以看到效果图如下:
- ]$ H6 s4 L) {5 _; F1 p8 R9 O1 I/ |1 y' F8 d' j
1 v5 O; ?3 I2 e# F 当然如果想对坐标轴粗细变化可以引入一下命令。 ax.outline_patch.set_visible(False)# m% C$ t" E5 w2 r# C" H! f
ax.spines[bottom].set_visible(True)
$ j8 h9 A8 }5 K ax.spines[left].set_visible(True)
# M) K* }" Q- z) Y: g* P ax.spines[right].set_visible(True)
6 s9 J- e0 p0 I' P7 O, e4 v ax.spines[top].set_visible(True)
* n5 J: X" J! @6 h; J+ z* _ ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
/ y2 s: ]1 N9 u0 y7 ^0 B6 k ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细
6 f# ?/ h5 l- { ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细" i8 L9 ?" |9 Y4 q7 p
ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
8 }! Z( L, k! e6 A
9 h1 W- [ R, G, x4 i 12345678910应该在该模块下,控制坐标轴的命令已经和常规不一样。因此先关闭该控制,然后开启常规坐标轴设置。
+ V" v5 n/ A" ?+ O 二、区域地图的绘制5 B+ Q) Y$ @; O1 k* m6 v7 Z i& {
当我们在某一小块区域研究时,需要绘制区域地图。此时我们可以引入命令: ax.set_extent(box,crs=ccrs.PlateCarree())0 V9 J0 b. y, s2 R, T2 O
1
l' {! |1 Y% Z; V' }5 i; m 其中box为绘制区域,crs为投影类型。其他命令基本不变。设置box为[40,180,0,90],可得到效果图如下:
6 r$ }( I1 X/ D" ^; \) Q3 z6 l: E9 A2 s7 K+ I2 _ b
! _4 J: I/ {8 p8 j' h( H: F& [- y 总结( V. p. k2 H! t# M3 s
为方便各位读者,我书写了绘制地图的函数,大家在使用时可直接调用。此处示例为方形投影,若希望绘制其他投影。只需要修改函数部分参数即可。代码如下: def map_make(scale,box,xstep,ystep):; h/ T3 f7 C/ w1 _: p
ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=180))# l1 P+ a6 a0 `6 j
a = (box[1]-box[0])//xstep
% m4 F) T% ?' `5 J" n: _) k1 j+ q( n x_start = box[1] - a*xstep& c0 f" ~8 g. I* t
a = (box[3]-box[2])//ystep
2 E/ N3 ~/ ~( b3 z3 w7 S7 [ y_start = box[3] - a*ystep: H6 x* g( x0 p) s
ax.set_extent(box,crs=ccrs.PlateCarree())3 M! r, ?( K; i2 X$ k
#ax.add_feature(cfeature.LAKES.with_scale(scale))! ?! q6 M! _* Y
#ax.add_feature(cfeature.OCEAN.with_scale(scale))! {6 N0 Y6 D+ C0 `, n, ?& Z! \* `
#ax.add_feature(cfeature.RIVERS.with_scale(scale)) z/ @# C* u p
#ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)
1 C4 `. l+ e$ w# o7 R4 x ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)" o+ a- U2 A" p3 Z1 N+ {# S% ~' b
; E+ E- [* O1 B* t( Y% O$ q
ax.set_xticks(np.arange(x_start,box[1]+xstep,xstep), crs=ccrs.PlateCarree())! w, e) Q5 r/ k6 Q( |$ U& d: X
ax.set_yticks(np.arange(y_start,box[3]+ystep,ystep), crs=ccrs.PlateCarree())
$ ^ i4 j; b& o9 o5 [ #zero_direction_label用来设置经度的0度加不加E和W
, r4 V6 K& \4 T* ?7 | lon_formatter = LongitudeFormatter(zero_direction_label=False)
2 ^. M( e5 ?* J0 E! S: \ lat_formatter = LatitudeFormatter()
# t6 B/ f! A0 C) h* v3 y5 g ax.xaxis.set_major_formatter(lon_formatter)
/ J8 w H; Z, k" h ax.yaxis.set_major_formatter(lat_formatter)
& s4 M+ r3 o) B9 I #添加网格线
8 b( G+ F% @$ j ax.grid()* Q4 v9 ]% F2 m0 e5 e
y' F; f, H" N6 Z U# Q$ G* t
ax.outline_patch.set_visible(False)2 D# W& Q# |2 Y1 E U
ax.spines[bottom].set_visible(True)
9 ^- x* R0 x1 w, g( o2 W ax.spines[left].set_visible(True)
% l1 j( W$ X& L+ U+ j/ d4 Y' Z, x ax.spines[right].set_visible(True)+ }4 T) h; i# t8 M3 @8 W
ax.spines[top].set_visible(True)
+ f/ G- v4 y/ U5 T ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
9 E) B* Y8 q& _9 M% l. ?; z9 l ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细
9 b0 G8 P. ^; O9 i ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细. x2 a: f) t! M. G
ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细2 L" l5 @; f0 D! i# Y$ {+ v! t" Q
8 V2 u* i, J- L: W return ax最后多说一句,想学习Python可联系阿喵,这里有我自己整理的整套python学习资料和路线,想要这些资料的都可以关注阿喵,并私信“01”领取。
$ s: o8 R8 B6 |/ h5 u8 E0 e" z
& ?# o1 p; R, b2 V) u4 E2 ~( m' n2 f' d6 |' B4 m
; b. X$ v$ J# E3 f
8 d4 M, o0 D" R) h h |