. ^9 B2 J( e5 g C' ^
Notes:请务必将matplotlib的版本控制在3.2(或以下),经过测试发现,3.3及以后的版本在配合proplot使用时,在设置colorbar的时候会出现警告信息,同时生成的图不正常。降版本之后问题不再出现。 4 v4 W/ H# P% G
在我的上一篇文章中,我推荐了由NCAR负责开发的PyNgl库作为Python语言下面的地理绘图库,并且介绍了如何在子系统(WSL)下面的安装方法。详细的请见传送门: , Q9 D( A: c& b: [" J; `0 M
- {& n! |/ u) y: e6 @; S 不过现在选择使用PyNgl有些尴尬,首先是官方宣布不再进行大更新了,只进行小修小补(维护模式),其次根据一些说法,PyNgl相较于NCL本身,还存在一些Bugs。总的来说就是体验一般。不过,如果很早就习惯了NCL的声明式绘图,可能你会非常喜欢他。 5 ]4 P, S8 Y" k0 n( `, f( v
一次偶然,我发现了Proplot这个库,Proplot对matplotlib进行了高度的封装,是一个高级绘图工具,其功能相当强大!而且融和了cartopy、basemap、xarray和pandas。作者是来自科罗拉多州立大学大气科学学院的硕士研究生Luke Davis。简单来说:Proplot针对matplotlib和cartopy的很多不友好的方面,并通过封装来解决这些问题。使用者可以通过新引入的format方法来完成繁琐复杂的图形设置问题(更简单的代码,更好看的图形)
0 k. N( z( Q4 Z7 v8 Y& ]) b( ]3 u
) V0 p/ L! T/ o5 o5 S% E 在官方文档中,已经大量的绘图例子,可以前往查看,下面简单展示一下具体的绘图效果:
# s4 b- \% W# b3 O' W; t ①简单常用的填色图: 9 L- [2 `& B) |5 s
import proplot as plot: a+ F$ B; T, ~: t7 P/ r
import numpy as np
/ U' f8 t+ B$ _) L
8 M& R. E3 @" B/ P7 A # 创建虚拟数据
3 o9 c! G' ~# E2 ~" c7 m- L offset = -40
{, ]& _' n1 n( \ lon = plot.arange(offset, 360 + offset - 1, 60)
l+ G, o+ ?5 U* S lat = plot.arange(-60, 60 + 1, 30)! J8 S, }: l2 A. o
state = np.random.RandomState(51423)
6 l7 u- b, Q M& O- P data = state.rand(len(lat), len(lon))! }2 ~9 Y3 e! l+ I6 g8 H2 ]
1 {) J0 v$ p/ n: G8 S7 u1 u
plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi
' \% J* s" f/ j5 v! G9 {2 h proj = plot.Proj(cyl)$ a/ a9 Z5 D$ `5 o6 N7 N
fig, axs = plot.subplots(nrows=1, ncols=2, axwidth=6, proj=proj) e+ L+ v3 V+ ]6 E# f
axs.format(
/ G1 l7 v) P% ^0 k6 [1 L/ S7 x abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,
) w" n' K1 O, F+ Y labels=True, lonlines=30, latlines=20,
' y: n( T+ p. k4 K coast=True,gridminor=True,coastlinewidth=1,
( z! B8 S- i6 p K5 n9 Z# K0 w suptitle=Contourf,suptitlesize=20,1 W: U/ O7 d c3 M' J; C" j
rowlabels=[Cartopy example],' d4 s, Z0 V" ^$ Z) r$ Z
collabels=[Contourf, Pcolormesh])
# P' G" C8 v5 {! t& |/ D3 H cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度/ I# ~9 M( J% x$ Z9 R
- m1 _7 Y1 z1 H# c+ M3 G) W
m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)0 y6 m( W, ]1 J& \' ^
axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)8 j* E0 I, ?7 ~* y5 {
7 Z, a7 Z5 C" C4 c; v
fig.colorbar(m, loc=b, label=State,
- ]! }6 I' N V" `$ A! U0 K labelsize=20,ticklabelsize=18, extendsize=1.7em)
; y- q3 g4 ^$ F( V2 |& F& z) i fig.save(rC:\Users\59799\Desktop\image.png,
* J+ T; {, w6 D dpi=600)* V- B/ m: ~* X% v
plot.close()
3 `* j Y4 _, A7 ?6 e5 J * I+ B* n+ {$ ~8 C* }3 {$ S. j/ [
# B4 w( C% o* @ s9 Y
②子图特殊布局:
- Q" @: f% D* { import proplot as plot
5 Z4 c) q6 J7 v# _% Z: \ import numpy as np
( d- e" @0 [. e* ^4 w+ z3 j1 K7 a3 V$ ]* @
# 创建虚拟数据
+ p) ~3 _) L: _4 w4 v5 Y _ offset = -40
+ h# c7 g. q( l4 c. p$ m& n( w7 M: l7 A# s lon = plot.arange(offset, 360 + offset - 1, 60)
4 e6 `% h1 S2 ~1 B2 ] lat = plot.arange(-60, 60 + 1, 30)% b& x0 V# X: f6 Y0 @. y
state = np.random.RandomState(51423)
^& a* H- s( g" f& c I: \0 T& I data = state.rand(len(lat), len(lon))
/ Y- H1 s8 K1 Z
+ m e9 K9 b# v/ Q8 a+ f2 f% h0 `, S7 K/ S# d4 O u% n! v3 {3 w! u0 M$ S7 _
subplot_array = [[0,1,1,0],$ I. _! S) Y' S: r# t7 w
[2,2,3,3]] #0表示没有图片 1 2 3...表示子图1 2 3...
9 R+ x) [/ N! M7 s, e9 m2 g9 \1 r+ u/ ]# r- H4 u( G/ e6 Y
plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi5 w1 |$ |* y4 r4 ^( r2 l
proj = plot.Proj(cyl)
" [1 K, P* ~% h+ T. P7 Q+ }: w, A fig, axs = plot.subplots(subplot_array, axwidth=6, proj=proj)
7 X7 J" A g5 R1 T- R! \ axs.format(
4 D1 x! o" V" M, G abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18, d6 w0 x$ B$ E$ p& M/ Z: S
labels=True, lonlines=30, latlines=20,! P6 O. R/ [, i6 ]
coast=True,gridminor=True,coastlinewidth=1)
3 r2 T7 b5 y8 P: F cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度
( _9 X- Q. R! b. N
& h* t k5 Q3 l& ?5 {0 M# x m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)1 E- t% O! ]3 r
axs[0].format(title = subplot 1, titlesize=20)% k4 u3 q) B4 X( f
: T+ W$ J5 j% j" {0 A" h7 G# v axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)
6 U6 |. ?; ]' ?0 s axs[1].format(title = subplot 2, titlesize=20)
& s1 m! }* z% j6 H3 m. ]- v) X! F! R$ U u; \, y' e/ ~
axs[2].contour(lon, lat, data, extend=both)! C% f& \% o5 `" D1 h
axs[2].format(title = subplot 2, titlesize=20)( n& y4 Y o/ w& O8 R
# M* E& Y- U2 ^/ ^
fig.colorbar(m, loc=b, label=State,% h) p7 j9 L8 n# c" x9 u- g* e
labelsize=20,ticklabelsize=18, extendsize=1.7em)
, k6 H; x% X2 W fig.save(rC:\Users\59799\Desktop\image.png,. Y, m: N. B3 A- _. v4 K: \5 z$ | L
dpi=600)
- |( F1 h8 `2 |; Q+ K% O plot.close() & w" L! N; V0 i5 G) E
- `5 m" |) Y% q' \
使用技巧:
0 ]9 m% G8 L' a1 c. U3 q ①在保存图片时,默认保存的图片为1200dpi,如果直接放进word文档,可能会因为图片压缩导致图片异常(如果设置为不压缩,图片一多会导致word非常卡),所以请尽量使用dpi参数改变保存图片时候的dpi。
$ i! r9 s; v* c0 Y) k3 i2 q ②format方法可以针对不同的子图设置不同格式,例如:
8 j( e7 I) ?( X/ N$ p( Z0 H axs.format(...)#设置全部子图
" r: C6 g! K7 N axs[0:2].format(...)#设置第1张和第2张子图
5 X& q- v, k' K3 X9 K axs[0].format(...)#设置第1张子图 9 k3 @9 Z" e5 M
③所有的图形设置都可以在format方法中通过参数的方法完成,具体的参数请查阅官方文档的Configuring ProPlot章节 6 {8 _% G2 K' Z
④现在Proplot中还包含着basemap,个人不太推荐使用。
, z+ k9 j) w9 V" v) ^$ C% r b% K# _( e- o4 G& ^% p& g V. A
7 ?" U' v7 k# H' g# w8 u% j
- H5 T9 v+ _5 p! w
5 c9 n# o' E+ M4 T! w a |