. }) n5 l5 k; Z! ]+ X% x Notes:请务必将matplotlib的版本控制在3.2(或以下),经过测试发现,3.3及以后的版本在配合proplot使用时,在设置colorbar的时候会出现警告信息,同时生成的图不正常。降版本之后问题不再出现。 3 C' M/ h: n" V+ _9 m
在我的上一篇文章中,我推荐了由NCAR负责开发的PyNgl库作为Python语言下面的地理绘图库,并且介绍了如何在子系统(WSL)下面的安装方法。详细的请见传送门:
5 l/ R/ I9 U* ]$ f3 j# e
$ y# C' {' z6 d$ B 不过现在选择使用PyNgl有些尴尬,首先是官方宣布不再进行大更新了,只进行小修小补(维护模式),其次根据一些说法,PyNgl相较于NCL本身,还存在一些Bugs。总的来说就是体验一般。不过,如果很早就习惯了NCL的声明式绘图,可能你会非常喜欢他。
9 X9 i* T1 a q5 D 一次偶然,我发现了Proplot这个库,Proplot对matplotlib进行了高度的封装,是一个高级绘图工具,其功能相当强大!而且融和了cartopy、basemap、xarray和pandas。作者是来自科罗拉多州立大学大气科学学院的硕士研究生Luke Davis。简单来说:Proplot针对matplotlib和cartopy的很多不友好的方面,并通过封装来解决这些问题。使用者可以通过新引入的format方法来完成繁琐复杂的图形设置问题(更简单的代码,更好看的图形) ; V/ j$ Y+ k0 |5 _$ O+ t2 d
2 J8 I* o' w3 S$ q5 O
在官方文档中,已经大量的绘图例子,可以前往查看,下面简单展示一下具体的绘图效果: 9 J- I2 C/ I# L- ?1 j3 [
①简单常用的填色图:
9 \- h) G: j- W& y8 N$ ] import proplot as plot
# q" u; o1 C$ ]' W% J import numpy as np( ]$ ]: ~- T( l+ \; t
# x8 n. @. ]9 |( f2 m # 创建虚拟数据* Z; N+ U3 h' M6 g6 @) i4 M
offset = -40& l- A7 z2 ]& I( C. o% K7 x. F( c
lon = plot.arange(offset, 360 + offset - 1, 60)
( f9 D7 r& v* ]0 \# ~" c lat = plot.arange(-60, 60 + 1, 30)
! n( J" F6 O- Q5 P) s state = np.random.RandomState(51423)- f9 t4 N3 v4 u' {
data = state.rand(len(lat), len(lon))
+ I* \4 G1 p5 @8 ]9 W1 A, V
7 ]5 A1 C" y/ x8 S8 j5 H" `: p plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi
) G2 }' ~& z3 V, \' c- M7 ^ proj = plot.Proj(cyl)6 [0 F0 g+ }+ a1 M/ w# U$ h
fig, axs = plot.subplots(nrows=1, ncols=2, axwidth=6, proj=proj)' h% b. b; L! c# U
axs.format(7 \! _# `9 E. K9 U: G1 g4 w* e
abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,
, o7 N2 w; N) n3 | labels=True, lonlines=30, latlines=20,
; D W/ y6 i8 K) V coast=True,gridminor=True,coastlinewidth=1,2 @8 i/ ^+ b. g: y1 }) X
suptitle=Contourf,suptitlesize=20,. ~9 R. y" G B- W8 t
rowlabels=[Cartopy example],# Z5 o7 B: X% @% s( m# {; n% C
collabels=[Contourf, Pcolormesh])
: c; M; ^3 V" E cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度
# \1 c; a2 t4 P0 C
6 ?9 ?+ d3 h( r- _9 } m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)
+ c; ?+ |3 ?( h$ } axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)
* a R8 p$ C7 C! m' G# `$ I
) b4 H; Y. ?( U fig.colorbar(m, loc=b, label=State,
E- U0 Y4 ~& G% }* f9 R R labelsize=20,ticklabelsize=18, extendsize=1.7em)
; p& K. }) h% ?9 K2 M* c fig.save(rC:\Users\59799\Desktop\image.png,: C) T4 L; j" U
dpi=600) w: A4 c( `0 {; z* y! h( N
plot.close()
R' l( i9 N2 m Y
7 |5 N. L7 J$ B* K/ x7 w
6 g: `2 ~9 w, c: I, J% j ②子图特殊布局: # J3 G' n+ D1 r3 [
import proplot as plot7 T; `5 A6 z" L7 V
import numpy as np4 I& N2 D- M* R
7 @3 d# E' [7 R. l # 创建虚拟数据
( x9 L e7 U. S8 j2 k offset = -40
' O5 O! V& @6 K, \) B! Y/ a lon = plot.arange(offset, 360 + offset - 1, 60)
3 f+ O! P" h) i9 j8 y3 N lat = plot.arange(-60, 60 + 1, 30)- X4 `) b$ n+ a# n5 d& {
state = np.random.RandomState(51423). X; o) ]* h/ P S/ o8 P- D
data = state.rand(len(lat), len(lon))
: T4 M# F+ @" v7 e+ h/ t+ h, S. K$ k0 I; P
. j$ o7 g( D5 h. E: t subplot_array = [[0,1,1,0],7 i2 W! }2 @' s) `4 e6 S
[2,2,3,3]] #0表示没有图片 1 2 3...表示子图1 2 3...: `+ @! t6 {/ w! e$ i
) U- F: R6 o0 H/ D% Q, O plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi. `% T. D5 ^8 ]) C0 a/ k
proj = plot.Proj(cyl)4 b: `: I1 |2 ^& s
fig, axs = plot.subplots(subplot_array, axwidth=6, proj=proj)
, ^3 i3 T+ x5 @: o$ t* D8 l) [ axs.format(
! E1 L. L. N& z7 S3 r abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,& p' K7 X5 ?8 G: W# g& y _
labels=True, lonlines=30, latlines=20,+ n% I, T6 r' l! V0 ~7 ~& b
coast=True,gridminor=True,coastlinewidth=1)
: M0 {: G+ d3 U9 |) I cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度9 e5 {3 B( E) |- g" e1 R( b
. {7 E! T* @- `5 \# g1 X m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)+ O7 @" g7 M$ T5 p6 W5 {4 A
axs[0].format(title = subplot 1, titlesize=20)
6 x5 G" z2 D! }
& X1 o2 R; s; D) Y8 } axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)2 v( c, ~. [" P! A$ {4 C7 [+ N4 x1 A+ Y
axs[1].format(title = subplot 2, titlesize=20)9 ^6 s `. G( @2 l3 J4 h
) d3 Q+ q: I; Y+ y4 ]
axs[2].contour(lon, lat, data, extend=both)3 Z) d* H& Z6 N, J# h/ w
axs[2].format(title = subplot 2, titlesize=20); x* Y1 P( V: ]" ~; V
" |, X- b7 W( Z2 W, n. ^
fig.colorbar(m, loc=b, label=State,
1 f* @( m! g/ M8 l labelsize=20,ticklabelsize=18, extendsize=1.7em); Y+ f v% ^( j
fig.save(rC:\Users\59799\Desktop\image.png,
0 P; @. A6 \+ N' G5 n dpi=600)7 K5 U4 g4 N$ r# P+ R9 C [3 o A
plot.close()
8 |4 t: L) e, T* Q4 e( `7 U
0 W! V. N# s$ O% P5 \ 使用技巧:
" L; G8 ]4 s" ^) ^0 [ ①在保存图片时,默认保存的图片为1200dpi,如果直接放进word文档,可能会因为图片压缩导致图片异常(如果设置为不压缩,图片一多会导致word非常卡),所以请尽量使用dpi参数改变保存图片时候的dpi。
; |9 C% v! D! l* o, B. | ②format方法可以针对不同的子图设置不同格式,例如:
; ~/ T- z |9 k/ }$ a: n2 Z) h axs.format(...)#设置全部子图
! \$ k3 y7 l1 a$ D+ p# ?) D& s axs[0:2].format(...)#设置第1张和第2张子图9 r2 g# k V* S
axs[0].format(...)#设置第1张子图
' i" B4 v1 `4 Z' ~1 c: S$ ~ ③所有的图形设置都可以在format方法中通过参数的方法完成,具体的参数请查阅官方文档的Configuring ProPlot章节 3 t2 b' A* y0 M4 `1 n6 n
④现在Proplot中还包含着basemap,个人不太推荐使用。
; n% R0 M# z' W. f
. @' t" ?( I! L8 d# Q; K( ~3 P6 S ]* n& l5 m9 ?" A% l
" N: N9 I7 F& R* M1 r2 F
! H# w! j: \- f! F# O
|