|
o! c1 i6 t% W+ F9 K( T' h3 x
Notes:请务必将matplotlib的版本控制在3.2(或以下),经过测试发现,3.3及以后的版本在配合proplot使用时,在设置colorbar的时候会出现警告信息,同时生成的图不正常。降版本之后问题不再出现。 ; b5 I+ b+ G3 a8 d: I. D# V
在我的上一篇文章中,我推荐了由NCAR负责开发的PyNgl库作为Python语言下面的地理绘图库,并且介绍了如何在子系统(WSL)下面的安装方法。详细的请见传送门: ! i1 d4 @ A! x: r7 A% W
# b6 ~4 C0 V* n7 ]9 i
不过现在选择使用PyNgl有些尴尬,首先是官方宣布不再进行大更新了,只进行小修小补(维护模式),其次根据一些说法,PyNgl相较于NCL本身,还存在一些Bugs。总的来说就是体验一般。不过,如果很早就习惯了NCL的声明式绘图,可能你会非常喜欢他。 ! {9 T6 W* X! e# [5 t
一次偶然,我发现了Proplot这个库,Proplot对matplotlib进行了高度的封装,是一个高级绘图工具,其功能相当强大!而且融和了cartopy、basemap、xarray和pandas。作者是来自科罗拉多州立大学大气科学学院的硕士研究生Luke Davis。简单来说:Proplot针对matplotlib和cartopy的很多不友好的方面,并通过封装来解决这些问题。使用者可以通过新引入的format方法来完成繁琐复杂的图形设置问题(更简单的代码,更好看的图形)
- Q( |. C( M1 u) s: m' u6 `9 } ' f3 J2 T7 t& U7 Z
在官方文档中,已经大量的绘图例子,可以前往查看,下面简单展示一下具体的绘图效果:
' W9 Q4 F7 c8 n+ x+ } ①简单常用的填色图: - ]7 w9 V: s l- b. T
import proplot as plot3 z& J/ `( X2 W3 z( F" Q5 x' j
import numpy as np
* l; R: W8 c# }' V5 i5 }4 \6 e
# 创建虚拟数据" U( o) _4 O$ l$ I3 g
offset = -40+ J- P2 m) Q! x: L9 ^" M) l
lon = plot.arange(offset, 360 + offset - 1, 60)9 t: X+ q n8 k
lat = plot.arange(-60, 60 + 1, 30)8 I# H" G* A, q5 Z2 J
state = np.random.RandomState(51423)
3 Y+ Y- m( r5 K' g data = state.rand(len(lat), len(lon))
0 ? }) V" p& n5 z+ l% R/ U4 Y0 ?* D0 M/ {1 w5 A8 _0 M1 s. O
plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi+ l* s& _9 b* `
proj = plot.Proj(cyl)4 I4 E! }, f" Y
fig, axs = plot.subplots(nrows=1, ncols=2, axwidth=6, proj=proj)
: ?. ~& H2 [' V: T/ v axs.format(6 H% C3 h7 {3 z" ]9 f/ t, ]
abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,: a2 A; Z7 [, I
labels=True, lonlines=30, latlines=20,6 Q; r D3 u% \' h& `
coast=True,gridminor=True,coastlinewidth=1,
2 Z# N+ ?8 P$ M6 W, x. k' b r; ` suptitle=Contourf,suptitlesize=20,. t4 C2 {+ P8 `- P; w
rowlabels=[Cartopy example],8 Q/ h0 c, W( R! X
collabels=[Contourf, Pcolormesh])
: i9 J+ K6 E7 ] cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度* ^. E) B/ r K+ }
6 @& e& y# S2 V" }% q
m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)# ]& ~/ Z0 U$ ?; t2 ] `( D
axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)5 b% h9 h$ A7 B" N- \4 n
9 @" ?* N( ]% S% } fig.colorbar(m, loc=b, label=State,
! d7 L: m# s2 t* }$ x+ ^ labelsize=20,ticklabelsize=18, extendsize=1.7em)! o$ W( J8 ?" Q: K) E, q4 W, o& \
fig.save(rC:\Users\59799\Desktop\image.png," g6 B4 R5 {% v' {
dpi=600)) C/ f% I7 S9 f. S* C3 [" g$ W
plot.close()
' l' V# b2 S# ~8 n X4 U6 |' n
# [; G1 a0 O: O. h4 X % r* W' `/ V# @: v! g2 Y! \
②子图特殊布局:
. S8 a' F2 U: F3 z7 o import proplot as plot
$ r. {9 |9 J R) E/ ^ import numpy as np$ A9 _8 o5 R3 r) h6 [- D: ~
& M, f2 E4 l9 o1 f: J- k u$ e # 创建虚拟数据
3 s# ]; L" k0 h3 |+ m offset = -404 @0 g+ E q% s; C( f
lon = plot.arange(offset, 360 + offset - 1, 60)
3 W7 s# `. V4 m; D+ R, h lat = plot.arange(-60, 60 + 1, 30)! T3 X& J0 S& ]& O* p( Q2 n" T
state = np.random.RandomState(51423)' \; @$ `" m* p" C1 X) b
data = state.rand(len(lat), len(lon))
2 [. Q9 X6 s" I/ ]' x: B5 a u8 N0 i/ \# v& k/ B
: n! X' e6 {5 T5 g, s4 p- e subplot_array = [[0,1,1,0],4 `8 k5 Q: c6 v+ H, i
[2,2,3,3]] #0表示没有图片 1 2 3...表示子图1 2 3...
$ l9 p3 G1 |& } e. _" V
8 ^5 B. I1 N/ [5 | plot.rc.reso = lo#海岸线可以不同分辨率 hi med lo x-hi xx-hi
" ]2 e8 z* o) m- g7 l) I; d J proj = plot.Proj(cyl); g% y, R: j5 I, H! a+ H4 i
fig, axs = plot.subplots(subplot_array, axwidth=6, proj=proj)! ?, b' Y0 @; g! a6 h0 d
axs.format(
* z' `8 `# S% W abc=True,abcloc=ul,abcsize=30, abcstyle=a), gridlabelsize=18,
9 t) m! X- n" z labels=True, lonlines=30, latlines=20,4 K7 O1 ^- Q- p( ]7 J4 l" |8 C/ `; B
coast=True,gridminor=True,coastlinewidth=1) U4 K: n) j( W9 w9 x8 D
cmap=plot.Colormap(Div, gamma=0.6)#gamma提高颜色深度" |7 L& r) U$ k3 b
& W4 Z/ X( F6 O7 `. B, i m = axs[0].contourf(lon, lat, data, cmap=cmap, extend=both)
3 J4 n5 z! F7 I* z0 s/ Y axs[0].format(title = subplot 1, titlesize=20)
9 q4 W. s" m' j
; \* y& p1 {9 [ axs[1].pcolor(lon, lat, data, cmap=cmap, extend=both)
0 D5 a( ?4 T! E7 T% B, r7 D- C axs[1].format(title = subplot 2, titlesize=20)# @. ?" \$ M# L( k; U: U# Z
# j0 \! i6 j) d1 Y4 f( ~7 M' f0 J+ W axs[2].contour(lon, lat, data, extend=both)
+ _8 _1 ~3 |4 Y; @ axs[2].format(title = subplot 2, titlesize=20)3 j' C* e9 \+ i, ^; O/ }, u5 U# ~
! m5 \4 W, ~& ]6 ~! ~! S# e fig.colorbar(m, loc=b, label=State,
& c- A) Y% t6 ?3 V& H" s$ q labelsize=20,ticklabelsize=18, extendsize=1.7em)6 m, r, } b7 C( G0 M! c
fig.save(rC:\Users\59799\Desktop\image.png,
" l3 j' ]7 e* M$ b dpi=600)
/ ?/ b0 @" {2 Q& i$ k, G2 u5 I plot.close() - D! ]1 a" K8 r. @9 b# F+ r0 X
, u7 m% ^9 P0 C0 {8 F 使用技巧: 3 G7 e. x/ U$ F! v! {# q
①在保存图片时,默认保存的图片为1200dpi,如果直接放进word文档,可能会因为图片压缩导致图片异常(如果设置为不压缩,图片一多会导致word非常卡),所以请尽量使用dpi参数改变保存图片时候的dpi。 % _1 ~2 B, I! O" Z" v, A8 X
②format方法可以针对不同的子图设置不同格式,例如: : v$ o- X, ^! Y9 q" K; J4 V2 t' j
axs.format(...)#设置全部子图
6 Z/ M* [5 l/ e+ V. M axs[0:2].format(...)#设置第1张和第2张子图6 x6 Y/ S, i8 [' C0 }1 S/ L
axs[0].format(...)#设置第1张子图 6 K8 Z1 n( ?( n9 p; [
③所有的图形设置都可以在format方法中通过参数的方法完成,具体的参数请查阅官方文档的Configuring ProPlot章节
& Q; |) x: z4 U0 \6 n% l5 }! Y$ N ④现在Proplot中还包含着basemap,个人不太推荐使用。 " G6 @7 Z4 Q. F/ y! [
' N6 P9 Z9 w/ ]" [. ~9 d
$ M4 f8 p! G; Y3 Y7 J, v4 d; y! k( S- J7 o$ z
+ V+ ?! t S- V* D4 _* s h" n' U
|