零基础小白python入门必看之Cartopy的基础使用

[复制链接]
8 W) z' o# Z+ l. |$ y

文章目录

前言一、基础介绍二、区域地图的绘制总结

前言

! U' j& `; O6 r6 C

常用地图底图的绘制一般由Basemap或者cartopy模块完成,由于Basemap库是基于python2开发的一个模块,目前已经不开发维护。故简单介绍cartopy模块的一些基础操作。

4 P- F0 L7 g4 Z, s* a
/ k' j4 W2 V" X4 H1 I. [

如果大家在学习中遇到困难,想找一个python学习交流环境,可以加入我们的python,关注小编,并私信“01”即可进裙,领取python学习资料,会节约很多时间,减少很多遇到的难题。

9 M f& p4 x6 B& c

一、基础介绍

5 @* v# g- Q( L) _9 {7 T3 A& n6 U( f

首先导入相关模块。

import numpy as np q5 U$ E, B9 Y2 s import matplotlib.pyplot as plt w5 W. u: U& _! U( Y5 t, M4 j import cartopy.crs as ccrs 8 a: K% `- N2 u6 v9 N: j9 {/ S import cartopy.feature as cfeature% l: G6 D. W/ c& y& B* Z from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter, u& M) p8 U; w0 j 12345 ' q) X6 F" X, s9 v& e- y

首先介绍参数projection,该命令可以配合ccrs设置投影类型,此处以方形投影命令为示例。其中central_longitude参数为投影中心位置。其中心设置与Basemap设置规则一样,详情可以看上一篇文章。

ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=0))( r6 Z ~) r- |$ w6 M/ A: y 1

在设置好绘制类型后,绘制地图各特征量。其代码如下:

#ax.add_feature(cfeature.LAKES.with_scale(scale)) 4 ^: m! @) f1 L! u- | ax.add_feature(cfeature.OCEAN.with_scale(scale)) $ c! v2 A* e2 o) K( t #ax.add_feature(cfeature.RIVERS.with_scale(scale)) |# h: U- L5 s; @( b6 [1 I1 V: A #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)3 ? N# o- ?1 t7 h ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2)( r; F# R f; K7 I' ?3 G 123458 d4 O7 \, R; h. J) [$ I3 v V) j

参数scale为地图分辨率,目前支持10m,50m,110m,参数lw为线条粗细。此处绘制海岸线和海洋,效果图如下:

5 M4 O& [$ C2 E) I! r( x2 V8 C2 [! M/ B( n/ d
3 d$ y: r4 E: l

在绘制结束后,作为地图。经纬度自然是必不可少的,在该模块中,引进同时设置坐标轴标签改变该标签刻度的表示,具体形式如下:

ax.set_xticks(np.arange(0,361,40), crs=ccrs.PlateCarree())* u3 y4 p7 D# L! Y1 h8 w- U! y: G ax.set_yticks(np.arange(-90,90+30,30), crs=ccrs.PlateCarree())1 ]# R+ R2 ^; H, U0 z3 E+ p #zero_direction_label用来设置经度的0度加不加E和W 6 l% I3 S/ N3 ?5 B5 } V lon_formatter = LongitudeFormatter(zero_direction_label=False) 3 A+ U% r$ L5 x' ~2 F lat_formatter = LatitudeFormatter(), q! f. _" k, Z$ Q* m8 e1 { ax.xaxis.set_major_formatter(lon_formatter) 6 P' n' R8 Y* U R& b& l ax.yaxis.set_major_formatter(lat_formatter)0 n# N/ Q0 T' a2 R 1234567

可以看到效果图如下:

7 @9 L0 j- z5 }$ p- T# r0 x3 N) S3 S1 W- ^" [) y- z
+ ]+ _1 k8 r/ I0 _0 J

当然如果想对坐标轴粗细变化可以引入一下命令。

ax.outline_patch.set_visible(False) : Q2 V) O; o7 f+ ^/ Q% y ax.spines[bottom].set_visible(True) ( k1 |1 x) d. g- ~2 B* M6 z" o" U: c ax.spines[left].set_visible(True) 5 r4 c5 y# U+ W3 Q+ C) o ax.spines[right].set_visible(True) : X& x: i% I; n2 r% o1 e ax.spines[top].set_visible(True) 2 A* Y4 L' J( k8 o ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细2 Q* p; @. V. a ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细' ~/ T/ C M% }% F* c3 U% X( ~ ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细2 R S7 d3 a- L0 x1 q' V ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细 6 D# q, s( H- z- x' c! ] V' A6 i' q' `! M) ` 12345678910

应该在该模块下,控制坐标轴的命令已经和常规不一样。因此先关闭该控制,然后开启常规坐标轴设置。

# r0 X! {" C1 ]& S

二、区域地图的绘制

& r- t& {& _: G( r2 }1 T

当我们在某一小块区域研究时,需要绘制区域地图。此时我们可以引入命令:

ax.set_extent(box,crs=ccrs.PlateCarree()) : O: E. u& z' N7 T: J- C 1' U' G8 l+ W \) S

其中box为绘制区域,crs为投影类型。其他命令基本不变。设置box为[40,180,0,90],可得到效果图如下:

& F4 a% Z: ]- R8 K # N: D0 r7 v& o9 H$ n( s
# |1 _. p0 o! x5 d1 Q

总结

& d& h) J, S& z. g/ V- {

为方便各位读者,我书写了绘制地图的函数,大家在使用时可直接调用。此处示例为方形投影,若希望绘制其他投影。只需要修改函数部分参数即可。代码如下:

def map_make(scale,box,xstep,ystep): 4 P! I% J; C# a, O% X1 k ax=plt.axes(projection=ccrs.PlateCarree(central_longitude=180))& }, `' a3 ^3 I9 P9 P1 n a = (box[1]-box[0])//xstep ; d4 s5 a1 Q3 M% l: W5 q x_start = box[1] - a*xstep 1 g* N3 U1 N% Q. c" p% j1 l a = (box[3]-box[2])//ystep 5 Q0 E' l5 Y% D; y1 m8 r y_start = box[3] - a*ystep( [& r. \. \. k ax.set_extent(box,crs=ccrs.PlateCarree()) 3 @ ? s8 z4 Z# f3 s- n! r #ax.add_feature(cfeature.LAKES.with_scale(scale)) 1 }" u6 M1 g9 @$ ^0 f3 I: u0 d #ax.add_feature(cfeature.OCEAN.with_scale(scale)) , N' g* A, b. d0 z6 u #ax.add_feature(cfeature.RIVERS.with_scale(scale)) & y# f& n d" f8 a, x& j) I, O Q #ax.add_feature(cfeature.LAND.with_scale(scale),lw=0.5)- _: I4 ~& Q; P) a ax.add_feature(cfeature.COASTLINE.with_scale(scale),lw=2) # R; k9 w. e9 e$ f$ o% l8 R % l, G: a3 v! g: V6 m ax.set_xticks(np.arange(x_start,box[1]+xstep,xstep), crs=ccrs.PlateCarree()) . x* [ Z5 k$ n4 D7 z4 C& y% A ax.set_yticks(np.arange(y_start,box[3]+ystep,ystep), crs=ccrs.PlateCarree())& R$ \. Z* d9 Z #zero_direction_label用来设置经度的0度加不加E和W + T' {8 }1 J4 r8 i" w lon_formatter = LongitudeFormatter(zero_direction_label=False)1 F3 i; d8 b4 U5 z5 T/ @& D1 n lat_formatter = LatitudeFormatter()1 a6 k) O) h7 K6 g ax.xaxis.set_major_formatter(lon_formatter)- j& @3 ~# z% R0 U# Z% _+ r ax.yaxis.set_major_formatter(lat_formatter) 1 R& \! r9 Y6 N' \3 ` #添加网格线% C7 u8 i9 k6 s# n; [) N ax.grid() , a$ e0 [- |7 o' F , I/ Y3 [' s0 ~/ p1 P7 l ax.outline_patch.set_visible(False)/ f1 t0 ~9 L8 T% I% N' b ax.spines[bottom].set_visible(True): |! [% _1 \! U/ J' h3 E$ d- R ax.spines[left].set_visible(True)6 U2 L! T( C9 |) t3 X9 X ax.spines[right].set_visible(True)' ]2 d( g n+ J% _" t ax.spines[top].set_visible(True)" d: A5 e- o7 S. ~* O( D( v, W ax.spines[bottom].set_linewidth(2.5);###设置底部坐标轴的粗细 A* {' a& m3 k7 W# u ax.spines[left].set_linewidth(2.5);####设置左边坐标轴的粗细# |1 H5 q$ |, X8 ?# ] ax.spines[right].set_linewidth(2.5);###设置右边坐标轴的粗细; O2 G" [9 W9 }. A E ax.spines[top].set_linewidth(2.5);####设置上部坐标轴的粗细 ! M2 l+ Q$ g+ m% \ * Q/ h5 R$ Z) k: U i9 h return ax

最后多说一句,想学习Python可联系阿喵,这里有我自己整理的整套python学习资料和路线,想要这些资料的都可以关注阿喵,并私信“01”领取。

$ S- M1 S M# V# e Y; M ) B( r7 B [; z3 r$ w y6 Y# f* ~) Y; e+ s( d3 t 8 @% ]2 P0 ^; }8 i4 F( T3 P- e/ G5 ] b" j2 w
回复

举报 使用道具

全部回帖
暂无回帖,快来参与回复吧
懒得打字?点击右侧快捷回复 【吾爱海洋论坛发文有奖】
您需要登录后才可以回帖 登录 | 立即注册
大狼
活跃在7 天前
快速回复 返回顶部 返回列表