|
: W# R7 [. K! h8 R5 W N Notes:请务必将matplotlib的版本控制在3.2(或以下),经过测试发现,3.3及以后的版本在配合proplot使用时,在设置colorbar的时候会出现警告信息,同时生成的图不正常。降版本之后问题不再出现。 5 J6 Q! |$ Y4 @% F) S9 |
在我的上一篇文章中,我推荐了由NCAR负责开发的PyNgl库作为Python语言下面的地理绘图库,并且介绍了如何在子系统(WSL)下面的安装方法。详细的请见传送门:
/ [& s" a' v, J5 ]8 U0 ~* R / F8 H5 M/ ^3 D+ e- V. c2 R" C& y
不过现在选择使用PyNgl有些尴尬,首先是官方宣布不再进行大更新了,只进行小修小补(维护模式),其次根据一些说法,PyNgl相较于NCL本身,还存在一些Bugs。总的来说就是体验一般。不过,如果很早就习惯了NCL的声明式绘图,可能你会非常喜欢他。
- p& ]9 m) Z. U2 l8 G4 c 一次偶然,我发现了Proplot这个库,Proplot对matplotlib进行了高度的封装,是一个高级绘图工具,其功能相当强大!而且融和了cartopy、basemap、xarray和pandas。作者是来自科罗拉多州立大学大气科学学院的硕士研究生Luke Davis。简单来说:Proplot针对matplotlib和cartopy的很多不友好的方面,并通过封装来解决这些问题。使用者可以通过新引入的format方法来完成繁琐复杂的图形设置问题(更简单的代码,更好看的图形)
9 L: u; z5 Y& y- H 1 }3 u+ c6 J3 M, `8 x( L5 v
在官方文档中,已经大量的绘图例子,可以前往查看,下面简单展示一下具体的绘图效果: . l/ v+ V1 w, Z* e
①简单常用的填色图:
; Z/ j. a% Q2 D- I import proplot as plot
H: R2 p5 G5 L4 h import numpy as np2 h$ `0 D+ H9 c1 L
% x: p1 ?; [' N- j0 U; P2 f) t
# 创建虚拟数据2 W* h; p S. h/ I, P
offset = -40
9 t: T. `8 P# P% \3 k lon = plot.arange(offset, 360 + offset - 1, 60)
; _4 g" p+ r+ U# _ F! J4 A lat = plot.arange(-60, 60 + 1, 30)
+ W3 C4 O+ \* n+ O state = np.random.RandomState(51423)2 X! O0 y! I0 J6 j- s% K& J
data = state.rand(len(lat), len(lon))
/ C9 X: Q) }4 s' i! a3 ]4 r& W; @, }1 _( t2 [- v" t. l; x
plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi+ B& X9 Z6 Z$ D7 p1 i9 X1 x
proj = plot.Proj(cyl)
% V, M# ^3 w" ~1 U- R/ E fig, axs = plot.subplots(nrows=1, ncols=2, axwidth=6, proj=proj)
3 m4 U6 W0 g2 ?- @ axs.format($ N8 H; h0 W( C1 q7 p& ?$ s! K* d
abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,; _& X) C3 D4 ?+ C
labels=True, lonlines=30, latlines=20,
- V2 G7 q* C# o5 _7 b- S) i+ p coast=True,gridminor=True,coastlinewidth=1,9 s1 J. K- [& x- L2 m6 z
suptitle=Contourf,suptitlesize=20,/ I& Q7 I. f' Y0 E9 G5 M. i* S8 ~
rowlabels=[Cartopy example],- k' l% Y2 V' l
collabels=[Contourf, Pcolormesh])' P$ q4 P! i; i+ D) m
cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度
, V+ J2 F2 ^$ F; g
8 o0 h" T( B9 q2 N# Z" @/ R m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)
* U0 b2 Q, Z* i+ ]$ @ J axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)( {6 v- p1 o! E, X. f# |; C, n
$ R9 l# t+ k9 ]& R
fig.colorbar(m, loc=b, label=State,6 d# \, L* b0 W+ g" r# P3 v
labelsize=20,ticklabelsize=18, extendsize=1.7em)1 T; K; y7 y$ _# T3 P* n# ]( f! [
fig.save(rC:\Users\59799\Desktop\image.png,
, n+ R* ]4 P; y9 U4 q* E' o dpi=600)2 v7 |' D. m! e# d" R9 c& ?) S
plot.close()
" ~' y4 n) N% z( G1 x4 m
) z# a0 P. v7 f6 M# i T" p - D" }4 c1 d" ]2 e+ I
②子图特殊布局: : {- Q" \! {+ q- f3 }
import proplot as plot; E9 a$ y% v& W6 L+ A. Q
import numpy as np& N0 l8 ]# g& n
|+ V1 d! ^& _ Q0 e2 p/ ~ # 创建虚拟数据
$ Q+ P! C! H/ v: _0 X offset = -40
, z) {( ~# l1 A3 z, E+ C- c7 T lon = plot.arange(offset, 360 + offset - 1, 60)1 o" X; F) w/ S/ O
lat = plot.arange(-60, 60 + 1, 30)
7 w! ?4 `8 S7 s5 X' p; W8 m6 G state = np.random.RandomState(51423)
. Z& r- e/ k- Z data = state.rand(len(lat), len(lon))5 Z4 c: |) g) c s
! j$ q- u1 z6 v, F+ k
0 h. {6 c2 z# `
subplot_array = [[0,1,1,0],/ f0 l) \- ]6 e% S& P3 u
[2,2,3,3]] #0表示没有图片 1 2 3...表示子图1 2 3...' x9 F4 L- m5 _
7 a) b6 ?% f5 h; i { plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi) V+ a7 V5 v8 x% i1 u/ m: B& W
proj = plot.Proj(cyl)
' l8 g0 ?! h, n7 i z' j fig, axs = plot.subplots(subplot_array, axwidth=6, proj=proj)
# p1 q7 e" J5 j axs.format() `; r7 f, E) k& j. F. I
abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,
! p0 l% R% G/ \ y2 p" W labels=True, lonlines=30, latlines=20,
" g z ~/ g* h4 X% p coast=True,gridminor=True,coastlinewidth=1)
# G/ o! P) l0 |2 `2 v v9 A cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度
" D9 D" l2 d8 Y. F& _5 Q) {8 o- R5 n( A& D8 E$ }) s5 t
m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)
+ ^( X @/ u' G0 u) L axs[0].format(title = subplot 1, titlesize=20)
0 S3 P r3 {/ `% \4 W5 m8 I
+ h* L _4 X7 o7 A axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)
/ B' z. f( t8 e& s: ]2 ~ axs[1].format(title = subplot 2, titlesize=20)
. j( ], L3 a- M4 i w5 t4 L: @- w" n) q% Y
axs[2].contour(lon, lat, data, extend=both)
: @6 F4 g- v8 {+ h axs[2].format(title = subplot 2, titlesize=20)$ B( o7 m1 \+ ^4 C8 F
o8 e0 O' W: }' N$ ] fig.colorbar(m, loc=b, label=State,% H% R& j1 X1 E& C
labelsize=20,ticklabelsize=18, extendsize=1.7em)5 m; f/ T% n$ W" J( [% M9 ^
fig.save(rC:\Users\59799\Desktop\image.png,
2 J0 ]8 P0 q( V4 g0 r2 K; g$ Z9 b dpi=600)
( J8 \) r$ i: N8 E s+ q. a plot.close()
. N0 r' z# ^ ?8 f8 a) d' d : X# ?; d% b# G6 ]) e$ ^7 v
使用技巧:
2 i4 K! a6 X, Q! I ①在保存图片时,默认保存的图片为1200dpi,如果直接放进word文档,可能会因为图片压缩导致图片异常(如果设置为不压缩,图片一多会导致word非常卡),所以请尽量使用dpi参数改变保存图片时候的dpi。
4 t& n2 e4 [ K$ N ②format方法可以针对不同的子图设置不同格式,例如: 7 \- a: v" m6 {) t m$ t; q/ C, [
axs.format(...)#设置全部子图. T$ ?8 W4 w( F9 I; N7 q
axs[0:2].format(...)#设置第1张和第2张子图
$ t* T1 h( Q" z( ~, D axs[0].format(...)#设置第1张子图
6 Y. M0 Q; o1 t3 a$ T& y5 x ③所有的图形设置都可以在format方法中通过参数的方法完成,具体的参数请查阅官方文档的Configuring ProPlot章节 + w% ]8 p. w4 N, s7 X9 \
④现在Proplot中还包含着basemap,个人不太推荐使用。
3 R% v) s' N+ B. g/ T4 m' t& Q( j9 {0 R, E& n" d/ _$ B
7 Y1 }% Q( e# @7 {+ c% H3 s7 }9 Q
4 o! P& P* J6 h/ X
. Z! J! v0 s2 ]- Y/ c+ ~ |