|
" o! T: }! n+ j9 d. O, [ Notes:请务必将matplotlib的版本控制在3.2(或以下),经过测试发现,3.3及以后的版本在配合proplot使用时,在设置colorbar的时候会出现警告信息,同时生成的图不正常。降版本之后问题不再出现。 : B7 m9 V2 x& n$ A- v
在我的上一篇文章中,我推荐了由NCAR负责开发的PyNgl库作为Python语言下面的地理绘图库,并且介绍了如何在子系统(WSL)下面的安装方法。详细的请见传送门: . V+ R* L4 Q5 t8 U4 s4 e
: E! u! I' C! G0 [: c, V! a
不过现在选择使用PyNgl有些尴尬,首先是官方宣布不再进行大更新了,只进行小修小补(维护模式),其次根据一些说法,PyNgl相较于NCL本身,还存在一些Bugs。总的来说就是体验一般。不过,如果很早就习惯了NCL的声明式绘图,可能你会非常喜欢他。 ! |, r7 r8 m6 Z; H: l
一次偶然,我发现了Proplot这个库,Proplot对matplotlib进行了高度的封装,是一个高级绘图工具,其功能相当强大!而且融和了cartopy、basemap、xarray和pandas。作者是来自科罗拉多州立大学大气科学学院的硕士研究生Luke Davis。简单来说:Proplot针对matplotlib和cartopy的很多不友好的方面,并通过封装来解决这些问题。使用者可以通过新引入的format方法来完成繁琐复杂的图形设置问题(更简单的代码,更好看的图形)
e" u& w" j- V$ u ?4 o
; [7 g( B9 F) @) l 在官方文档中,已经大量的绘图例子,可以前往查看,下面简单展示一下具体的绘图效果:
* k! a0 [$ i6 E- J$ ?- F ①简单常用的填色图:
& }3 G2 q6 L& q- O( ?0 R import proplot as plot
; O: T# |# d( x S import numpy as np
( G+ y5 D7 v p2 P" W @# @' p- t$ D( \7 v: B
# 创建虚拟数据
5 v$ S k0 p( }; o offset = -40( m, G1 U% |4 B7 `
lon = plot.arange(offset, 360 + offset - 1, 60)
: _3 s# A r/ n! @/ C$ Z; H7 G lat = plot.arange(-60, 60 + 1, 30)
: s7 m, h1 n1 A! Q( g" E* E$ @ state = np.random.RandomState(51423)
, ~. z/ J8 r$ }; f; c* p data = state.rand(len(lat), len(lon)). P7 r3 |- G2 C* l) N4 q8 D6 m
6 w# }7 D* r- s) a z plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi
( k2 s4 s4 x1 [ proj = plot.Proj(cyl)( ~3 ~* P- R& k9 q
fig, axs = plot.subplots(nrows=1, ncols=2, axwidth=6, proj=proj)
# v7 P/ @4 I7 O0 d. T# B; x/ R axs.format(7 b' x; q1 M q: g- J& [' G
abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,( ~! i+ M$ T$ x) {7 V: M$ f
labels=True, lonlines=30, latlines=20,
1 ^3 V# w5 e& I! m% _0 s! C coast=True,gridminor=True,coastlinewidth=1,
# i; v Z2 ]$ w5 z" w" s4 g suptitle=Contourf,suptitlesize=20,( }4 ^4 `+ g0 e$ F0 f( ^ F) J9 y" G
rowlabels=[Cartopy example],
: j1 M. s L) U; F collabels=[Contourf, Pcolormesh])
/ ~/ U, ~/ f; j2 l cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度" J9 a- Y) m h- v
- V7 @/ [- w: L# F. O/ ` m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)
) g# W5 Y' P. ]" T. d axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)
# b- H6 d% ]/ y# O8 B" j
* ^1 y0 J+ L9 M& _4 W fig.colorbar(m, loc=b, label=State, M$ }0 ~. `( j3 X" l( A* R
labelsize=20,ticklabelsize=18, extendsize=1.7em)
9 c9 A. `% D W; H fig.save(rC:\Users\59799\Desktop\image.png,
: t, _* z0 F3 m, h* F* E* M dpi=600)
+ ? ^5 I* G4 u0 \( F plot.close()
: T- P9 a% b* F$ y
- r; L6 `- U0 g7 u7 \' \% b P9 {! h; H G
②子图特殊布局: 1 s* W% r0 ^2 j; P
import proplot as plot/ c8 j7 m% B5 _' @. j4 Z, `( N M
import numpy as np
: z! I2 Q9 }$ P- M) u/ Z7 [9 p# Q# q+ K* a1 Y
# 创建虚拟数据
& N# Y& x0 P' ^- i# E" b( U ?+ g offset = -40
4 ^+ M) @, K" Y lon = plot.arange(offset, 360 + offset - 1, 60)2 y2 \9 g' U$ K& ~
lat = plot.arange(-60, 60 + 1, 30)
/ w0 A' w# Q! [4 a state = np.random.RandomState(51423)/ O: @' P R6 T3 C$ o* y$ Z
data = state.rand(len(lat), len(lon))
' q; n, ]* f4 R7 G& P6 @$ i
+ `) P; E1 l, _( J* g4 }) n5 Z; m. w ]
subplot_array = [[0,1,1,0],
/ m" l# v# o3 e. Z [2,2,3,3]] #0表示没有图片 1 2 3...表示子图1 2 3...: T7 ~# N, |$ n: j
4 z5 p" D, @4 N/ l" b% g plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi/ e" `. V) A; f! H T/ @
proj = plot.Proj(cyl)
! e s( g7 p* A& g; s9 W- L6 c fig, axs = plot.subplots(subplot_array, axwidth=6, proj=proj)+ V/ u% M+ T& X& a7 h: ?' Z
axs.format(1 H; B8 f- G- o% i. I* y
abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,
Z0 e5 R5 w, l labels=True, lonlines=30, latlines=20,% ~6 ?2 f% J9 ~# x
coast=True,gridminor=True,coastlinewidth=1)- Y5 I9 h: h, ?8 z
cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度
& d: `8 q7 [6 e8 O0 x7 N8 t h `$ e2 b
m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)7 G$ X E) k0 P2 @( C* a# v
axs[0].format(title = subplot 1, titlesize=20)! _2 g% v/ q" D3 D5 O7 h5 n/ O& e+ g
1 d6 A, m; ]8 O/ @0 o' m axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)
+ |* D7 W/ D2 D: P5 [% ^/ X axs[1].format(title = subplot 2, titlesize=20)
7 i. U$ @, v/ s, L+ I& {
, I; O6 w# s4 e4 c+ Z axs[2].contour(lon, lat, data, extend=both)
I( h/ l7 _! m2 z axs[2].format(title = subplot 2, titlesize=20)" Y/ R5 o( J0 t8 d2 v% j
+ K- H9 _/ V' {5 y5 H
fig.colorbar(m, loc=b, label=State,% z5 w) K( K: z( Z8 u) P: J
labelsize=20,ticklabelsize=18, extendsize=1.7em)
; a+ k6 f$ b- p+ Q. X- h fig.save(rC:\Users\59799\Desktop\image.png,0 R$ t4 X7 U" z1 @( d
dpi=600)
: i7 w. l+ x/ f' ]6 r/ C plot.close()
3 D+ N% l. b- O 6 J5 Q1 I4 Q0 [
使用技巧:
, s1 E+ `+ J4 t! @7 @$ g) z" B1 j ①在保存图片时,默认保存的图片为1200dpi,如果直接放进word文档,可能会因为图片压缩导致图片异常(如果设置为不压缩,图片一多会导致word非常卡),所以请尽量使用dpi参数改变保存图片时候的dpi。
' _% { r, D7 R/ P" Q n: Z; r3 `! t ②format方法可以针对不同的子图设置不同格式,例如: 0 X, D& B. w2 Z0 ]
axs.format(...)#设置全部子图" Q3 Z- B3 `3 v, ~: x1 w# k4 t. p
axs[0:2].format(...)#设置第1张和第2张子图2 R3 C3 g! N& f" i
axs[0].format(...)#设置第1张子图 7 O8 z% m$ j; B( L* S. Y% \
③所有的图形设置都可以在format方法中通过参数的方法完成,具体的参数请查阅官方文档的Configuring ProPlot章节 2 [1 V" I5 U& _) `
④现在Proplot中还包含着basemap,个人不太推荐使用。
$ s% q8 [2 q; v% B, I: F
+ D( c6 v' [: C( T1 j
, s7 E7 B z* Y+ h; ~% o- ?& o3 k" E5 S
) R" i: y$ q0 l6 I* U- t |