% |* L% l3 w; c' v D. o3 n/ }
Notes:请务必将matplotlib的版本控制在3.2(或以下),经过测试发现,3.3及以后的版本在配合proplot使用时,在设置colorbar的时候会出现警告信息,同时生成的图不正常。降版本之后问题不再出现。
v6 e3 i# z, p9 s! q 在我的上一篇文章中,我推荐了由NCAR负责开发的PyNgl库作为Python语言下面的地理绘图库,并且介绍了如何在子系统(WSL)下面的安装方法。详细的请见传送门:
i; e5 q9 l6 ^' ]5 F $ s$ }. P' Z" s- n z7 f5 R/ V+ Z2 l
不过现在选择使用PyNgl有些尴尬,首先是官方宣布不再进行大更新了,只进行小修小补(维护模式),其次根据一些说法,PyNgl相较于NCL本身,还存在一些Bugs。总的来说就是体验一般。不过,如果很早就习惯了NCL的声明式绘图,可能你会非常喜欢他。
7 Z5 l4 ^& M" x9 a: _; X- R. D 一次偶然,我发现了Proplot这个库,Proplot对matplotlib进行了高度的封装,是一个高级绘图工具,其功能相当强大!而且融和了cartopy、basemap、xarray和pandas。作者是来自科罗拉多州立大学大气科学学院的硕士研究生Luke Davis。简单来说:Proplot针对matplotlib和cartopy的很多不友好的方面,并通过封装来解决这些问题。使用者可以通过新引入的format方法来完成繁琐复杂的图形设置问题(更简单的代码,更好看的图形) % l* U( B! h0 \, i' B
% W7 \5 X& e, v, `! x4 }% ^. {' k# R
在官方文档中,已经大量的绘图例子,可以前往查看,下面简单展示一下具体的绘图效果: 1 o7 k0 ]. X5 t+ u! Y/ ?
①简单常用的填色图: $ W' B! w/ R6 M1 b6 C
import proplot as plot
+ [% t X/ ?: j$ I* d6 y+ e& _, _6 L! @7 ~ import numpy as np
# ]4 q; Z4 C! h% j7 O$ e
% N7 q8 d4 a, n* Q, ]. T G # 创建虚拟数据6 \: P4 c- @& E; ?6 V% R6 Y
offset = -40
" l) e4 \8 ^! `9 U) U6 [ lon = plot.arange(offset, 360 + offset - 1, 60)$ W: _1 u, C, V/ z- i
lat = plot.arange(-60, 60 + 1, 30)# w C- k- I% q2 B
state = np.random.RandomState(51423)
% A4 |- ?) u3 [, K9 i k data = state.rand(len(lat), len(lon))
2 x7 s% g5 S$ l( ~1 m) e
3 x* V: k3 D8 Y, {1 Y plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi5 T, j, Q/ U/ M: D2 [" l3 `7 c9 Y$ t
proj = plot.Proj(cyl); ^( S- h; H# p
fig, axs = plot.subplots(nrows=1, ncols=2, axwidth=6, proj=proj)
! _/ K* p. C9 ^/ X3 S1 h. K8 x axs.format(
' `: T* Y* H; l1 t* A abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,0 M9 M8 R& h; N3 i9 L) h) v
labels=True, lonlines=30, latlines=20, s! S' c: o- m9 H& k& a
coast=True,gridminor=True,coastlinewidth=1,
! q9 ~" T. C# | suptitle=Contourf,suptitlesize=20,
- c. ]6 I7 x8 S* d rowlabels=[Cartopy example],- Q4 c7 |$ M; ^& q! D
collabels=[Contourf, Pcolormesh])
4 F; u2 g5 x" o" `4 c0 L( x/ P( U cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度
8 p- q; \/ [8 |0 B z; g, m: G
* i; v7 ^2 |; {9 q& K& d' k; W5 h m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both); u& C# Z: K- d9 x& T
axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)0 [4 l; O6 w6 R5 g& B7 @
8 e' Y3 A- b/ z/ @/ c3 j; j* x, V
fig.colorbar(m, loc=b, label=State,
- P5 w3 n7 k8 E3 X4 G Q labelsize=20,ticklabelsize=18, extendsize=1.7em)
% V8 Y# C/ a/ b* i* b9 O fig.save(rC:\Users\59799\Desktop\image.png,
9 e/ Y6 [1 |$ ~& e/ Q dpi=600)
2 c* \% Z" o/ Y7 _/ k! X0 ? plot.close()
1 ]+ Z* [' K* A( n2 q
% f, i! c0 f& n' t+ n1 E7 o* [5 }* m
; b3 t* h6 v3 `& |& [. @ P# D ②子图特殊布局:
7 S; o) J8 w D% N8 `7 p import proplot as plot
b- k3 F- E" g/ ? import numpy as np7 X+ a% b, w5 p6 |- h# `# W" X7 p
- H! t, Z% l9 {) C1 H
# 创建虚拟数据$ p _4 O; H3 {' J7 T
offset = -40
D' z- Z' l: D1 W) J/ f7 @ E* f& N$ ` lon = plot.arange(offset, 360 + offset - 1, 60). L, C( e0 U0 |. f
lat = plot.arange(-60, 60 + 1, 30)6 S/ k# W9 n7 Y, ^* _1 k) ?3 e, o
state = np.random.RandomState(51423)# N9 r- U/ t# d& {2 g
data = state.rand(len(lat), len(lon))
3 C% p' L, n/ @! L) h D3 m {6 d( @+ }, m9 G9 \ i4 @% z6 E" h
. r' N6 | i# C, N1 |* t, L subplot_array = [[0,1,1,0],
- O* z5 k! L A+ @: f [2,2,3,3]] #0表示没有图片 1 2 3...表示子图1 2 3...$ z" g! H3 d6 F! L/ o# J
) x% B% b+ }9 u% ]
plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi
( j! J: b" i2 g" s" t& W proj = plot.Proj(cyl)
, h1 i- P l4 F- t" a" _1 F6 H1 y fig, axs = plot.subplots(subplot_array, axwidth=6, proj=proj)
" Y% P5 i8 f. ~; J# J axs.format($ |/ M: l' ?, \. z4 n! U7 I& M; ?
abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,
$ ?4 j+ M; Q2 `8 }2 T/ T labels=True, lonlines=30, latlines=20,3 C3 D$ i3 L: M- E, V0 F
coast=True,gridminor=True,coastlinewidth=1)
6 _. F0 o& n5 ^# i3 t) [; s cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度/ y, G, J% z9 ^# g% Z. Y
8 g5 d% u% g- w' Y/ _% [ m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)( O! c$ y# ~5 Y- z! R7 z% D* m
axs[0].format(title = subplot 1, titlesize=20)
/ Q* L I- b# K4 l' t' S# v5 {: f2 N5 K. x& ~7 Y9 m# A
axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)# z' m3 ?* h+ G
axs[1].format(title = subplot 2, titlesize=20)4 J) @) [2 p0 z9 `/ R: t, }% _" F! X
/ `1 ~! {4 t U5 l, Y! L axs[2].contour(lon, lat, data, extend=both)
8 u- n1 b/ I" V, ?* a) }( t" \ axs[2].format(title = subplot 2, titlesize=20)
( @1 f" U3 ]2 R/ l) x/ U: P
4 c+ ~, t' i+ |9 v, r fig.colorbar(m, loc=b, label=State,
9 k5 P) L7 N' ~/ G* u3 n labelsize=20,ticklabelsize=18, extendsize=1.7em)
?, Y" ]3 y+ N- ~' \# A( O. D& C fig.save(rC:\Users\59799\Desktop\image.png,4 `1 L8 k, o* a! D3 R) q
dpi=600)
, U5 D6 ?9 x Q( D# [ plot.close()
+ q6 F9 ?' z- P+ a0 O, J 8 u1 {, y# s1 `8 g J' r7 a; V
使用技巧:
. u6 ~. |/ `% I* `% }' {( S ①在保存图片时,默认保存的图片为1200dpi,如果直接放进word文档,可能会因为图片压缩导致图片异常(如果设置为不压缩,图片一多会导致word非常卡),所以请尽量使用dpi参数改变保存图片时候的dpi。 ! d8 x) Q9 |; S0 g6 U. |( j
②format方法可以针对不同的子图设置不同格式,例如: 8 C/ t5 P8 _- m
axs.format(...)#设置全部子图/ b- o* b5 Q/ i9 i
axs[0:2].format(...)#设置第1张和第2张子图
% T2 V6 S; Q" C axs[0].format(...)#设置第1张子图
6 B- a! P, m' L# \7 K ③所有的图形设置都可以在format方法中通过参数的方法完成,具体的参数请查阅官方文档的Configuring ProPlot章节 5 g4 |6 U6 v! `: Y$ f) d$ H
④现在Proplot中还包含着basemap,个人不太推荐使用。
! d8 U5 L5 w, P4 D- n2 n* I* q# ^
: w+ W Y5 ~* f; }& k% [4 D4 a" v2 M6 X' s! z! n$ p
5 N5 f! |9 U: G( t" O/ [
: z0 H8 b7 @. }" j, o. w g7 S0 ` |