|
7 H: [( j/ S: {* ~% D
Notes:请务必将matplotlib的版本控制在3.2(或以下),经过测试发现,3.3及以后的版本在配合proplot使用时,在设置colorbar的时候会出现警告信息,同时生成的图不正常。降版本之后问题不再出现。 B( Q0 |- W |- ^: }
在我的上一篇文章中,我推荐了由NCAR负责开发的PyNgl库作为Python语言下面的地理绘图库,并且介绍了如何在子系统(WSL)下面的安装方法。详细的请见传送门:
+ b1 U' F o7 ~2 L, D! X1 I7 r$ ] p! i( f* }4 u/ G) G
不过现在选择使用PyNgl有些尴尬,首先是官方宣布不再进行大更新了,只进行小修小补(维护模式),其次根据一些说法,PyNgl相较于NCL本身,还存在一些Bugs。总的来说就是体验一般。不过,如果很早就习惯了NCL的声明式绘图,可能你会非常喜欢他。
# p! U7 C4 u1 ]" Z 一次偶然,我发现了Proplot这个库,Proplot对matplotlib进行了高度的封装,是一个高级绘图工具,其功能相当强大!而且融和了cartopy、basemap、xarray和pandas。作者是来自科罗拉多州立大学大气科学学院的硕士研究生Luke Davis。简单来说:Proplot针对matplotlib和cartopy的很多不友好的方面,并通过封装来解决这些问题。使用者可以通过新引入的format方法来完成繁琐复杂的图形设置问题(更简单的代码,更好看的图形) & C! b( o$ W' n& A
( S6 t7 g' h b# g$ j; l' F# n3 |1 Y
在官方文档中,已经大量的绘图例子,可以前往查看,下面简单展示一下具体的绘图效果: 4 `: X" \6 `/ I$ o, ^
①简单常用的填色图:
/ q- ~6 q1 R: b8 {$ e$ u% \; j import proplot as plot
' i! h: ^3 A2 V3 g% y import numpy as np' [) r5 ~/ ?" C. l; K, A* ]( w
" t$ E$ W7 @ d9 w. l$ n( V' n
# 创建虚拟数据* r' ?% }' e& Q; C! w( b/ O6 |
offset = -40
- a" B8 o, {. I lon = plot.arange(offset, 360 + offset - 1, 60)
7 P( c( y4 k( ]) d4 S+ M5 y. Y8 K lat = plot.arange(-60, 60 + 1, 30)- }8 o) x1 n+ @4 J( {) x% F
state = np.random.RandomState(51423)
+ t' j% R! J* Y9 L: V3 P( s data = state.rand(len(lat), len(lon))
6 Y+ m, l1 Q X5 X3 q [, J8 e7 \& u6 K5 A% V/ q- s
plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi+ L2 l( s; e; l# m- F6 B
proj = plot.Proj(cyl)% C$ i/ }3 \: z. n
fig, axs = plot.subplots(nrows=1, ncols=2, axwidth=6, proj=proj)
8 \0 _8 o8 t0 X" \- F, z4 t8 ]9 R axs.format(
6 m1 d% @$ d8 A3 ]9 t abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,# G, } a8 P: a% H8 x
labels=True, lonlines=30, latlines=20,
! K8 ?, n( U3 B coast=True,gridminor=True,coastlinewidth=1,
6 @* `5 k+ |3 } suptitle=Contourf,suptitlesize=20,0 M8 H- Z& J3 E# y
rowlabels=[Cartopy example],) t4 \+ X8 M1 h# q( L# e( v
collabels=[Contourf, Pcolormesh])3 `, ~ `/ ?; L9 ^% {5 V
cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度) a0 W$ s, ~: R5 g
2 b: L6 \! b W+ k m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)
s2 Y7 m9 Z# b+ M axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)9 B6 t+ E( X0 h7 f9 t
" y/ {" p. a) k4 U
fig.colorbar(m, loc=b, label=State,- y) @# C! w; y- N, {9 L6 ^& z
labelsize=20,ticklabelsize=18, extendsize=1.7em)7 i! B K% z! I7 i6 Q4 a
fig.save(rC:\Users\59799\Desktop\image.png,
7 [8 B/ v4 X6 m- F7 Z3 p1 r' Q, Q dpi=600)
% G" J" P/ f& ?+ m- u2 Q% t plot.close()- {+ ~% z! a+ i f& y" B6 C
2 Y. F9 Y. l. h4 [0 F . s' K0 I4 n0 S0 o! x) B# j5 U
②子图特殊布局:
7 A7 L4 N) B( q" c8 N* V import proplot as plot
* \/ o) p" d" E0 W' o3 J import numpy as np
7 t% X1 h) v n3 _7 A% Y2 [# m$ H5 g
7 n W# ]- F2 e p5 {7 I # 创建虚拟数据
' M' f- A( }. L offset = -40
% q+ g3 P/ O) R8 S i lon = plot.arange(offset, 360 + offset - 1, 60)* Z8 O( E3 t" W, P
lat = plot.arange(-60, 60 + 1, 30)6 D* Q# D+ ~3 S2 I7 Z
state = np.random.RandomState(51423)
, P# W: Z6 n, n) V# W1 k" V8 o: C data = state.rand(len(lat), len(lon))
& i+ E$ \7 U; w3 x0 j% \! P& Z' d+ o* p
" [: S! N1 A# P$ X) q subplot_array = [[0,1,1,0],$ i0 y7 U* V: h1 s: P; @
[2,2,3,3]] #0表示没有图片 1 2 3...表示子图1 2 3...- I- m# v# c. m7 K( l: P2 A: m
- R" t% N( t; G* }0 {0 u9 b) ?
plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi
' o4 w, x/ W3 d; s proj = plot.Proj(cyl)
: _: u, w c4 d8 B9 {# t0 ~ fig, axs = plot.subplots(subplot_array, axwidth=6, proj=proj)
U& N& p5 s- B3 k" @" d" f axs.format(
2 d! I/ c* P: [7 j* ?7 K abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,8 |4 @# q+ y8 A+ ?2 P0 v( N2 m
labels=True, lonlines=30, latlines=20,: B& R5 [) y) w3 P4 f
coast=True,gridminor=True,coastlinewidth=1)( R) \1 X* S2 }0 g! M4 p; s- R. c+ a
cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度* I) S n, b3 ~3 C
8 ^/ x- R, j+ I) Z
m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)/ Q! Z0 F& d, n Y
axs[0].format(title = subplot 1, titlesize=20)
) ~1 [0 y' }' f& E$ C! p# l( k, a9 ^
axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)
5 g+ E& a3 f- K! A' b axs[1].format(title = subplot 2, titlesize=20)" D) \" u% [; f
0 H& T5 z. L o2 m5 j* P
axs[2].contour(lon, lat, data, extend=both)% k- ^8 l. ]1 I8 k3 @" B
axs[2].format(title = subplot 2, titlesize=20)& U# I. d1 C4 T! Y' ]) k
, ^7 Y3 W# M+ j9 A/ ~4 k
fig.colorbar(m, loc=b, label=State,
G6 ?7 G& ^, [" y labelsize=20,ticklabelsize=18, extendsize=1.7em)* |! } Y/ P1 e6 R: q' a
fig.save(rC:\Users\59799\Desktop\image.png,, I* D4 |2 D6 P3 {& I: m
dpi=600)
9 q2 o/ X2 F4 M+ b q plot.close() ; X8 h& K' h9 o2 G6 x+ W
$ Q+ f B, f8 y; `7 o 使用技巧: 5 y; J! I& u" e% r$ J; ~- Z% D
①在保存图片时,默认保存的图片为1200dpi,如果直接放进word文档,可能会因为图片压缩导致图片异常(如果设置为不压缩,图片一多会导致word非常卡),所以请尽量使用dpi参数改变保存图片时候的dpi。
- O5 u; U. H g& { ②format方法可以针对不同的子图设置不同格式,例如:
! v4 ]- C f7 D7 H) N axs.format(...)#设置全部子图+ C& d5 Q6 ]( w* V/ [& B
axs[0:2].format(...)#设置第1张和第2张子图
j8 p9 n+ l( |% W# q5 O axs[0].format(...)#设置第1张子图 : R. _7 F$ k1 `8 `0 r5 w+ w
③所有的图形设置都可以在format方法中通过参数的方法完成,具体的参数请查阅官方文档的Configuring ProPlot章节 k9 g- a. Q$ g) o3 S5 J" a' J
④现在Proplot中还包含着basemap,个人不太推荐使用。 4 k1 \" G6 f& D6 F( J3 G2 e" c
4 J# x# e' v# ^1 g4 Z
0 `+ I0 C/ H. k% t7 K' z, q* v9 F7 ^7 T
, \, d' E2 j9 Q9 n7 y* T |