8 _" g" Y8 B2 ~# G 文章目录前言一、基础介绍二、区域地图的绘制总结前言+ L% i3 H3 n& h* d: D
常用地图底图的绘制一般由Basemap或者cartopy模块完成,由于Basemap库是基于python2开发的一个模块,目前已经不开发维护。故简单介绍cartopy模块的一些基础操作。 ! C* R3 {! `0 `1 \' ?4 g7 T7 ]
5 X( ?; U" h J% U: Q8 x
如果大家在学习中遇到困难,想找一个python学习交流环境,可以加入我们的python裙,关注小编,并私信“01”即可进裙,领取python学习资料,会节约很多时间,减少很多遇到的难题。
/ L% _! S7 \8 Z 一、基础介绍
/ V, }7 V9 f/ p3 s( s 首先导入相关模块。 import numpy as np
+ o1 R8 p$ N8 A% ^. b6 @' P import matplotlib.pyplot as plt
8 D$ ~; {6 e1 t) j/ V$ s import cartopy.crs as ccrs
5 I5 @0 P& w, F4 _3 h$ a, f import cartopy.feature as cfeature7 U, \& p" {" `8 S8 Q$ U# Z# z$ }
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
# s/ Q3 G- V% h7 x" D' i 12345
5 W9 X: P/ @# S 首先介绍参数projection,该命令可以配合ccrs设置投影类型,此处以方形投影命令为示例。其中central_longitude参数为投影中心位置。其中心设置与Basemap设置规则一样,详情可以看上一篇文章。 ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=0))! C% K0 q$ j1 y+ i9 y) _
1在设置好绘制类型后,绘制地图各特征量。其代码如下: #ax.add_feature(cfeature.LAKES.with_scale(scale))
- b1 N2 K, |8 x$ l" B4 S q ax.add_feature(cfeature.OCEAN.with_scale(scale))
# D y- @) A/ w( ]& O #ax.add_feature(cfeature.RIVERS.with_scale(scale))
: I. R5 P% t7 F/ L/ @+ B5 c #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)
& k6 G$ w9 O7 E& A' p% P ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2); M* _) w" j+ w& f7 u2 b) |# ^
12345
4 ^4 d/ q1 a4 W5 N+ t 参数scale为地图分辨率,目前支持10m,50m,110m,参数lw为线条粗细。此处绘制海岸线和海洋,效果图如下: * @) _9 S8 B& ^
1 l9 i$ I I( i, x $ e# [1 X4 I* R
在绘制结束后,作为地图。经纬度自然是必不可少的,在该模块中,引进同时设置坐标轴标签改变该标签刻度的表示,具体形式如下: ax.set_xticks(np.arange(0,361,40), crs=ccrs.PlateCarree())4 ]4 E [& E* v/ p
ax.set_yticks(np.arange(-90,90+30,30), crs=ccrs.PlateCarree()); ~9 G1 Z0 \* O4 Q; q7 V* S
#zero_direction_label用来设置经度的0度加不加E和W
. d" I% f4 ?% u lon_formatter = LongitudeFormatter(zero_direction_label=False)3 ^) ^% K" Q9 U) i) v. x+ E
lat_formatter = LatitudeFormatter()! R& B& j/ m8 f
ax.xaxis.set_major_formatter(lon_formatter)
2 z, z5 ?$ m, k; n! P ax.yaxis.set_major_formatter(lat_formatter)9 {5 h3 b5 ?$ x/ E! j
1234567可以看到效果图如下: , `' ^( C3 P; Y$ C0 s1 b8 c* k
/ T7 \* v1 l9 c% v
4 s O* P4 N1 @" t 当然如果想对坐标轴粗细变化可以引入一下命令。 ax.outline_patch.set_visible(False)
6 Y: j9 u3 y. Y& j+ l5 H ax.spines[bottom].set_visible(True)
) X) V) X! c( P0 o+ S ax.spines[left].set_visible(True)0 t7 X( a. p$ s$ r4 T* |
ax.spines[right].set_visible(True)
" T# D' J3 _& v3 x$ D$ y ax.spines[top].set_visible(True)
1 {7 |3 N8 L# _6 j2 Y- _ ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
" s! b! w# @! g2 O! c ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细- u% ?, o+ X' t2 J+ q
ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细
+ @" D7 p, G9 H8 a E7 [ ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
' ?, `" S& O& u: a, Z p
7 I3 r! o8 b# W 12345678910应该在该模块下,控制坐标轴的命令已经和常规不一样。因此先关闭该控制,然后开启常规坐标轴设置。 ) `# z/ Y! v. W, x. B+ }
二、区域地图的绘制* t# I+ @1 r, D7 \0 M- s4 f) y
当我们在某一小块区域研究时,需要绘制区域地图。此时我们可以引入命令: ax.set_extent(box,crs=ccrs.PlateCarree())
* S; U3 t+ z3 _7 K# c" n* | }& u 1
% @5 R/ j0 i5 o 其中box为绘制区域,crs为投影类型。其他命令基本不变。设置box为[40,180,0,90],可得到效果图如下: 4 |1 B g( l: x1 x! h5 t4 U `0 i
: ]2 L. I F6 U7 t9 Q) V
/ a& |' Q' S# H* r( x% { 总结% S( c( z" @+ v h+ M+ d" T
为方便各位读者,我书写了绘制地图的函数,大家在使用时可直接调用。此处示例为方形投影,若希望绘制其他投影。只需要修改函数部分参数即可。代码如下: def map_make(scale,box,xstep,ystep):
$ ~! n, Z$ T8 D ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
2 b* B# L& K& a, z a = (box[1]-box[0])//xstep
" [3 G( ^& Q( O1 y* H x_start = box[1] - a*xstep7 p/ X7 _9 N6 W) s
a = (box[3]-box[2])//ystep
& ]% k5 W- G( B! g1 y y_start = box[3] - a*ystep
( H8 d+ A" h( O5 h1 m& p' j ax.set_extent(box,crs=ccrs.PlateCarree())
x* I4 B* R0 T6 j3 `7 B #ax.add_feature(cfeature.LAKES.with_scale(scale))
( u% E1 _3 O# [9 `' f. A; F0 i #ax.add_feature(cfeature.OCEAN.with_scale(scale)), S6 n! m3 o: M
#ax.add_feature(cfeature.RIVERS.with_scale(scale))
1 g2 K# S. M: C #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)
8 X6 T6 ^, f w" u0 `( E6 u1 Z9 y# B6 Z ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)2 P4 m( z7 A' k/ d; }' Z
3 ?0 _: X- j3 r. o" I: T ax.set_xticks(np.arange(x_start,box[1]+xstep,xstep), crs=ccrs.PlateCarree())
3 T- c1 T" o1 X ax.set_yticks(np.arange(y_start,box[3]+ystep,ystep), crs=ccrs.PlateCarree())
0 h" @* n# \+ W( ~! v; G% k1 E7 T #zero_direction_label用来设置经度的0度加不加E和W& C% y: p6 O* C/ r% P/ o
lon_formatter = LongitudeFormatter(zero_direction_label=False)
% N Z( W3 ^$ s4 w3 G0 g. f lat_formatter = LatitudeFormatter()
e: X- l( M w/ Y9 Y ax.xaxis.set_major_formatter(lon_formatter)
: S( b' q- V7 b- Z, ]. k. [ ax.yaxis.set_major_formatter(lat_formatter)2 k7 f# ~+ \8 D2 [
#添加网格线
. G$ I3 |8 f3 x d% F' U ax.grid()
^4 B7 Y9 T: Y+ i K0 @; l/ A- e* X+ X! Y# q& d
ax.outline_patch.set_visible(False)8 O( `. R! h& k) }
ax.spines[bottom].set_visible(True)6 {, H% ?9 R1 \! N* r: [
ax.spines[left].set_visible(True)/ G) q0 q0 o; }* B- k$ H& ] J
ax.spines[right].set_visible(True)
* p. A! S7 u8 v" v: z l# O8 M5 G ax.spines[top].set_visible(True)8 e8 M: {6 u8 o7 r/ p3 z
ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
1 T$ D) ~. F8 }( Y$ a! r ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细
0 v8 L7 h' @6 l" V6 N x ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细 g, v( }' d8 T! G$ k
ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
8 _8 x' ?6 Z8 Z$ r3 \
) F6 v& I9 x% ~' { return ax最后多说一句,想学习Python可联系阿喵,这里有我自己整理的整套python学习资料和路线,想要这些资料的都可以关注阿喵,并私信“01”领取。 1 I" u; K# ^$ i- h% w" T5 \0 F0 T
' v) ]# f2 l) K# ]( O9 z
! w7 E! r- W$ j/ W! e9 o
& h# t) q6 c) l$ B" W, C
& c, S3 t( g+ }2 \5 R2 Q! S8 { |