* q- a2 T3 w$ |+ _0 z
文章目录前言一、基础介绍二、区域地图的绘制总结前言
1 k1 R2 K, S: d% Y 常用地图底图的绘制一般由Basemap或者cartopy模块完成,由于Basemap库是基于python2开发的一个模块,目前已经不开发维护。故简单介绍cartopy模块的一些基础操作。 ( a+ J. [$ ~5 V R
" d( L) _/ r# {; b 如果大家在学习中遇到困难,想找一个python学习交流环境,可以加入我们的python裙,关注小编,并私信“01”即可进裙,领取python学习资料,会节约很多时间,减少很多遇到的难题。
/ T2 P2 ?; \7 P# l0 i, j k6 x 一、基础介绍
+ y0 f8 f1 W; h2 i4 Q/ ]& W0 E$ } 首先导入相关模块。 import numpy as np
# z7 L9 `$ p( H! B" a/ _ import matplotlib.pyplot as plt
2 y* M- G' l* X+ @& c, ? import cartopy.crs as ccrs
( O8 i* O/ v- J) Y import cartopy.feature as cfeature4 k0 R0 w/ l4 _7 x. S, w) L, r. |
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter9 w( B& h1 J$ a- H* g1 O
12345. B) |! [/ W* g/ R& R/ [1 Y* p; a
首先介绍参数projection,该命令可以配合ccrs设置投影类型,此处以方形投影命令为示例。其中central_longitude参数为投影中心位置。其中心设置与Basemap设置规则一样,详情可以看上一篇文章。 ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=0))
7 `; E+ O z! Q/ v; h3 Q 1在设置好绘制类型后,绘制地图各特征量。其代码如下: #ax.add_feature(cfeature.LAKES.with_scale(scale))
- {9 E6 l, g+ U1 d3 z* H2 |0 O$ A ax.add_feature(cfeature.OCEAN.with_scale(scale))
0 e8 Y/ l+ S+ N #ax.add_feature(cfeature.RIVERS.with_scale(scale))
2 [* u& l, w& C8 s #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)
. C+ ^7 [- H3 K# ^! {2 H$ h/ [ ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)
# u. P5 v/ X( j E" S- M: t 123455 p. E2 M: J- H
参数scale为地图分辨率,目前支持10m,50m,110m,参数lw为线条粗细。此处绘制海岸线和海洋,效果图如下:
2 h( [7 E- u" ?# f9 m3 `; k# D4 N& b4 W) t: R
* x# |" c- u% o) R6 i% n9 n/ M
在绘制结束后,作为地图。经纬度自然是必不可少的,在该模块中,引进同时设置坐标轴标签改变该标签刻度的表示,具体形式如下: ax.set_xticks(np.arange(0,361,40), crs=ccrs.PlateCarree())
) Q0 w, p6 U2 m) H) _ ax.set_yticks(np.arange(-90,90+30,30), crs=ccrs.PlateCarree())
0 t2 }9 o- |; ?# G #zero_direction_label用来设置经度的0度加不加E和W9 B+ L$ X2 e+ M! M. Q8 t2 ^$ Q2 z4 l
lon_formatter = LongitudeFormatter(zero_direction_label=False)
" _% S+ s& J% g6 ` lat_formatter = LatitudeFormatter()' k! W: k4 Y$ ?! f& E% x% J& d
ax.xaxis.set_major_formatter(lon_formatter)
& T5 s7 U- b$ ` ax.yaxis.set_major_formatter(lat_formatter)1 ]0 R+ b! i" w* M
1234567可以看到效果图如下:
& s( J5 U& X1 f' m u2 F+ \6 j* l, S; U1 E- |! R4 P& a/ Y. f! ^! U3 u
, l, P5 t' @% l4 R# Q: X
当然如果想对坐标轴粗细变化可以引入一下命令。 ax.outline_patch.set_visible(False)
8 d! E' y1 G) @9 Q- B* K6 d ax.spines[bottom].set_visible(True)0 ?' p+ d5 @# d w: \
ax.spines[left].set_visible(True)7 A9 K5 M8 c1 z3 k8 T1 f
ax.spines[right].set_visible(True)
" ^ H9 A* E# \* j ax.spines[top].set_visible(True)
: Q$ C$ @( [: N, N2 D5 w9 { ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细! O6 x2 S# K9 g3 g. d
ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细
8 U ], j& x* g* V ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细3 ~' K8 @! e' I% B, i: Z( t
ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
. e; p d R8 e1 K3 H! S: m9 D* \+ h4 f8 ?# `2 b' D- i
12345678910应该在该模块下,控制坐标轴的命令已经和常规不一样。因此先关闭该控制,然后开启常规坐标轴设置。 + u& Y1 X- K/ U% @* e. Q7 X
二、区域地图的绘制6 `9 j: H! @7 B+ W
当我们在某一小块区域研究时,需要绘制区域地图。此时我们可以引入命令: ax.set_extent(box,crs=ccrs.PlateCarree())
3 S/ t: S) e6 S1 @7 x$ p 1
( F2 z4 F3 G2 U' v* N4 Q; a 其中box为绘制区域,crs为投影类型。其他命令基本不变。设置box为[40,180,0,90],可得到效果图如下:
: V' `9 e3 r/ p A
# P2 n5 x" n9 C! x/ M* o, z5 h7 m
* ? D5 I W: g/ e3 D0 | 总结; h/ l5 z1 m3 j( @% Z
为方便各位读者,我书写了绘制地图的函数,大家在使用时可直接调用。此处示例为方形投影,若希望绘制其他投影。只需要修改函数部分参数即可。代码如下: def map_make(scale,box,xstep,ystep):
8 j* Q: \3 l: ]% f) y) S J: ] ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=180))3 n) C# F' d5 W7 p7 q
a = (box[1]-box[0])//xstep
8 p/ P* g( u( m* i% { x_start = box[1] - a*xstep! G7 \9 w# V0 ?; s0 U
a = (box[3]-box[2])//ystep0 M+ X8 o) z: | p, K
y_start = box[3] - a*ystep; w4 d- B0 C9 b, [
ax.set_extent(box,crs=ccrs.PlateCarree())
8 D% E1 _+ F* L+ Y6 `- B; G #ax.add_feature(cfeature.LAKES.with_scale(scale)) P8 w2 d5 r0 _8 S: r
#ax.add_feature(cfeature.OCEAN.with_scale(scale))
; E+ E; d u4 {' c9 h; T6 @8 O$ w- y #ax.add_feature(cfeature.RIVERS.with_scale(scale))
! C2 ^# ~+ s4 b! Z3 r* D- ] #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)% U7 o3 E* `% b5 S
ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2); H5 v# ]/ d U A
5 M8 W, G4 H7 g, T+ x M0 d1 A
ax.set_xticks(np.arange(x_start,box[1]+xstep,xstep), crs=ccrs.PlateCarree())' m+ S% }% z- }9 L
ax.set_yticks(np.arange(y_start,box[3]+ystep,ystep), crs=ccrs.PlateCarree())5 j( h& Q3 H' ?/ }2 U
#zero_direction_label用来设置经度的0度加不加E和W
) H- j4 `$ N1 o$ A: ] ^; W lon_formatter = LongitudeFormatter(zero_direction_label=False)8 f8 {1 m: P: ~$ G" k
lat_formatter = LatitudeFormatter()
5 R+ M7 n/ b. |$ s; i ax.xaxis.set_major_formatter(lon_formatter)
) w2 P4 d* Q" _( G ax.yaxis.set_major_formatter(lat_formatter)6 c+ a4 Z2 k) W) @" O
#添加网格线
& b U( `7 R5 E( [2 J ax.grid()9 w" @0 d% w4 z7 O6 R
7 P$ u w, d6 H: d9 L- h
ax.outline_patch.set_visible(False)
' R6 G) L( ~$ e: u: H ax.spines[bottom].set_visible(True)
8 Y5 A/ z$ U+ h ax.spines[left].set_visible(True)6 R3 o- _- T: o( Z/ x* P
ax.spines[right].set_visible(True)
$ [8 V0 g/ r' H" z ax.spines[top].set_visible(True)0 N& }% {* `0 i- b- M7 ~
ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
$ x8 R' y8 M; f0 C6 T ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细/ A2 J) G# S* ^( Y# `$ @
ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细1 T" s. L+ q. g+ ^1 I* n! v
ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细: n) f K# v6 \& a0 @8 \; r
; z7 D {: ^- d; X return ax最后多说一句,想学习Python可联系阿喵,这里有我自己整理的整套python学习资料和路线,想要这些资料的都可以关注阿喵,并私信“01”领取。
! q, l, V3 A. s" u2 L. |& T$ D- n) R: K/ d2 k* s. u
& c. e& b7 \, @0 I
* j: t" f( B: D' X; Z2 {8 Y
7 _$ _: j! A$ {4 |% N5 X5 c$ f |