+ v$ S7 o1 L3 _5 ^ x 文章目录前言一、基础介绍二、区域地图的绘制总结前言
1 S ^7 E# }$ X) P 常用地图底图的绘制一般由Basemap或者cartopy模块完成,由于Basemap库是基于python2开发的一个模块,目前已经不开发维护。故简单介绍cartopy模块的一些基础操作。 8 V2 A1 @; ^; ^0 {9 {# W4 O4 V
6 X# E" v; w) p; U" Q7 X
如果大家在学习中遇到困难,想找一个python学习交流环境,可以加入我们的python裙,关注小编,并私信“01”即可进裙,领取python学习资料,会节约很多时间,减少很多遇到的难题。
I0 }/ }2 y4 E! n0 q r6 ?- u j 一、基础介绍
5 `& c& ?( v; H+ K6 o. n4 ?& l 首先导入相关模块。 import numpy as np# |2 R, V) v* T K
import matplotlib.pyplot as plt, ]) A/ x* c! Q% F+ ?
import cartopy.crs as ccrs
5 l9 K0 e y1 z8 s2 u import cartopy.feature as cfeature( V2 ^9 X) j+ W
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
) ^& H8 i( {( R1 s C 12345+ e* h8 w6 ]% n) B" m7 e: S( `% \
首先介绍参数projection,该命令可以配合ccrs设置投影类型,此处以方形投影命令为示例。其中central_longitude参数为投影中心位置。其中心设置与Basemap设置规则一样,详情可以看上一篇文章。 ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=0))8 S7 L5 X9 [& l' p: @! e
1在设置好绘制类型后,绘制地图各特征量。其代码如下: #ax.add_feature(cfeature.LAKES.with_scale(scale))
+ `* c2 |1 x+ n ax.add_feature(cfeature.OCEAN.with_scale(scale))' ?$ k. `) X; n2 |) n/ S* L
#ax.add_feature(cfeature.RIVERS.with_scale(scale))6 j& X) \( ~* M" F$ N* M
#ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)7 D e9 P3 Y2 T$ ~' X6 `3 A
ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)
- F7 E' j) g8 \ 12345
/ Y a }0 p9 V7 i3 M0 x% [ 参数scale为地图分辨率,目前支持10m,50m,110m,参数lw为线条粗细。此处绘制海岸线和海洋,效果图如下: - \- I$ r% V, y$ Y% ^1 m) d
7 ~) i" `6 H/ s$ K" {# _
5 ~4 N" v- r% R0 F0 [: U) ~ 在绘制结束后,作为地图。经纬度自然是必不可少的,在该模块中,引进同时设置坐标轴标签改变该标签刻度的表示,具体形式如下: ax.set_xticks(np.arange(0,361,40), crs=ccrs.PlateCarree())
# A% A2 W( B. l$ d1 ] Q0 L0 h: y ax.set_yticks(np.arange(-90,90+30,30), crs=ccrs.PlateCarree())
1 d* y4 Z1 z: h, C( \# u #zero_direction_label用来设置经度的0度加不加E和W& Z/ {$ p: g7 s
lon_formatter = LongitudeFormatter(zero_direction_label=False)# l7 c2 F6 q7 P; ]( j* P. q
lat_formatter = LatitudeFormatter()
, N! e7 s7 D7 m* u( m ax.xaxis.set_major_formatter(lon_formatter)/ p% a5 ~% ^ X- g: s; A
ax.yaxis.set_major_formatter(lat_formatter)5 ]' K u" l0 h0 a3 ^4 c
1234567可以看到效果图如下: # G& C5 F" s" P( M6 N6 t
& h& _5 m# D6 ~
7 Y7 L4 ~9 `+ I9 N7 |0 A
当然如果想对坐标轴粗细变化可以引入一下命令。 ax.outline_patch.set_visible(False)
, ?1 m' n/ r- ` ax.spines[bottom].set_visible(True): R6 N1 z0 L8 ^& k3 _4 F, A; }
ax.spines[left].set_visible(True)
: N5 g6 ?/ z3 }3 e. K ax.spines[right].set_visible(True)
; V$ d, D. N/ T7 x7 h6 k ax.spines[top].set_visible(True)8 M( I( W6 r4 G/ b9 c8 n8 G
ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细; e3 o3 S7 v |
ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细
# E ^. T7 s2 a5 e- Q$ n ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细
6 K5 |* g) M! S1 [) y% T- f( k3 d ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
- x$ j0 l) _" m' m( t) S) p- U4 W7 R
12345678910应该在该模块下,控制坐标轴的命令已经和常规不一样。因此先关闭该控制,然后开启常规坐标轴设置。 3 c+ I9 `$ f( D
二、区域地图的绘制 m$ A+ _, o% z% A8 {: Y5 d
当我们在某一小块区域研究时,需要绘制区域地图。此时我们可以引入命令: ax.set_extent(box,crs=ccrs.PlateCarree())" t4 a- ^8 Z4 b; h
1
4 R" }# H# D7 h) d 其中box为绘制区域,crs为投影类型。其他命令基本不变。设置box为[40,180,0,90],可得到效果图如下:
2 G4 o4 F5 C1 l5 h' H8 }
! z6 g( z5 Q/ J, u# l " @# p' p& h' Y% [. S
总结 C5 O n$ R! J: b/ S
为方便各位读者,我书写了绘制地图的函数,大家在使用时可直接调用。此处示例为方形投影,若希望绘制其他投影。只需要修改函数部分参数即可。代码如下: def map_make(scale,box,xstep,ystep):3 C% h% N# Q2 C d$ y' J
ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
$ v0 X) d5 H5 L7 J5 n# e! Q a = (box[1]-box[0])//xstep; I: X! p0 ~% n6 V! Y1 ~% H0 m
x_start = box[1] - a*xstep4 j7 G% K9 u3 R. x/ N ]6 M
a = (box[3]-box[2])//ystep4 p; T( V9 i4 j. p# g* Z1 h: O
y_start = box[3] - a*ystep6 U) ~) ]# n C% I" g: Q/ n( D
ax.set_extent(box,crs=ccrs.PlateCarree())
6 Y5 `5 ]* l. K #ax.add_feature(cfeature.LAKES.with_scale(scale))" _' _' ?3 B6 l0 R5 O: v- l
#ax.add_feature(cfeature.OCEAN.with_scale(scale))
" j6 s1 s& @ ]- |0 b; x: ` #ax.add_feature(cfeature.RIVERS.with_scale(scale)) N! r! x5 H4 r0 h6 {7 [' h* Q
#ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)1 E7 i) D( c- d0 s7 N
ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)6 |4 x4 j9 @4 `
8 x" I( {! e3 S# e! o
ax.set_xticks(np.arange(x_start,box[1]+xstep,xstep), crs=ccrs.PlateCarree())
/ K6 X) j. R1 {( x+ U" P. O ax.set_yticks(np.arange(y_start,box[3]+ystep,ystep), crs=ccrs.PlateCarree())
/ s$ v' n, U7 b: G( l$ k# \) N #zero_direction_label用来设置经度的0度加不加E和W
7 x9 F$ e! j! x, J0 k# E lon_formatter = LongitudeFormatter(zero_direction_label=False)1 K6 k" j* G& W' N
lat_formatter = LatitudeFormatter()7 D/ V2 i& [9 K, O
ax.xaxis.set_major_formatter(lon_formatter)" W) M% l* \# I
ax.yaxis.set_major_formatter(lat_formatter)
* Y5 ]& k; ~& ^: N1 p3 h# `+ y% A #添加网格线
5 n- h" |+ N2 M4 a# _ ax.grid()
: o$ D& y% d* G
4 F$ x) Z0 l! C! ?3 j ax.outline_patch.set_visible(False): f/ D' F& P I
ax.spines[bottom].set_visible(True)1 [9 N9 l$ Q. u* w% A0 @/ r
ax.spines[left].set_visible(True)
! r4 J# B m+ q8 K* l ax.spines[right].set_visible(True)
5 {+ y' b8 {4 k& |0 }$ M9 p ax.spines[top].set_visible(True)
% M# u [) x; N; P2 n! d% P: r2 p ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细
* A7 d; z* \! f ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细
$ o" X. p9 Q+ Y# Z! t. ? ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细0 L" J, J4 c5 A4 [8 \' z
ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细
$ f3 `( N$ f( u5 x$ H8 {: t0 r% s+ G- q, K8 d( o0 ]) c# k: }: V U
return ax最后多说一句,想学习Python可联系阿喵,这里有我自己整理的整套python学习资料和路线,想要这些资料的都可以关注阿喵,并私信“01”领取。 6 D% k* E5 }/ w5 L
/ F7 Y7 e& v' G1 m M+ r+ Y
- K/ m6 l/ J6 x+ ]. {6 [
5 P5 d0 a3 B0 z: a3 m8 Z
6 i$ c0 g6 l- Y8 w0 i
|