9 Z2 w1 [4 e" n! g" L2 a5 R) V. C
Notes:请务必将matplotlib的版本控制在3.2(或以下),经过测试发现,3.3及以后的版本在配合proplot使用时,在设置colorbar的时候会出现警告信息,同时生成的图不正常。降版本之后问题不再出现。
Y" z) [* ` h) d# J+ x+ J3 p& n1 O 在我的上一篇文章中,我推荐了由NCAR负责开发的PyNgl库作为Python语言下面的地理绘图库,并且介绍了如何在子系统(WSL)下面的安装方法。详细的请见传送门:
6 ~6 v& F9 m E5 N ) l& L" c* f$ N' l! J1 v
不过现在选择使用PyNgl有些尴尬,首先是官方宣布不再进行大更新了,只进行小修小补(维护模式),其次根据一些说法,PyNgl相较于NCL本身,还存在一些Bugs。总的来说就是体验一般。不过,如果很早就习惯了NCL的声明式绘图,可能你会非常喜欢他。 e( Z6 N* K5 X$ K9 ?% b, ?
一次偶然,我发现了Proplot这个库,Proplot对matplotlib进行了高度的封装,是一个高级绘图工具,其功能相当强大!而且融和了cartopy、basemap、xarray和pandas。作者是来自科罗拉多州立大学大气科学学院的硕士研究生Luke Davis。简单来说:Proplot针对matplotlib和cartopy的很多不友好的方面,并通过封装来解决这些问题。使用者可以通过新引入的format方法来完成繁琐复杂的图形设置问题(更简单的代码,更好看的图形) $ \' f; ~: U* t8 v5 ? r) E
1 o0 o% |/ |& c% {# i; G9 x
在官方文档中,已经大量的绘图例子,可以前往查看,下面简单展示一下具体的绘图效果:
1 B; \4 F8 M1 D7 @1 @5 d+ s# W& o ①简单常用的填色图: . [7 ~4 G- A1 ~, O3 u: L
import proplot as plot
" s8 G$ g2 u2 h2 B5 |1 I% V, O import numpy as np
! j3 b( A) u# T4 a; r+ }: h x7 L( Y& q
# 创建虚拟数据$ X0 q8 ~% l3 s- Y& p' [
offset = -40# p% M' e7 E$ J. {7 b: W
lon = plot.arange(offset, 360 + offset - 1, 60)
2 j, B$ N5 E! g: b$ l: ^) g lat = plot.arange(-60, 60 + 1, 30)7 l1 G! \3 y- b! R+ y
state = np.random.RandomState(51423)- s2 D |0 K- C& b+ T+ o
data = state.rand(len(lat), len(lon))+ ^2 k0 N! k. e
/ y* V6 Z H$ w4 U. ] plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi
7 X9 d# O3 b) G" x proj = plot.Proj(cyl)
; ?/ v, y- c. v K& b7 R fig, axs = plot.subplots(nrows=1, ncols=2, axwidth=6, proj=proj)1 E7 m3 g3 @3 F# Z! b
axs.format(
2 i5 n: i1 I% i; e; E, C abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,
% b1 \" x% |' z" t' ~. D. z6 x labels=True, lonlines=30, latlines=20,3 f6 E/ V* l( _( v+ b
coast=True,gridminor=True,coastlinewidth=1," Y/ a# r+ D" A: p) @1 o4 W6 r5 I/ N9 Z
suptitle=Contourf,suptitlesize=20,. G$ E) u/ c8 t, D) c8 M
rowlabels=[Cartopy example],
& Y% K6 i/ c! c) E" | [' ~1 I/ i F collabels=[Contourf, Pcolormesh])- A, n( R7 v& ]6 c o
cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度
, L- Z8 H" S- t j& o! ?! h9 _0 g' f
! u' r" x, `8 B, ] V m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)
2 |" l6 T, }) ~9 f0 O axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)
0 n: p) O% X% E! w4 X! z" W# R. [4 S$ q8 J2 G" k U
fig.colorbar(m, loc=b, label=State,
! b; ~* D: T k# R8 K3 M( w labelsize=20,ticklabelsize=18, extendsize=1.7em)
+ o4 L# A- p0 Z$ k/ Z6 h2 }4 \7 H6 l fig.save(rC:\Users\59799\Desktop\image.png,
% y9 U U% M- Q0 B) ^- `$ K dpi=600)( J7 B( Y7 ?5 N: [6 B5 v7 O0 O
plot.close(); \" h( K3 M8 z( D" Y; W9 C
, o8 L. q' B' R5 ^; g
4 E7 p2 t" ^ r2 ~ ②子图特殊布局:
w! a+ e+ D$ E! V$ O! g; n import proplot as plot7 ~' j* A( x& M% [9 V) C" X
import numpy as np
: L% G0 o5 g7 K7 Y2 f3 @
8 k" x+ M6 m4 c x6 y7 O% v # 创建虚拟数据
& D! a- |4 a5 o offset = -40+ V: Q3 T$ b7 b* k$ ^
lon = plot.arange(offset, 360 + offset - 1, 60)
' }5 f. g+ m0 b lat = plot.arange(-60, 60 + 1, 30)0 ^5 K! _6 h. y6 u0 m2 s
state = np.random.RandomState(51423)$ d0 P7 S8 l# \
data = state.rand(len(lat), len(lon))4 ?; X" ?" U1 H
$ J! p' L# r! A. X; h' G
+ ?8 y. p- O- Y subplot_array = [[0,1,1,0],
* X3 l" X& N: w+ a% I: b. v [2,2,3,3]] #0表示没有图片 1 2 3...表示子图1 2 3...: p3 G& T2 S! Z) f
4 J- {9 ?) ]: T3 C2 [5 ^. Q plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi
4 F- A( s4 l/ ^ proj = plot.Proj(cyl)
1 [5 T/ H Y3 M( O0 [ fig, axs = plot.subplots(subplot_array, axwidth=6, proj=proj)
: j+ i- Z0 B3 N2 u6 n% I4 n( c axs.format(
5 w' T! n1 f- G4 n7 Y4 t abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,- J) c5 Z# {) x, ?( F- ?$ _% M& Q
labels=True, lonlines=30, latlines=20,$ q; j/ y& P9 f: D- L
coast=True,gridminor=True,coastlinewidth=1)
9 E a; ], D. h G cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度
* D* y H$ j* p* S9 X- F. O1 h* n5 ~( \4 Q
m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)
9 q5 J( d& I6 U. c: C axs[0].format(title = subplot 1, titlesize=20)* b0 h+ }6 w& Q8 z4 i
! W6 h4 I6 F3 B9 m axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)7 a4 I' ^; M$ P/ p4 C$ V
axs[1].format(title = subplot 2, titlesize=20)3 P8 R# a x$ r: h4 d1 e
: S. ]1 J7 C3 M. Z1 I: ^ axs[2].contour(lon, lat, data, extend=both)
4 B; B7 Z8 c( o' L& o* y axs[2].format(title = subplot 2, titlesize=20)
! K, `0 ~5 ~' \: a& ]* l$ Z7 p/ c0 a: f9 a7 ^2 Y" t) r
fig.colorbar(m, loc=b, label=State,' |6 t/ e9 A: k0 L9 S
labelsize=20,ticklabelsize=18, extendsize=1.7em)
( M7 l$ `/ M7 y- D$ ^ fig.save(rC:\Users\59799\Desktop\image.png,, q$ B) p$ t- g7 L, k% r: Y
dpi=600)
8 K$ H* n9 h- W plot.close()
5 {6 k% ]4 Y! ^' Y7 t% P z
: v' x! K9 @" O' y 使用技巧: # s/ N3 |/ K# P4 u0 Q1 e1 N9 K& T
①在保存图片时,默认保存的图片为1200dpi,如果直接放进word文档,可能会因为图片压缩导致图片异常(如果设置为不压缩,图片一多会导致word非常卡),所以请尽量使用dpi参数改变保存图片时候的dpi。 3 R l" T( D$ \! r$ [9 g- x, B
②format方法可以针对不同的子图设置不同格式,例如:
; B4 r+ g7 }( \+ C axs.format(...)#设置全部子图
6 z( A( m& T9 V/ ? axs[0:2].format(...)#设置第1张和第2张子图
% n* [, v) ], F. a1 ? axs[0].format(...)#设置第1张子图
3 F; F2 A9 B' g! Q+ L& f ③所有的图形设置都可以在format方法中通过参数的方法完成,具体的参数请查阅官方文档的Configuring ProPlot章节
7 o8 S3 }+ k0 h/ S3 ^7 a: w7 [: y) m/ Q ④现在Proplot中还包含着basemap,个人不太推荐使用。 ( p0 c1 D C% W0 ~* d
+ G1 h3 J2 d- ^' ~% b% l% Y5 }) O& f6 @4 E
' h/ Y2 y& z4 w w. |' X" g- P2 M7 R9 I# D) V
1 W+ F! I d9 ~0 f, s& A" r4 N
|