|
! C* E5 q! c% w7 {9 _
Notes:请务必将matplotlib的版本控制在3.2(或以下),经过测试发现,3.3及以后的版本在配合proplot使用时,在设置colorbar的时候会出现警告信息,同时生成的图不正常。降版本之后问题不再出现。
5 p+ h: k. X2 R2 T( t4 ~ 在我的上一篇文章中,我推荐了由NCAR负责开发的PyNgl库作为Python语言下面的地理绘图库,并且介绍了如何在子系统(WSL)下面的安装方法。详细的请见传送门: - N+ J! I( r* m M: A
6 O# B: V, B2 D
不过现在选择使用PyNgl有些尴尬,首先是官方宣布不再进行大更新了,只进行小修小补(维护模式),其次根据一些说法,PyNgl相较于NCL本身,还存在一些Bugs。总的来说就是体验一般。不过,如果很早就习惯了NCL的声明式绘图,可能你会非常喜欢他。 3 ?7 O( V6 p( Q1 d+ a# u
一次偶然,我发现了Proplot这个库,Proplot对matplotlib进行了高度的封装,是一个高级绘图工具,其功能相当强大!而且融和了cartopy、basemap、xarray和pandas。作者是来自科罗拉多州立大学大气科学学院的硕士研究生Luke Davis。简单来说:Proplot针对matplotlib和cartopy的很多不友好的方面,并通过封装来解决这些问题。使用者可以通过新引入的format方法来完成繁琐复杂的图形设置问题(更简单的代码,更好看的图形) " k5 {8 Q/ ]' x; ]
6 n7 K T7 i& ^% P/ f5 M 在官方文档中,已经大量的绘图例子,可以前往查看,下面简单展示一下具体的绘图效果: ' F. t' ^3 u) j3 e: T2 P3 }
①简单常用的填色图: $ X9 r; Q( [9 J2 l
import proplot as plot
) a7 ~/ F( K* \! Y+ r/ r4 C6 H import numpy as np; Q& `- q; d2 Q0 I
z7 } m4 w* \+ L% X U2 l5 a
# 创建虚拟数据4 b9 m* L- R! |5 n! z4 a0 |$ A
offset = -40
* L; S) x! `! o' ~ lon = plot.arange(offset, 360 + offset - 1, 60)* z+ `. S, r/ S i8 U, f& ]
lat = plot.arange(-60, 60 + 1, 30)% Q+ B l/ C3 \9 k1 J
state = np.random.RandomState(51423)- A8 ]& `$ w o: V' G) |: Y
data = state.rand(len(lat), len(lon))( R+ T0 `, m) v! X& d
- g# U l! q1 T) |
plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi- D5 p/ C6 H# v% v( ^
proj = plot.Proj(cyl)
4 h! M3 F: K' I" ] fig, axs = plot.subplots(nrows=1, ncols=2, axwidth=6, proj=proj)
/ v$ r+ R7 X" J9 Y. R5 G axs.format(9 a$ P3 r$ U) p% t
abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,
z& c; M/ F8 u2 T4 v labels=True, lonlines=30, latlines=20,8 L q6 W3 |2 H* `
coast=True,gridminor=True,coastlinewidth=1,7 _0 ^( y2 H& B# d
suptitle=Contourf,suptitlesize=20,* @3 Q' |1 Z. ~$ U+ V, h
rowlabels=[Cartopy example],
$ v" k. m$ h; ?3 ^( E6 T collabels=[Contourf, Pcolormesh])* H" v' y# m! F( v) U$ }) N
cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度
( W( W% R: o2 l6 p6 F1 _+ v0 U0 r T0 u+ ~# ?1 M8 s7 I x
m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)0 M5 i# h' \, K
axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)5 S2 V; M' d. i8 h( a' R' T
: m, d7 o6 b0 d
fig.colorbar(m, loc=b, label=State,
: X3 P8 w5 f# M9 O labelsize=20,ticklabelsize=18, extendsize=1.7em); C0 p/ S9 |' a' Q: h5 B, `
fig.save(rC:\Users\59799\Desktop\image.png,
, |+ A2 y/ o, h* y1 u B dpi=600)
1 L* G2 y' R2 Z0 v9 Y5 P' P) X- ?$ ] plot.close(): b( C+ N+ i4 v; k9 w
0 [. M# U# ?" z7 x
4 X6 ^% f% B% a$ T7 i: k7 L _ K ②子图特殊布局:
" l# _; Y. ?5 z3 ?, ^' Y% _, V import proplot as plot0 t& m/ J7 c) N, I: J
import numpy as np
) J8 N* A9 ?; F
0 a) h" P c- {* _4 ?: } # 创建虚拟数据
* \) W( s# Z& ~ } offset = -40
& w) k9 _& g" N% M$ i" h lon = plot.arange(offset, 360 + offset - 1, 60)6 Q' Y4 I3 J* v: n
lat = plot.arange(-60, 60 + 1, 30)
3 y0 F# ?- j5 ~. u4 G- R9 e state = np.random.RandomState(51423)5 W- Q0 m: L* m$ k
data = state.rand(len(lat), len(lon))
}! K% j$ z% u
- g! B3 N) c- ^ x9 ~$ N" ~$ h1 t) e6 n( K1 s% t, ?
subplot_array = [[0,1,1,0],7 P1 `/ F9 `& w
[2,2,3,3]] #0表示没有图片 1 2 3...表示子图1 2 3...
1 B# V" F `! q8 n
) j4 d, U* P+ y7 N/ A% ^ plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi
9 j% V8 q, ]1 J3 m& ], x3 D proj = plot.Proj(cyl)) w! K; L6 z: w6 R) a
fig, axs = plot.subplots(subplot_array, axwidth=6, proj=proj) z& c5 O* H8 p) u7 H! ?
axs.format(
, @8 V0 U$ v9 q" ]+ A% F abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,3 ]. y7 {- D) y/ @2 b8 w' o1 X# C
labels=True, lonlines=30, latlines=20,
) `9 R A8 c, Q+ f+ ~, j3 u coast=True,gridminor=True,coastlinewidth=1)/ s; z; Z1 A* l: @
cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度: G# }4 u& _2 `; Y6 C2 t1 p- h
; f, b. y S- e m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)0 `3 t3 U# c' t+ Y t. p
axs[0].format(title = subplot 1, titlesize=20)
6 t+ q# W/ _- f" u; e
8 Z1 R1 h! b1 C axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)
+ T8 r% G) {$ b" v3 w6 B& e axs[1].format(title = subplot 2, titlesize=20)* M6 y! `' ]9 x1 s% k
7 [3 l$ s# T1 F+ p axs[2].contour(lon, lat, data, extend=both)
6 i# ]! i5 i6 { axs[2].format(title = subplot 2, titlesize=20)8 Y" ]! b: U1 d% a7 a' ]
5 a, u4 H2 X* g$ f# T& V, b
fig.colorbar(m, loc=b, label=State,. Z3 t5 t: l8 A0 S+ S+ [
labelsize=20,ticklabelsize=18, extendsize=1.7em)
5 i1 @8 i# n8 \9 P fig.save(rC:\Users\59799\Desktop\image.png,2 d. B( T: P4 m2 Y+ x
dpi=600)8 m; X) K+ O) y l
plot.close() ; H- V" V* q# S1 J- z! w" D
0 v' {& U+ J- z+ d0 O6 ]0 v 使用技巧:
9 Y* A5 N5 Z9 q9 a ①在保存图片时,默认保存的图片为1200dpi,如果直接放进word文档,可能会因为图片压缩导致图片异常(如果设置为不压缩,图片一多会导致word非常卡),所以请尽量使用dpi参数改变保存图片时候的dpi。
) A! t' J V0 x0 a* h9 [7 R; ~# P, c2 V ②format方法可以针对不同的子图设置不同格式,例如: . j! w$ J0 d4 ^: ~0 x8 V6 s
axs.format(...)#设置全部子图
$ }% ?+ b0 d$ o# o3 p. J axs[0:2].format(...)#设置第1张和第2张子图& p0 V; A' {; U N
axs[0].format(...)#设置第1张子图 % M; p! F6 e7 ]% [2 p( w. j2 @; \6 X
③所有的图形设置都可以在format方法中通过参数的方法完成,具体的参数请查阅官方文档的Configuring ProPlot章节 " N Y6 | a9 M: m
④现在Proplot中还包含着basemap,个人不太推荐使用。 ; t$ t$ m1 g1 m; y, r
4 d1 e G- a3 k* x0 T* S
/ o; W! \0 U$ U* O8 r9 g2 d5 H+ w4 ^2 H$ y9 l- K/ h
" \, `0 I4 e3 h) _6 Q; k% g
|