|
* H+ Y) c$ f3 `2 W' V4 k1 M Notes:请务必将matplotlib的版本控制在3.2(或以下),经过测试发现,3.3及以后的版本在配合proplot使用时,在设置colorbar的时候会出现警告信息,同时生成的图不正常。降版本之后问题不再出现。
& t, R, X9 O9 k7 j! u& @ 在我的上一篇文章中,我推荐了由NCAR负责开发的PyNgl库作为Python语言下面的地理绘图库,并且介绍了如何在子系统(WSL)下面的安装方法。详细的请见传送门:
) d7 M# [' g0 A# H
( z/ D: d H6 \; M, l, G( A" V 不过现在选择使用PyNgl有些尴尬,首先是官方宣布不再进行大更新了,只进行小修小补(维护模式),其次根据一些说法,PyNgl相较于NCL本身,还存在一些Bugs。总的来说就是体验一般。不过,如果很早就习惯了NCL的声明式绘图,可能你会非常喜欢他。
( p% w/ K' y2 [/ r9 q9 q) ~ 一次偶然,我发现了Proplot这个库,Proplot对matplotlib进行了高度的封装,是一个高级绘图工具,其功能相当强大!而且融和了cartopy、basemap、xarray和pandas。作者是来自科罗拉多州立大学大气科学学院的硕士研究生Luke Davis。简单来说:Proplot针对matplotlib和cartopy的很多不友好的方面,并通过封装来解决这些问题。使用者可以通过新引入的format方法来完成繁琐复杂的图形设置问题(更简单的代码,更好看的图形)
0 f; n! S+ w0 G. d " W2 ?' J' |# a1 U" S0 k
在官方文档中,已经大量的绘图例子,可以前往查看,下面简单展示一下具体的绘图效果: 4 ]! \1 }3 W2 U+ }3 ]
①简单常用的填色图: / t) p& a2 c8 Q7 M' R: Q8 l
import proplot as plot8 C5 V- V& m* X! p$ H
import numpy as np
3 |6 g% I/ y2 m- ?5 k1 u: X' w1 O, O' ~: y
# 创建虚拟数据% I' _8 r# \! o
offset = -40' z N3 [' u9 o% X% `9 G
lon = plot.arange(offset, 360 + offset - 1, 60)
8 _% Y9 M' h( i% j3 H6 W' P% K0 ] lat = plot.arange(-60, 60 + 1, 30)
' c0 B1 d9 N3 ]: `3 j& k4 j state = np.random.RandomState(51423)
0 Y! V- g( U/ s# G- b. q' R data = state.rand(len(lat), len(lon))( q8 F2 i: Z7 y5 \
# Z0 }) j+ `9 X' S( V9 g: M5 V4 j plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi6 m6 j. Q+ K, o9 v+ G
proj = plot.Proj(cyl)2 M2 u9 z" n; K! z$ Y6 k
fig, axs = plot.subplots(nrows=1, ncols=2, axwidth=6, proj=proj)+ @- x* U' {( }
axs.format(! p; x- n7 n8 x- I
abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,
* J+ U; u! i7 A7 e labels=True, lonlines=30, latlines=20,( |9 {$ z: I$ `$ j8 R% ^
coast=True,gridminor=True,coastlinewidth=1,
( i3 L' j# M/ `$ {: m suptitle=Contourf,suptitlesize=20,1 i1 l! E4 R9 C( ~: o/ C4 z! y+ `" c
rowlabels=[Cartopy example],8 u2 e1 |, J( [7 E
collabels=[Contourf, Pcolormesh])
6 R$ |: M% \2 z cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度) o6 r$ p' O2 C& x1 }) |" X2 @/ G
$ F2 Z# `8 D& B# o7 y
m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)
% [% ?4 }. Y- E7 e+ F- h# e: | axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)
' f2 y. D4 _4 [; E; X5 |" ^
- h# W. ] ~0 _( x' ?* D, S; i fig.colorbar(m, loc=b, label=State,5 V: ]+ y; Q3 h/ z* R
labelsize=20,ticklabelsize=18, extendsize=1.7em)5 k; V. t1 l9 i! d
fig.save(rC:\Users\59799\Desktop\image.png,
+ }1 ]1 G/ @; z5 | dpi=600)/ x4 {( C6 E# c! {7 t- f
plot.close()2 E" F* ^+ T8 z3 Q3 j
* v6 d9 N- X* u8 g: u- d( r. m ) v4 n0 U0 ]# V( j5 e: u6 n
②子图特殊布局:
: Z0 l6 O5 n3 `1 V, }3 @( D import proplot as plot
7 e3 x1 F* w5 q) i% V import numpy as np2 a8 b# R6 I. u+ e
! J2 t$ n0 L. d6 L0 y3 P0 y
# 创建虚拟数据2 P0 q* W6 t- ~0 L! k
offset = -40! q" A' r7 J! Q! h7 ~4 h3 J
lon = plot.arange(offset, 360 + offset - 1, 60)
/ s9 ?4 B' q& c+ }$ F0 I$ f lat = plot.arange(-60, 60 + 1, 30)
. Y \6 ?8 D- Z6 Y* V9 b5 `1 m! T state = np.random.RandomState(51423)2 n2 p0 c; S; O1 a' h ?( s4 {
data = state.rand(len(lat), len(lon))" O0 M! F0 S0 \" R! |; e
# O2 F- Q4 Z% Z7 r. z. M0 s5 _5 Z4 s
! i# V7 c' Y" q
subplot_array = [[0,1,1,0],
8 Z9 ?! m& g. ^) f7 { [2,2,3,3]] #0表示没有图片 1 2 3...表示子图1 2 3...$ b( v/ N/ y: y' a& h
8 J$ \1 {* I: t1 ^: y
plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi
+ c U( q7 V: ?0 X proj = plot.Proj(cyl); v" W9 e% O2 L- }
fig, axs = plot.subplots(subplot_array, axwidth=6, proj=proj)
0 ? `7 F+ H( \ _3 Y3 x axs.format(& Q/ i8 m4 e# e$ Z4 o
abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,9 N% a$ I, n4 @, I3 z2 g
labels=True, lonlines=30, latlines=20,
: z- p( e) l4 J) R coast=True,gridminor=True,coastlinewidth=1)
% v, c" E* s2 r' K cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度+ J9 b. E# B, h3 z; N; E
2 n( l! r5 ]! a2 ?: b m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)
% I+ @, E0 X! H6 i, `9 ^ axs[0].format(title = subplot 1, titlesize=20)2 Z3 q& f$ N7 w* }2 p0 k
: @% v( R# J6 C: N
axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)
' K' |: V: c: _+ t- d* T* K/ B axs[1].format(title = subplot 2, titlesize=20)
/ f& i0 b) J3 R6 _# b0 O9 o
$ C" P, Z" }( J, @ axs[2].contour(lon, lat, data, extend=both)' i9 q/ f% d+ A) h8 Z& i
axs[2].format(title = subplot 2, titlesize=20). V2 h( s% U7 K: F
9 [. l2 A `$ o. k3 v& I0 B
fig.colorbar(m, loc=b, label=State,' }9 p4 ]+ E6 B- j1 j) X
labelsize=20,ticklabelsize=18, extendsize=1.7em)
: F0 d& k% \& R3 F! I% l fig.save(rC:\Users\59799\Desktop\image.png,/ [3 f* J- J6 S
dpi=600)
# W6 |0 L2 R, u( E% L plot.close() ' B5 y7 D' e" j$ H
1 v3 M2 _+ v9 Y- p* d
使用技巧: " j+ l P. q) T& Y9 X
①在保存图片时,默认保存的图片为1200dpi,如果直接放进word文档,可能会因为图片压缩导致图片异常(如果设置为不压缩,图片一多会导致word非常卡),所以请尽量使用dpi参数改变保存图片时候的dpi。
: R6 [5 o9 g. C8 F" e2 ]) s ②format方法可以针对不同的子图设置不同格式,例如:
# Z8 B7 X' _) m7 r1 H3 Z9 f axs.format(...)#设置全部子图5 P ^: @: t, p$ y+ I
axs[0:2].format(...)#设置第1张和第2张子图
1 U# t" [- I3 t1 z axs[0].format(...)#设置第1张子图
' K$ m0 v* Q# [6 H# C ③所有的图形设置都可以在format方法中通过参数的方法完成,具体的参数请查阅官方文档的Configuring ProPlot章节 ) h0 D. w' g) ?. z' W: y
④现在Proplot中还包含着basemap,个人不太推荐使用。 8 A. n0 Q- g# b7 x1 Y
6 f; _( ]8 F& D, B4 k
/ u9 U W; P/ }5 g
6 J- i& @+ M* p: q
. h% ^" Z. S* U. Q# l
|