|
& a5 U6 }; C, \# u/ h, u/ l
Notes:请务必将matplotlib的版本控制在3.2(或以下),经过测试发现,3.3及以后的版本在配合proplot使用时,在设置colorbar的时候会出现警告信息,同时生成的图不正常。降版本之后问题不再出现。 0 ^- o( A2 T& Y2 u
在我的上一篇文章中,我推荐了由NCAR负责开发的PyNgl库作为Python语言下面的地理绘图库,并且介绍了如何在子系统(WSL)下面的安装方法。详细的请见传送门:
1 k' N1 d% D5 S- L$ n 5 p- m' ^1 S2 j! V7 Q; u9 I4 ^
不过现在选择使用PyNgl有些尴尬,首先是官方宣布不再进行大更新了,只进行小修小补(维护模式),其次根据一些说法,PyNgl相较于NCL本身,还存在一些Bugs。总的来说就是体验一般。不过,如果很早就习惯了NCL的声明式绘图,可能你会非常喜欢他。
% P! p$ t9 z$ S. ~" d 一次偶然,我发现了Proplot这个库,Proplot对matplotlib进行了高度的封装,是一个高级绘图工具,其功能相当强大!而且融和了cartopy、basemap、xarray和pandas。作者是来自科罗拉多州立大学大气科学学院的硕士研究生Luke Davis。简单来说:Proplot针对matplotlib和cartopy的很多不友好的方面,并通过封装来解决这些问题。使用者可以通过新引入的format方法来完成繁琐复杂的图形设置问题(更简单的代码,更好看的图形) " `8 b a; @) Y; n5 ^- Y" N
9 a$ Q1 P% V& e% b j( P. d6 D7 y
在官方文档中,已经大量的绘图例子,可以前往查看,下面简单展示一下具体的绘图效果: ( W( D7 O% ]; H) _. z) `' X
①简单常用的填色图:
3 ^- ~, r( b9 U9 Q# {( Z6 \# t$ {) b0 S import proplot as plot
+ y2 ?$ ^6 o5 X. o/ b0 Q import numpy as np
& I4 t4 [3 E- t. D! q$ p/ j7 C
/ v0 L) A# @# w/ o: V- [ # 创建虚拟数据0 Q3 I3 G* [1 o( s8 g& ]
offset = -40$ c$ v) A8 J6 E. [6 F! V& N& Q' ~" A
lon = plot.arange(offset, 360 + offset - 1, 60)
& X1 j7 }4 m, i% \# ~0 D& O7 q lat = plot.arange(-60, 60 + 1, 30)
" V! s# r z7 P+ t* S/ r7 _ state = np.random.RandomState(51423)
) W6 x3 D( S0 M9 I1 [6 b) t data = state.rand(len(lat), len(lon))
: P' X; c& R9 o# U& S8 y
; ^; s% r& L' @ I% D3 {9 @4 @ plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi
( C4 C" H* G! @+ |+ e9 ~ proj = plot.Proj(cyl)# Z& C2 k2 f0 Y8 L$ R' z$ L
fig, axs = plot.subplots(nrows=1, ncols=2, axwidth=6, proj=proj)
: w, n) @4 m8 N) \& v; L axs.format(, N+ d$ d0 G2 e# S6 ^) {
abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,# ]1 e" V5 f C8 a1 E' r- |$ q8 U" ?
labels=True, lonlines=30, latlines=20,
) |* [1 `+ c3 S& \, t* v5 } ` coast=True,gridminor=True,coastlinewidth=1,
5 E' m3 ]- d, w( q/ P1 Z- T1 P- w suptitle=Contourf,suptitlesize=20,! b( x& n$ b! t+ L. R
rowlabels=[Cartopy example],
: U$ V& ]/ n, o collabels=[Contourf, Pcolormesh])
& p" E1 H6 V+ j% h$ y cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度
4 M4 H3 @5 a/ \2 n! L
' x8 e5 x; y( S8 n1 j3 e m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)% g3 k# n5 b9 C5 ~. w) ]0 X! ~
axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)2 _& Z' H- ?6 j G+ j! ^' F1 ` e/ J
, M" V9 t$ w4 b fig.colorbar(m, loc=b, label=State,6 y3 `0 Q" B2 k' M1 x9 E# R! w
labelsize=20,ticklabelsize=18, extendsize=1.7em)
: P& k# a; V' f9 _8 s fig.save(rC:\Users\59799\Desktop\image.png,3 e) w3 R% n' [' h4 P: g
dpi=600)4 G& f1 I9 H1 i3 n- \
plot.close()
6 {) r& m1 X+ D, _ : g+ i! e$ ]: s; M! X
$ W4 a# G( v+ i+ X. ~
②子图特殊布局:
( z t' H9 M$ k B: w/ w import proplot as plot, ~' q: r0 J( k# P/ J, q1 q3 C
import numpy as np; M$ Z. l" [% |9 \
2 s. j! J* `9 I- @1 h% n # 创建虚拟数据3 y+ O. I5 U1 `! k4 R7 x6 p: ^
offset = -40. e, X" @, Z: k* y9 R. l) h
lon = plot.arange(offset, 360 + offset - 1, 60)
C0 t/ D& t8 t1 }9 } lat = plot.arange(-60, 60 + 1, 30)
5 U0 i/ J, k/ B6 I+ f state = np.random.RandomState(51423), f2 B& D3 X, u7 R: {! n, e. n
data = state.rand(len(lat), len(lon))
- @) v2 S5 b! q- O* }5 n' K; M% D: [- a) }7 w6 c" m
6 i q" r: H) k) T( w subplot_array = [[0,1,1,0],, v' B3 |/ }7 L; q2 v
[2,2,3,3]] #0表示没有图片 1 2 3...表示子图1 2 3...
% y! ]2 a- T7 w5 I. C; }3 w! Y$ |+ r" F% j
plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi
( ?& ^9 ~) \" U, c4 Z4 e proj = plot.Proj(cyl)
: U" a. E o, T9 D fig, axs = plot.subplots(subplot_array, axwidth=6, proj=proj)
2 R4 {+ w' T, t% V, U axs.format(
# E" R/ D5 h2 {" b. L, o5 E X" S abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,# K6 F) h% I3 Y0 e$ W! X: Y
labels=True, lonlines=30, latlines=20,
2 Y. m4 y8 a. K1 g* _( m coast=True,gridminor=True,coastlinewidth=1)
( T `4 p1 |8 v cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度$ |( n1 x! `( d$ v& N
! \! q$ ?6 O' w! S; Z m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)
2 e3 R" L7 s: J8 o7 b1 C& N axs[0].format(title = subplot 1, titlesize=20)% I N0 P' y$ W# J
/ ]: g0 K; C F
axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)+ g) Z3 H4 j* q* A
axs[1].format(title = subplot 2, titlesize=20)1 _* `' F2 V+ d5 L' _/ J
$ s/ t y. a! V4 F8 w; o+ O
axs[2].contour(lon, lat, data, extend=both)+ p' ~' {- W) F4 V% _
axs[2].format(title = subplot 2, titlesize=20)
+ |+ K |6 B# N7 C0 |/ N
" k( f1 a- O+ b2 s fig.colorbar(m, loc=b, label=State,
7 [8 s9 K% m8 l2 V. {" R& t" k labelsize=20,ticklabelsize=18, extendsize=1.7em)
) j5 o% G+ u' K- P fig.save(rC:\Users\59799\Desktop\image.png,
: J) W$ ?& I2 y3 \+ i* ~+ I dpi=600)6 i! D1 ~5 U3 N9 Z$ W, q. o5 h0 W
plot.close()
0 k3 Q$ p3 g! _8 c. g. x4 x5 i- } 8 ]) D% U" d* |: j3 ?
使用技巧:
2 _) m+ M% B3 Z- y8 o ①在保存图片时,默认保存的图片为1200dpi,如果直接放进word文档,可能会因为图片压缩导致图片异常(如果设置为不压缩,图片一多会导致word非常卡),所以请尽量使用dpi参数改变保存图片时候的dpi。 + A; Y/ t; q9 M
②format方法可以针对不同的子图设置不同格式,例如:
% G* Y( }* J# s* b! M' O axs.format(...)#设置全部子图
* q' l/ _2 c3 I* W0 Z axs[0:2].format(...)#设置第1张和第2张子图
1 U6 i6 L( J0 N) Q e! n( F axs[0].format(...)#设置第1张子图 3 }$ P( w) n9 A* p
③所有的图形设置都可以在format方法中通过参数的方法完成,具体的参数请查阅官方文档的Configuring ProPlot章节
& X, q4 f4 s* `: t& d. W% e, V ④现在Proplot中还包含着basemap,个人不太推荐使用。
& @; a$ i: \3 \3 n( h7 N4 l$ w: v3 J0 ?, ]- n' R
/ Z8 Z7 K! @3 W+ D
3 h9 h0 A5 Z# T6 N
/ {6 m& [6 g& q3 x |