|
U# L1 {7 R( i7 [& Y9 t: k3 V9 O Notes:请务必将matplotlib的版本控制在3.2(或以下),经过测试发现,3.3及以后的版本在配合proplot使用时,在设置colorbar的时候会出现警告信息,同时生成的图不正常。降版本之后问题不再出现。
. R: h$ }& G# b, M 在我的上一篇文章中,我推荐了由NCAR负责开发的PyNgl库作为Python语言下面的地理绘图库,并且介绍了如何在子系统(WSL)下面的安装方法。详细的请见传送门: 8 y. H7 k5 w: Z: B9 e
% N2 o" v$ u7 `) ~ C5 Z0 M0 r/ i
不过现在选择使用PyNgl有些尴尬,首先是官方宣布不再进行大更新了,只进行小修小补(维护模式),其次根据一些说法,PyNgl相较于NCL本身,还存在一些Bugs。总的来说就是体验一般。不过,如果很早就习惯了NCL的声明式绘图,可能你会非常喜欢他。 : t, H$ b* x6 s0 O2 m' B
一次偶然,我发现了Proplot这个库,Proplot对matplotlib进行了高度的封装,是一个高级绘图工具,其功能相当强大!而且融和了cartopy、basemap、xarray和pandas。作者是来自科罗拉多州立大学大气科学学院的硕士研究生Luke Davis。简单来说:Proplot针对matplotlib和cartopy的很多不友好的方面,并通过封装来解决这些问题。使用者可以通过新引入的format方法来完成繁琐复杂的图形设置问题(更简单的代码,更好看的图形) : T/ S" z& ~( A) T
* f- J: R [4 e 在官方文档中,已经大量的绘图例子,可以前往查看,下面简单展示一下具体的绘图效果:
. S1 a, ~' u7 y& u6 Z6 t ①简单常用的填色图: + p( p; h0 [' z' B0 Y3 x
import proplot as plot
8 [7 M; W1 y+ U5 P, d import numpy as np8 c) Y3 r, F) q2 m( R6 p4 T
/ F& S3 e+ d& B) k # 创建虚拟数据+ x" B7 w& p L
offset = -403 {& C: N0 ], v* ]+ R$ S" g3 I
lon = plot.arange(offset, 360 + offset - 1, 60)
; |3 ~% L' y8 S E9 u* M lat = plot.arange(-60, 60 + 1, 30): e+ V- Y8 o, r9 g. I
state = np.random.RandomState(51423)
# f8 u% _6 b# m# q' Y data = state.rand(len(lat), len(lon))9 |- r3 M% e9 @* C9 P2 |* i4 y
G; E. j5 f# O( n plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi
4 k0 H- Q. T5 k proj = plot.Proj(cyl)" m# b* x% x Q$ {5 ]# ?1 ?0 f& i
fig, axs = plot.subplots(nrows=1, ncols=2, axwidth=6, proj=proj)' S# T- o) e* `0 I
axs.format(; n& c. Q! t% i# `2 d4 {
abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,4 {4 ?; g% z0 e6 B
labels=True, lonlines=30, latlines=20,
4 k4 I# h( ^6 y) U# B coast=True,gridminor=True,coastlinewidth=1,
6 r: K: R4 \# K% O' b suptitle=Contourf,suptitlesize=20,7 \3 P5 `2 D# e) u- d, {1 a
rowlabels=[Cartopy example],0 M# A6 u4 v1 s# A/ S' `
collabels=[Contourf, Pcolormesh])5 {$ x7 x- l; i/ L$ r
cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度. |8 @- @" L) a) Q; ?" B7 }; W3 ]
' v( P+ k, {* b4 u0 Y0 @1 C/ R/ D& d
m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)
% U+ z, i; A5 F1 g% r* O; W axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)* X: d# U- d0 n3 L' g
2 w& u& f# b/ f* D& m
fig.colorbar(m, loc=b, label=State,
) J6 P$ t8 ^4 J. c6 R. B0 d labelsize=20,ticklabelsize=18, extendsize=1.7em)9 j/ Q6 |* D% O0 }( g$ N: J/ i2 M
fig.save(rC:\Users\59799\Desktop\image.png,
* S1 L% {! g O3 p! [5 M9 j+ _ dpi=600)
* k1 D& y9 \7 r plot.close()7 f$ g, u6 [. J$ \: q
+ C6 N7 W' V! m- \3 i3 B* `; \
) ]$ r) z# _1 W0 C" D ②子图特殊布局:
, G8 b; ]) [9 U& v) u5 I import proplot as plot
8 p3 z+ O x4 y3 g import numpy as np
. {8 [& Y! b8 B, i; B0 \6 v5 x* T2 k, a/ }4 I- j- W9 I
# 创建虚拟数据+ x) P) H) @+ _7 \
offset = -400 s. p, Q+ E. z- g7 |
lon = plot.arange(offset, 360 + offset - 1, 60)( n5 [, l% V% A9 w
lat = plot.arange(-60, 60 + 1, 30): s% d; i& o" ?; G2 f( E
state = np.random.RandomState(51423)
) }$ O" Z* |4 C6 t, R. E data = state.rand(len(lat), len(lon))8 V! q0 l* T) t: W4 O3 _- t! k
2 K( Y+ C8 t1 @9 c- j1 i7 q! K8 u( _
subplot_array = [[0,1,1,0], ?, r; c, N# o
[2,2,3,3]] #0表示没有图片 1 2 3...表示子图1 2 3...# C7 c1 s6 A8 A% u6 w. U- N2 Q
1 w2 @2 N6 [+ }7 e" t. m Y plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi
: }" G0 o q0 v# _3 y proj = plot.Proj(cyl)
# |- u+ @% K# K) H fig, axs = plot.subplots(subplot_array, axwidth=6, proj=proj)
2 G0 N9 `$ z9 j. U axs.format(: |3 K: G0 k5 ~- f5 {, N
abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,7 u5 _$ `; Y# \5 \% o8 h
labels=True, lonlines=30, latlines=20,: Z- C8 O& j2 r
coast=True,gridminor=True,coastlinewidth=1)6 v, l8 V8 ^+ s4 O7 H: a
cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度" S A- R) V. B% j; H2 d
1 b9 R9 X5 a0 _+ G: T5 w2 \% t
m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)' V0 c' r8 @' {. \5 e8 J
axs[0].format(title = subplot 1, titlesize=20) A. _6 O3 r* R( L
1 `0 Q }# L1 p
axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)
' L* A2 Y7 U$ N: S* Z2 U axs[1].format(title = subplot 2, titlesize=20)5 C: Q) ^+ S( Z* T8 c1 |# `
5 u8 ~ ?2 N H4 p axs[2].contour(lon, lat, data, extend=both)
$ S+ T4 i9 b) }1 _/ b5 H8 T axs[2].format(title = subplot 2, titlesize=20)
6 f2 u4 ?% D" F6 T8 r( ?' A( z5 D) c. K# H6 }
fig.colorbar(m, loc=b, label=State,( q9 j& I9 D) y+ k( g" g5 g6 ^
labelsize=20,ticklabelsize=18, extendsize=1.7em)
2 L+ m" C. x7 n1 R/ ~ fig.save(rC:\Users\59799\Desktop\image.png,' G, N0 l9 T0 M3 I- Y, S$ S
dpi=600)% J9 b8 |' I! C6 J `
plot.close() 9 P/ U9 p/ @* w: Q
% X( |: h" r& k
使用技巧:
: F/ S; i4 M7 v; ?9 L6 E ①在保存图片时,默认保存的图片为1200dpi,如果直接放进word文档,可能会因为图片压缩导致图片异常(如果设置为不压缩,图片一多会导致word非常卡),所以请尽量使用dpi参数改变保存图片时候的dpi。 : S2 a( x* w* q4 ^$ L
②format方法可以针对不同的子图设置不同格式,例如: 0 G2 ^$ q. B! Y2 E# ^$ k+ E
axs.format(...)#设置全部子图
( p% r$ B( J( y, B( T axs[0:2].format(...)#设置第1张和第2张子图
u3 b. B! e* l axs[0].format(...)#设置第1张子图
4 B: f6 I$ J/ ^, _: c6 L ③所有的图形设置都可以在format方法中通过参数的方法完成,具体的参数请查阅官方文档的Configuring ProPlot章节 & P! {! r) f" I5 b+ H$ ~+ {
④现在Proplot中还包含着basemap,个人不太推荐使用。
/ y; |) w4 C) ]: Q
% C N8 I+ \% j( V' Z
6 f4 M3 V1 p1 C; J6 K1 A$ m; P1 u+ u/ a' Y$ x8 C% E
- U4 K9 F2 L' j: H
|