2 l/ S7 L$ }- I3 I 文章目录前言一、基础介绍二、区域地图的绘制总结前言
% `- P& U' ~! h+ y 常用地图底图的绘制一般由Basemap或者cartopy模块完成,由于Basemap库是基于python2开发的一个模块,目前已经不开发维护。故简单介绍cartopy模块的一些基础操作。
6 j- Y9 x5 T8 p: }' X A: ]% I- F
' X2 L4 Z3 A) p 如果大家在学习中遇到困难,想找一个python学习交流环境,可以加入我们的python裙,关注小编,并私信“01”即可进裙,领取python学习资料,会节约很多时间,减少很多遇到的难题。
5 `4 W5 T% _4 ] 一、基础介绍( g( D, w& h. p0 F' S
首先导入相关模块。 import numpy as np) K$ i) N5 \/ W- T5 o3 {. X% _
import matplotlib.pyplot as plt
4 x% I* u4 z4 ] import cartopy.crs as ccrs
. Z& D# m+ ^" }, l) P8 o% A' T+ r import cartopy.feature as cfeature
6 j6 ^ p# k, M8 m from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter& N: p I/ {8 o$ ^! F
12345
9 T5 t0 q6 O9 ~" u 首先介绍参数projection,该命令可以配合ccrs设置投影类型,此处以方形投影命令为示例。其中central_longitude参数为投影中心位置。其中心设置与Basemap设置规则一样,详情可以看上一篇文章。 ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=0))
/ U7 @6 ?4 K! t1 b. d( x) S 1在设置好绘制类型后,绘制地图各特征量。其代码如下: #ax.add_feature(cfeature.LAKES.with_scale(scale))
% o) M r: G/ E) ~% u/ P* I ax.add_feature(cfeature.OCEAN.with_scale(scale))
0 } X$ x, K1 b. u- F4 L' g0 X #ax.add_feature(cfeature.RIVERS.with_scale(scale))
# y! m' g- B1 k' W. ` #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)" n" A5 \ R u) s2 e" j' A- c- W
ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)/ H- Z* `0 h7 y1 L$ S+ K
12345
) [3 Y! m% ^, A9 @* m% x8 \/ z 参数scale为地图分辨率,目前支持10m,50m,110m,参数lw为线条粗细。此处绘制海岸线和海洋,效果图如下:
1 E/ N& g5 m0 B$ M4 F1 Y: {' {5 T& `0 {! z8 N g
6 V1 i2 ]& E" O; i2 P9 K
在绘制结束后,作为地图。经纬度自然是必不可少的,在该模块中,引进同时设置坐标轴标签改变该标签刻度的表示,具体形式如下: ax.set_xticks(np.arange(0,361,40), crs=ccrs.PlateCarree())3 W8 O5 {6 E2 H) F$ J1 u6 s) \
ax.set_yticks(np.arange(-90,90+30,30), crs=ccrs.PlateCarree())
/ L- J+ e1 x1 D: E/ m #zero_direction_label用来设置经度的0度加不加E和W% `, z* X4 G- w2 j5 ^ Z" l
lon_formatter = LongitudeFormatter(zero_direction_label=False)' d! M6 t" u- N9 r o! N: V- Y( i% F
lat_formatter = LatitudeFormatter()4 Q$ E0 c9 w1 I6 c' g7 f: _: D
ax.xaxis.set_major_formatter(lon_formatter)) w/ ]8 y; V ^
ax.yaxis.set_major_formatter(lat_formatter)
9 G7 L' j* D# R" w 1234567可以看到效果图如下: + J; Q8 ~/ |6 Z8 M1 \
1 p l" x7 i1 L% J$ E! K
& _0 D) I- Q& T3 p5 I& [
当然如果想对坐标轴粗细变化可以引入一下命令。 ax.outline_patch.set_visible(False)
. O% Y% ~! O$ K- G ax.spines[bottom].set_visible(True)
6 O; ^% A @2 E% R" y6 K! K ax.spines[left].set_visible(True)
1 f9 f4 F- g# b7 [5 m ax.spines[right].set_visible(True)7 E; y) `, T( L3 F/ @
ax.spines[top].set_visible(True)8 }1 ^. p" A6 X( j
ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
5 j' V6 h1 n; }' x; [" A ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细6 n, b5 u% ?7 A* O& ?
ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细
/ B% M, `' G" ?* R. V ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
6 \. T$ c7 B* L7 }) c. J0 ?, w; u8 d
12345678910应该在该模块下,控制坐标轴的命令已经和常规不一样。因此先关闭该控制,然后开启常规坐标轴设置。
$ K" R' U1 e. D! @% j& f 二、区域地图的绘制6 F; U- K$ @; n
当我们在某一小块区域研究时,需要绘制区域地图。此时我们可以引入命令: ax.set_extent(box,crs=ccrs.PlateCarree())
9 g9 H8 f" i3 s% x8 ~3 q8 ` 19 P- r7 V' j$ e2 Z
其中box为绘制区域,crs为投影类型。其他命令基本不变。设置box为[40,180,0,90],可得到效果图如下: 6 T! V' t' C& E# ]/ J* ]! ?
% w9 {+ D4 y% \ / y+ A; E) q. k' E- H1 B3 Z
总结
" _6 ]6 x! X9 c+ ^( _5 n# c/ M; z, Z 为方便各位读者,我书写了绘制地图的函数,大家在使用时可直接调用。此处示例为方形投影,若希望绘制其他投影。只需要修改函数部分参数即可。代码如下: def map_make(scale,box,xstep,ystep):: A7 U8 }# u( [' P$ Y
ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=180)); }4 f$ i2 e( m+ s* x" j
a = (box[1]-box[0])//xstep
+ h' h% Y4 e; G; U6 i$ d x_start = box[1] - a*xstep% e/ T i9 E) m- U
a = (box[3]-box[2])//ystep
0 ?( P. {& c3 e1 k$ h y_start = box[3] - a*ystep: H! g& o6 I! u8 @7 {- m1 `
ax.set_extent(box,crs=ccrs.PlateCarree())' w6 q# o( R# w
#ax.add_feature(cfeature.LAKES.with_scale(scale))+ W7 O$ {" B. p
#ax.add_feature(cfeature.OCEAN.with_scale(scale))
2 k0 j5 O5 U8 s+ a #ax.add_feature(cfeature.RIVERS.with_scale(scale))
' _4 h0 ?* R! \' \7 L2 ]& B #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)
& ]; C7 V: R. M" w* ~" J ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)
6 M7 a* ?1 l! }" o% w& H! f) j r4 ~6 o8 Z$ G, ^$ G
ax.set_xticks(np.arange(x_start,box[1]+xstep,xstep), crs=ccrs.PlateCarree())
! j# g' m* h% I$ |2 R( C ax.set_yticks(np.arange(y_start,box[3]+ystep,ystep), crs=ccrs.PlateCarree()) r% l2 l6 H- L) n9 {9 j b" d
#zero_direction_label用来设置经度的0度加不加E和W/ J4 g7 I1 `3 G2 I1 Y' H5 S
lon_formatter = LongitudeFormatter(zero_direction_label=False)2 q/ ^0 x' h. A" s; W5 [3 M0 q8 m
lat_formatter = LatitudeFormatter()
. L4 B4 @1 Q1 o( j8 Z* p ax.xaxis.set_major_formatter(lon_formatter)5 Y- p( c# P# s# S& m8 E
ax.yaxis.set_major_formatter(lat_formatter)
3 v9 c" k$ `" `2 x9 K3 I #添加网格线2 [ w2 F' r5 ?7 _% n* A8 b0 y/ h* k
ax.grid(), T `# u! Z; K
3 Y8 D* s) g5 C. Z
ax.outline_patch.set_visible(False)
/ U5 X# i2 o, C% V/ h! \ ax.spines[bottom].set_visible(True)+ A0 `+ a, J" h" `
ax.spines[left].set_visible(True)
* V. \6 ~' n2 h ax.spines[right].set_visible(True)
* k( v' C) O6 G' C ax.spines[top].set_visible(True)
& S8 K. x7 ^2 Q7 k( H( S H# B% W ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
& ?$ W t1 f: Z7 T ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细$ x" }, i# z( [3 z( x5 d
ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细* A/ F( i, W. @+ _# a
ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细6 q0 z0 S% N- `1 O, v9 k
3 V7 r; S' y5 J @+ e$ f; J3 I4 B
return ax最后多说一句,想学习Python可联系阿喵,这里有我自己整理的整套python学习资料和路线,想要这些资料的都可以关注阿喵,并私信“01”领取。
; \) M G) \! s
9 @2 x( R1 n$ x6 ]- j: c
; ?& W9 Q. w( {
" D" x8 h- }! {. D1 O4 Q: Q/ H
6 N! [6 L: `' t% c: q |