8 {) o5 \6 r/ @) @# A Notes:请务必将matplotlib的版本控制在3.2(或以下),经过测试发现,3.3及以后的版本在配合proplot使用时,在设置colorbar的时候会出现警告信息,同时生成的图不正常。降版本之后问题不再出现。
# d8 ? l5 `# m. z: l$ D& t 在我的上一篇文章中,我推荐了由NCAR负责开发的PyNgl库作为Python语言下面的地理绘图库,并且介绍了如何在子系统(WSL)下面的安装方法。详细的请见传送门: * B# O& P, h' \9 ]2 s
# |/ J+ H# f+ D 不过现在选择使用PyNgl有些尴尬,首先是官方宣布不再进行大更新了,只进行小修小补(维护模式),其次根据一些说法,PyNgl相较于NCL本身,还存在一些Bugs。总的来说就是体验一般。不过,如果很早就习惯了NCL的声明式绘图,可能你会非常喜欢他。 : s2 H0 `2 V$ G
一次偶然,我发现了Proplot这个库,Proplot对matplotlib进行了高度的封装,是一个高级绘图工具,其功能相当强大!而且融和了cartopy、basemap、xarray和pandas。作者是来自科罗拉多州立大学大气科学学院的硕士研究生Luke Davis。简单来说:Proplot针对matplotlib和cartopy的很多不友好的方面,并通过封装来解决这些问题。使用者可以通过新引入的format方法来完成繁琐复杂的图形设置问题(更简单的代码,更好看的图形)
' A2 D! A6 | [- `) V/ Q4 ]
% I, N- v( g! ^6 V+ `/ E 在官方文档中,已经大量的绘图例子,可以前往查看,下面简单展示一下具体的绘图效果:
/ Z7 c1 M6 N. u' x ①简单常用的填色图:
1 B, \- s0 U! g4 r \ import proplot as plot
7 S5 w- I6 d8 [8 j% w6 p6 Q import numpy as np+ Q0 q! w0 a* m$ s* M
0 B4 u$ \ y5 N. h4 c" |2 J2 U. p* P
# 创建虚拟数据
/ k; V5 I' |5 E3 s) x$ s/ ? offset = -400 v0 L( C% y+ x L
lon = plot.arange(offset, 360 + offset - 1, 60)# I4 y" A1 M, \
lat = plot.arange(-60, 60 + 1, 30)
0 X- y4 {+ i$ X+ F' L state = np.random.RandomState(51423)/ ~2 B/ V8 s9 Y
data = state.rand(len(lat), len(lon))
- n- B3 [ k4 {3 q+ b7 P {5 x5 w% G+ s
plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi
% M& `+ {. k% r7 H ]! t8 J' z proj = plot.Proj(cyl)5 f4 H2 B3 L0 w) ?) ~
fig, axs = plot.subplots(nrows=1, ncols=2, axwidth=6, proj=proj), t0 n5 x& H$ N
axs.format(& Y+ ~$ H# |" x
abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,
- v- K: J- V+ X4 _( ] labels=True, lonlines=30, latlines=20,
+ H3 h, E5 U, M) _- g coast=True,gridminor=True,coastlinewidth=1,' q& j5 F: g! M
suptitle=Contourf,suptitlesize=20,0 b! G( ?- w: M' W- \0 S& k
rowlabels=[Cartopy example],' e+ ]! @1 d5 V, i r+ I
collabels=[Contourf, Pcolormesh])1 D8 D" J8 K4 r: {* ~ N( `
cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度
; C2 C0 D4 i! @, ~% ]: |% O% K$ e5 } \ S) d
m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)( |5 K# `: Z! S
axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)
k8 _8 Z( _4 y, w* y" |
8 Z- y+ S2 d. J3 r! F fig.colorbar(m, loc=b, label=State,
7 \# R4 x3 Y; Z* f+ O- B$ a, F0 X labelsize=20,ticklabelsize=18, extendsize=1.7em)9 O$ @3 p* F9 s! |4 @( @
fig.save(rC:\Users\59799\Desktop\image.png,
4 O& r- C* i1 \8 l4 n dpi=600)( ~9 @0 o* A0 E4 T0 N1 t
plot.close()
7 @- Q* ^4 ?4 C* M* K! J 4 s1 n) B9 E8 {/ ^) F' T
/ w. |( P7 e& ]4 ~# S/ Y2 b/ g- E, } ②子图特殊布局:
& Y8 d' ~- Q+ V+ @& w% M$ D1 h import proplot as plot& h1 t# _) D2 Z4 r, T2 A3 L
import numpy as np( @' S/ a7 a; u) J
0 w# C- F! }7 e) K7 } # 创建虚拟数据
5 J5 b( T5 L* r' ? offset = -40
7 z# v: g4 }4 U' Q0 V5 f( v4 Z lon = plot.arange(offset, 360 + offset - 1, 60)
! D2 @( T4 V5 t, M. h# i' r5 g lat = plot.arange(-60, 60 + 1, 30)$ N" C" E/ m. ]: g- h1 v
state = np.random.RandomState(51423). h6 X8 G y5 Y o' Q
data = state.rand(len(lat), len(lon))' }. B/ ~/ o& A8 x+ a
- t, g. L% N# n9 Y+ ^4 o- p
" C$ @" L g& X& @ subplot_array = [[0,1,1,0],
2 M3 V6 f. H0 A! w- r" f6 [* D( v7 f [2,2,3,3]] #0表示没有图片 1 2 3...表示子图1 2 3...1 {0 w, c5 k* u2 z! [) F
* F1 e% u5 C/ _! A: L plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi
5 X! X6 ^' R& h3 y- q, A5 l9 p proj = plot.Proj(cyl)1 E+ H5 s$ r! \, h1 o! O
fig, axs = plot.subplots(subplot_array, axwidth=6, proj=proj)6 h4 j* l/ V' I6 A, G# j
axs.format(
- o" B" d; _- z2 _8 t3 \% ], } abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,
' u: e$ L# M/ s, m( V labels=True, lonlines=30, latlines=20,
V1 Y7 N0 x1 `$ E coast=True,gridminor=True,coastlinewidth=1)+ _- \* r8 Z/ S+ ~ O
cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度
4 D5 r" h: p) E& |4 }7 F" x! p1 v2 n* N/ R) Z8 U* T8 _. g
m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)
6 l2 m( I7 N& }" C, c9 N) l axs[0].format(title = subplot 1, titlesize=20)
( q! n+ y8 w4 R) G; J) \8 H/ T; D/ _0 x$ }
axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)
3 |" j+ m& q- i( o( } axs[1].format(title = subplot 2, titlesize=20)* h0 n; I$ q! K0 F! H( j6 w2 }6 U' V8 ?( e, N
0 P% }7 g) o H0 o" _, s" q axs[2].contour(lon, lat, data, extend=both)
. P- Y$ T* G0 [! o axs[2].format(title = subplot 2, titlesize=20)$ k/ E& j" V5 B8 _9 X1 y; Y$ V
4 l% ~8 H, ~+ S1 Z5 j
fig.colorbar(m, loc=b, label=State,5 z) Y5 Y# {" x9 z2 q. h6 e
labelsize=20,ticklabelsize=18, extendsize=1.7em)
+ Y" B- g: ^! s0 v5 @ fig.save(rC:\Users\59799\Desktop\image.png,1 m. g* l) K8 ^6 e Y8 X7 t% I
dpi=600)% Y E7 g1 a3 c1 y" O, O9 }
plot.close() 4 ]# ?6 }5 t% n7 {5 A. x
$ Q v5 r8 z) z. O* K: ? 使用技巧: 0 W8 ~! Q4 s% m
①在保存图片时,默认保存的图片为1200dpi,如果直接放进word文档,可能会因为图片压缩导致图片异常(如果设置为不压缩,图片一多会导致word非常卡),所以请尽量使用dpi参数改变保存图片时候的dpi。
; ~; q7 y, Q- k0 K7 S6 @ ②format方法可以针对不同的子图设置不同格式,例如:
' t3 d/ q4 ~) R, f axs.format(...)#设置全部子图
! r" n' n) t R' n8 U axs[0:2].format(...)#设置第1张和第2张子图
6 m ?; E! k; W7 L axs[0].format(...)#设置第1张子图
, I+ S7 b5 r# ^; i9 m0 u ③所有的图形设置都可以在format方法中通过参数的方法完成,具体的参数请查阅官方文档的Configuring ProPlot章节 7 t6 S- n/ Q9 v, o# ]7 [! f
④现在Proplot中还包含着basemap,个人不太推荐使用。 & b- X9 o/ F+ P* x9 L1 ]7 E8 _
; l6 a- Z' P* T0 k5 k) Z, g/ l1 M' G4 V+ T% O" S/ a y9 {
( O/ p/ B5 Z" o, L, }9 J
U, J, t1 K# [1 u) z$ t |