8 [% u) E7 D7 t" S* }5 r
Notes:请务必将matplotlib的版本控制在3.2(或以下),经过测试发现,3.3及以后的版本在配合proplot使用时,在设置colorbar的时候会出现警告信息,同时生成的图不正常。降版本之后问题不再出现。 ! E2 m) O' w9 s) Y2 e" R5 Q+ P
在我的上一篇文章中,我推荐了由NCAR负责开发的PyNgl库作为Python语言下面的地理绘图库,并且介绍了如何在子系统(WSL)下面的安装方法。详细的请见传送门:
' @$ M$ O$ @5 {6 J7 h7 x/ Z
$ T" }* h1 _$ v: f8 U( M% w 不过现在选择使用PyNgl有些尴尬,首先是官方宣布不再进行大更新了,只进行小修小补(维护模式),其次根据一些说法,PyNgl相较于NCL本身,还存在一些Bugs。总的来说就是体验一般。不过,如果很早就习惯了NCL的声明式绘图,可能你会非常喜欢他。 ) f) t: S3 S8 k/ K4 r) @6 q, e
一次偶然,我发现了Proplot这个库,Proplot对matplotlib进行了高度的封装,是一个高级绘图工具,其功能相当强大!而且融和了cartopy、basemap、xarray和pandas。作者是来自科罗拉多州立大学大气科学学院的硕士研究生Luke Davis。简单来说:Proplot针对matplotlib和cartopy的很多不友好的方面,并通过封装来解决这些问题。使用者可以通过新引入的format方法来完成繁琐复杂的图形设置问题(更简单的代码,更好看的图形)
$ s1 {# U) y5 y7 H 5 S0 }& G8 ~, h" @2 S
在官方文档中,已经大量的绘图例子,可以前往查看,下面简单展示一下具体的绘图效果:
3 H0 _2 h8 n* {+ @- F ①简单常用的填色图:
% ]4 {# I8 l* f. g1 l import proplot as plot
; N: `1 j, p6 Q" _% k6 ]' C import numpy as np
! L/ G8 B0 ]/ p- z$ X' R3 X* d. E7 j1 S7 }1 b2 K
# 创建虚拟数据3 J* P' o0 o! T( H
offset = -40
# K9 j3 b) G( m. c lon = plot.arange(offset, 360 + offset - 1, 60)" ^' Q: R! r, @3 u/ L, H: c [# Q* k
lat = plot.arange(-60, 60 + 1, 30)
6 f! |. E6 I, V5 q9 M% V- ] state = np.random.RandomState(51423)1 X9 C1 H& a; T( u
data = state.rand(len(lat), len(lon))! V) r, d+ V8 p) _; t
) i1 }: x) k. \" M
plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi
0 `+ P: s) O0 J/ M proj = plot.Proj(cyl)( A& ]# f0 Z0 V
fig, axs = plot.subplots(nrows=1, ncols=2, axwidth=6, proj=proj)+ x* C" c9 Y2 R9 d3 U
axs.format(* O5 ~ D& D0 `6 C) s# s
abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,
+ t2 } e; O3 `+ v: ]3 G4 S+ i labels=True, lonlines=30, latlines=20,$ n M; I- w! M4 f3 _; y/ o# G
coast=True,gridminor=True,coastlinewidth=1,' Z. |" Y6 s: l: W- y( l3 b& X3 }
suptitle=Contourf,suptitlesize=20,. u0 X! q% ]+ t
rowlabels=[Cartopy example],
# I! w& P8 x3 X( b. l4 Y2 z collabels=[Contourf, Pcolormesh])) I2 s6 t, D7 U; s0 J7 A8 I
cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度) n$ s) I0 q( X* Y" e$ A
( ]: [6 V7 n/ N2 D m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)& {8 v4 k( L/ c1 n% v9 z* k
axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)
1 n- L* T3 U* y4 P o6 g9 m# `
* s+ i% `, G& P" o+ X( F fig.colorbar(m, loc=b, label=State,
5 [0 W( [! `( L6 F/ o3 M T, p labelsize=20,ticklabelsize=18, extendsize=1.7em)
2 x: Y9 m# F! s; y) E1 U# e fig.save(rC:\Users\59799\Desktop\image.png,
+ n2 X4 u3 M9 Y: T* ]$ i dpi=600)( c2 s3 ?6 j3 m- y
plot.close()
: p8 i) }! f/ p/ M' `% I S0 ]
$ z; R3 Y; i0 G. u3 H9 N & j7 B/ L2 M/ W( _- |9 r
②子图特殊布局: : x/ r7 t" a, `' e: U
import proplot as plot
/ O* U p$ G, E- b$ E9 s import numpy as np5 g. T6 G3 O, e6 D1 X" u. F
$ V, s9 j/ w: } # 创建虚拟数据! d0 T" K; @# U" i/ f
offset = -40& Y0 [" `+ Z- J
lon = plot.arange(offset, 360 + offset - 1, 60)
+ A9 L" c o4 V# | lat = plot.arange(-60, 60 + 1, 30)
, @" w5 R3 C! E& H# o. u( a' d state = np.random.RandomState(51423)
4 ?: }, z- _ o+ J data = state.rand(len(lat), len(lon))/ L; m: Z1 X; r- `8 Z6 W7 A
% i# `& E+ {% g; l- A7 B+ T% }
& Z; v! t* o: G0 e I1 |3 G subplot_array = [[0,1,1,0],* \, B* E ]7 x% C3 T
[2,2,3,3]] #0表示没有图片 1 2 3...表示子图1 2 3...
: T* U, \) F" h* _( f0 m) ]* ~( A- H( p. b) W/ Q0 o( T
plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi0 s+ M$ f) U8 k. P; U# g
proj = plot.Proj(cyl)6 a3 X+ I4 C2 L3 x' X8 e
fig, axs = plot.subplots(subplot_array, axwidth=6, proj=proj)2 y, q c ^! r
axs.format(; \ K3 m# K4 O
abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,
7 V) T4 s$ s* `0 s, \ labels=True, lonlines=30, latlines=20,
" `2 J$ s; l# j% E$ P, f; w+ i coast=True,gridminor=True,coastlinewidth=1)
" j9 a3 A, n3 M1 @7 [: l cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度 [! c @8 e; m$ n; V! F
0 L- c2 H' U; \
m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)5 f( M, P: A; W8 n' [! d" R1 L
axs[0].format(title = subplot 1, titlesize=20), L8 c ?- o6 q5 p+ g$ C' B: `
$ B9 o* \! Z6 F7 ~0 \/ E
axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)! i/ ]# }6 K( o: z
axs[1].format(title = subplot 2, titlesize=20)# r: r, V$ ~1 w& R
! }" e' C% j% c- h( o& U4 t axs[2].contour(lon, lat, data, extend=both)
2 m: z, F, K# l( z/ L axs[2].format(title = subplot 2, titlesize=20)
0 ^; ~( Q; o0 }" w7 Y t- l- c4 l1 h+ v) g* I) y
fig.colorbar(m, loc=b, label=State,8 o- L: c2 ]) t
labelsize=20,ticklabelsize=18, extendsize=1.7em)) m; Q) q& l5 G" ]
fig.save(rC:\Users\59799\Desktop\image.png,
8 [6 e" y: k3 Q4 @ dpi=600)
4 j. m# X5 m$ i5 L. P/ v plot.close()
0 ?. h8 @6 @2 Q6 y 5 p v2 M* M* ]( t. W) Q" s k0 z
使用技巧: 6 A& X3 \: f. k$ O& x
①在保存图片时,默认保存的图片为1200dpi,如果直接放进word文档,可能会因为图片压缩导致图片异常(如果设置为不压缩,图片一多会导致word非常卡),所以请尽量使用dpi参数改变保存图片时候的dpi。 3 m7 ^0 G) v$ S
②format方法可以针对不同的子图设置不同格式,例如:
2 a- t) w' B+ E7 R) [" q axs.format(...)#设置全部子图
' O" e# T$ d/ k" q) }, \( E j axs[0:2].format(...)#设置第1张和第2张子图
. I4 I s/ X3 R/ F" `" n axs[0].format(...)#设置第1张子图 0 v1 Z! g& z4 c* O
③所有的图形设置都可以在format方法中通过参数的方法完成,具体的参数请查阅官方文档的Configuring ProPlot章节
- ^9 k/ {5 |5 O8 [9 e2 z7 ^' w# y ④现在Proplot中还包含着basemap,个人不太推荐使用。
8 Q I" X( s0 V9 d& A8 b, x) l) S b- G2 W; _7 F
! t9 \% F [3 J4 h Q
6 N/ o% M6 m8 s W" c' t( ]! \
* G7 g# n s4 e: h3 w5 ~' b, ^+ D |