-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsearch.xml
2939 lines (2602 loc) · 518 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>等高线图、填色图</title>
<url>/2020/06/10/ContourDiagram/</url>
<content><![CDATA[]]></content>
<categories>
<category>Plot</category>
</categories>
</entry>
<entry>
<title>Linear Baroclinic Model(线性斜压模式,LBM)初探</title>
<url>/2020/05/18/LBM%E6%A8%A1%E5%BC%8F%E5%88%9D%E6%8E%A2/</url>
<content><![CDATA[<p>介绍Linear Baroclinic Model(线性斜压模式,LBM)的安装与运行方法。LBM模式可以计算大气对规定强迫的稳定线性响应、特征分析,旨在通过消除动态大气过程中的非线性来帮助理解动态大气中复杂的反馈序列。</p>
<a id="more"></a>
<h1 id="一、LBM模式简介"><a href="#一、LBM模式简介" class="headerlink" title="一、LBM模式简介"></a>一、LBM模式简介</h1><p>LBM模式是为了研究大气中的线性动力学而建立的,例如计算对规定强迫的稳定线性响应、特征分析等等。</p>
<p>完全非线性的气候模型,如大气环流模型(AGCMs),得到了越来越多的改进,它们可以用来模拟和理解当前的气候,其中包括一些反馈过程。然而,这样的模型已经足够复杂了,如果不对输出结果进行彻底的分析,就很难对模型进行解释。而LBM中包含的线性大气模型旨在通过消除动态大气过程中的非线性来帮助理解动态大气中复杂的反馈序列。该模型简化了动力学框架,结果易于解释。此外,该模型提供了处理线性动力学的多种技术,这可能有助于研究大规模大气环流的各个方面。</p>
<p>官网链接:<a href="https://ccsr.aori.u-tokyo.ac.jp/~lbm/sub/lbm.html" target="_blank" rel="noopener">LBM官网</a></p>
<p>官方文档<a href="https://ccsr.aori.u-tokyo.ac.jp/~lbm/lbm/doc2.2.pdf" target="_blank" rel="noopener">下载</a></p>
<p>该模式由日本学者开发,而且是非开源的,因此需要下载安装包和模式数据的还是需要给作者发送邮件,表明目的,经作者授权后才能获得下载账户,去官网下载响应package。</p>
<p>作者邮箱:<a href="mailto:michiyah@hawaii.edu">michiyah@hawaii.edu</a></p>
<p>LBM模式推荐理由:全球气候模式比如CAM等等使用较为复杂(不论是移植还是运行),而且受限于大型机,对于个人的使用不友好,而LBM模式可以进行快速验证,且在个人PC即可使用,相对较为容易,且模拟时间短(往往几分钟即可生成结果)。当然了,一分价钱一分货,论知名度和准确性当然还是远远差于CAM模式的。</p>
<h1 id="二、编译"><a href="#二、编译" class="headerlink" title="二、编译"></a>二、编译</h1><h2 id="2-1-解压,设置环境变量"><a href="#2-1-解压,设置环境变量" class="headerlink" title="2.1 解压,设置环境变量"></a>2.1 解压,设置环境变量</h2><p>下载到压缩包后首先解压压缩包:</p>
<img src="/image/image-20200519095137865.png" alt="image-20200519095137865" style="zoom:67%;" />
<p>将ln_solver目录声明至环境变量:</p>
<p>建议直接修永久改环境变量:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">vim ~/.bashrc</span><br></pre></td></tr></table></figure>
<p>在其中加入:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">export LNHOME=/解压目录/ln_solver</span><br></pre></td></tr></table></figure>
<p>之后重新加载环境变量</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">source ~/.bashrc</span><br></pre></td></tr></table></figure>
<p>尝试:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">cd $LNHOME</span><br></pre></td></tr></table></figure>
<p>检查是否环境变量修改成功。</p>
<h2 id="2-2-配置分辨率"><a href="#2-2-配置分辨率" class="headerlink" title="2.2 配置分辨率"></a>2.2 配置分辨率</h2><p>修改$LNHOME/Lmake.inc文件,选择需要的水平分辨率和垂直分辨率(我使用的T42L20)。</p>
<p>Model type默认为tintgr。其余详细设置可参考文档。</p>
<h2 id="2-3-编译模式依赖"><a href="#2-3-编译模式依赖" class="headerlink" title="2.3 编译模式依赖"></a>2.3 编译模式依赖</h2><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">cd $LNHOME/model/src</span><br><span class="line">make lib</span><br></pre></td></tr></table></figure>
<p>之后会在$LNHOME/model/lib/???/文件夹下生成一个liblbmtxxmxxc.a的文件(xx为设置的分辨率格式)。</p>
<p>如果之后需要修改模式分辨率,则只需:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">cd $LNHOME/model/src</span><br><span class="line">make clean</span><br><span class="line">make lib</span><br></pre></td></tr></table></figure>
<h1 id="三、生成初始场"><a href="#三、生成初始场" class="headerlink" title="三、生成初始场"></a>三、生成初始场</h1><p>将从官网下载的两个数据包解压缩在$LNHOME文件夹下,之后编译初始场生成指令文件:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">cd $LNHOME/solver/util</span><br><span class="line">make bs</span><br></pre></td></tr></table></figure>
<p>这回导致生成两个新的指令</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">./ncepsbs</span><br><span class="line"><span class="meta">#</span><span class="bash">or</span></span><br><span class="line">./ecmsbs</span><br></pre></td></tr></table></figure>
<p>这两个指令分别用来生成NCEP的初值场和EC的初值场,根据自己需要选择即可。</p>
<p>设置初始场的选项位于$LNHOME/solver/util/SETPAR文件</p>
<p>NCEP:</p>
<img src="/image/image-20200519150909181.png" alt="image-20200519150909181" style="zoom:67%;" />
<p>EC:</p>
<img src="/image/image-20200519150953985.png" alt="image-20200519150953985" style="zoom:70%;" />
<p>其中,kmo指开始月份,navg指平均时期,如kmo=6,navg=3,指夏季平均状态。</p>
<h1 id="四、生成强迫"><a href="#四、生成强迫" class="headerlink" title="四、生成强迫"></a>四、生成强迫</h1><p>LBM模式的时间积分分支(time integration)的运行只需要处置场和强迫即可,不需要边界条件的设置。</p>
<p>同样,修改$LNHOME/solver/util/SETPAR文件,设置相关参数即可生成响应的强迫文件。</p>
<img src="/image/image-20200519151736163.png" alt="image-20200519151736163" style="zoom:67%;" />
<img src="/image/image-20200519151750314.png" alt="image-20200519151750314" style="zoom:67%;" />
<p>cfm,cfg为输出的强迫文件,nmvar为强迫变量,mnhpr为水平强迫设置,nmvpr为垂直强迫设置。</p>
<p>具体的参数信息可参见$LNHOME/solver/util/param_list文件。</p>
<p>这里列出一些简要信息:</p>
<img src="/image/image-20200519152018418.png" alt="image-20200519152018418" style="zoom:67%;" />
<p>修改好强迫配置后,输入以下命令生成强迫文件:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">cd $LNHOME/solver/util</span><br><span class="line">make clean</span><br><span class="line">make</span><br><span class="line">./mkfrcng</span><br></pre></td></tr></table></figure>
<p>make clean指令仅在第一次生成时使用即可。</p>
<h1 id="五、-运行"><a href="#五、-运行" class="headerlink" title="五、 运行"></a>五、 运行</h1><p>$LNHOME/model/sh/tintgr/文件夹下存放了很多运行不同模式方案的csh命令文件,主要靠可参考linear-run.classic.csh文件,将其中的分辨率修改为自己所用方案,将初值场和强迫场的存放路径与自己统一。</p>
<p>路径参数如下:</p>
<img src="/image/image-20200519152454674.png" alt="image-20200519152454674" style="zoom:67%;" />
<p>一般运行时间设置为20天左右,30天后斜压波会异常增长从而导致模式结果的异常。</p>
<p>注:经测试,tend并不是运行的时间,比如tend = 51,模式会运行20天,tend = 59模式会运行27天。具体还需自己测试。</p>
<p>运行模式的方法:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">cd $LNHOME/model/sh/tintgr/</span><br><span class="line">csh ***.csh</span><br></pre></td></tr></table></figure>
<h1 id="六、-后处理"><a href="#六、-后处理" class="headerlink" title="六、 后处理"></a>六、 后处理</h1><p>干模式输出结果包括u,v,t,z,w,p,psi,chi,湿模式还包括了q,dt,dq(我没用过湿模式)。</p>
<p>输出结果位于$LNHOME/data/out/ ,是.grd格式文件</p>
<p>建议使用CDO工具的</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">cdo -f nc import_binary out.ctl out.nc</span><br></pre></td></tr></table></figure>
<p>命令将其转为.nc格式。使用更加方便。</p>
<h1 id="致谢"><a href="#致谢" class="headerlink" title="致谢"></a>致谢</h1><p>感谢我的本科同学hhy大佬,在大佬的耐心指点下终于理清了LBM模式的安装和基本使用方法。感激!</p>
<p>最后的最后,给出一个我测试结果:尝试在巴伦支海上空加入了一个大气热源,模拟了20天后的大气异常。</p>
<p><img src="/image/image-20200519161417186.png" alt="results"></p>
]]></content>
<categories>
<category>Paper</category>
</categories>
<tags>
<tag>Model</tag>
</tags>
</entry>
<entry>
<title>Python vs NCL</title>
<url>/2021/06/23/NCL.vs.Python/</url>
<content><![CDATA[<p>通过示例对比Python和NCL,感受两种语言的区别。</p>
<p>NCL语言大概是从2018年开始,陪伴我走过了一年的时间,也帮助我发表了自己的第一篇文章。后来由于自己需要实现的算法过于复杂,自己无力编写,在朋友的诱惑下不得不转投Python,靠网上各路大神的帖子东拼西凑满足自己的科研需求。说卸磨杀驴也有点不合适,但在适应了Python之后,我确实基本没有再打开过NCL了。最近整理文件,找到了自己发表第一篇学术垃圾时候的NCL脚本,心血来潮的想再用Python实现一遍。也算是对评论里很多读者的一个回应吧(貌似气象家园帖子下边第一个评论就是希望我写一个两者对比的文章,被我鸽到现在,咕咕咕)。注:编程水平仅限于能跑就行,warning不管,冗杂语句请忽视。</p>
<a id="more"></a>
<h2 id="示例1(EOF)"><a href="#示例1(EOF)" class="headerlink" title="示例1(EOF)"></a>示例1(EOF)</h2><p>选择EOF的原因是图片内容较为丰富,同时方法较为常用</p>
<p>由于原始数据过大,只提供处理好的数据方便测试(数据为每年的寒潮路径的概率密度分布,为39年×90纬度×360经度,由FLEXPART模式追踪后通过高斯核密度估计算法Gaussian KDE得到。</p>
<p>测试数据和代码如下:</p>
<ol>
<li><p><a href="/image/out.nc">测试数据</a> 2. <a href="/image/nvp1_n.txt">NCL代码</a> 3. <a href="/image/nvp1_p.txt">Python代码</a></p>
<p>先对比下出图效果(两种语言对图形的渲染有差异,EOF算法可能也有些差异,但是结果是基本相同的,图只经过了基础的调整,并不是很好看)。</p>
<p><img src="/image/nclvspython.png" alt="NCL vs Python"></p>
</li>
</ol>
<h3 id="1-准备工作"><a href="#1-准备工作" class="headerlink" title="1 准备工作"></a>1 准备工作</h3><p><strong>NCL</strong>:在引入一些特殊函数(NCL本体不具备的函数)时,通常会加上类似于以下语句:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl"</span><br></pre></td></tr></table></figure>
<p><strong>Python</strong>:引入各个模块(库):</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> xarray <span class="keyword">as</span> xr</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> eofs.standard <span class="keyword">import</span> Eof</span><br><span class="line"><span class="keyword">import</span> cartopy.crs <span class="keyword">as</span> ccrs</span><br><span class="line"><span class="keyword">import</span> cartopy.feature <span class="keyword">as</span> cfeature</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="keyword">import</span> cartopy.mpl.ticker <span class="keyword">as</span> cticker</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">contour_map</span><span class="params">(fig,img_extent,spec)</span>:</span></span><br><span class="line"> fig.set_extent(img_extent, crs=ccrs.PlateCarree())</span><br><span class="line"> fig.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>)) </span><br><span class="line"> fig.add_feature(cfeature.LAKES, alpha=<span class="number">0.5</span>)</span><br><span class="line"> fig.set_xticks(np.arange(leftlon,rightlon+spec,spec), crs=ccrs.PlateCarree())</span><br><span class="line"> fig.set_yticks(np.arange(lowerlat,upperlat+spec,spec), crs=ccrs.PlateCarree())</span><br><span class="line"> lon_formatter = cticker.LongitudeFormatter()</span><br><span class="line"> lat_formatter = cticker.LatitudeFormatter()</span><br><span class="line"> fig.xaxis.set_major_formatter(lon_formatter)</span><br><span class="line"> fig.yaxis.set_major_formatter(lat_formatter)</span><br></pre></td></tr></table></figure>
<h3 id="2-数据读取"><a href="#2-数据读取" class="headerlink" title="2 数据读取"></a>2 数据读取</h3><p><strong>NCL</strong>:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">f=addfile("out.nc","r");读取文件</span><br><span class="line">dot=f->cspath(:,:,{0:180});读入变量</span><br><span class="line">dot:=dot(lat|:,lon|:,year|:);调整变量维度顺序(EOF函数对维度顺序有要求)</span><br><span class="line">x=ispan(1979,2017,1);时间</span><br></pre></td></tr></table></figure>
<p><strong>Python</strong>:利用Xarray库读取NC文件</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">f = xr.open_dataset(<span class="string">"out.nc"</span> )</span><br><span class="line">dot = np.array(f[<span class="string">'cspath'</span>].loc[:,<span class="number">0</span>:<span class="number">90</span>,:])</span><br><span class="line">lat = f[<span class="string">'lat'</span>].loc[<span class="number">0</span>:<span class="number">90</span>]</span><br><span class="line">lon = f[<span class="string">'lon'</span>]</span><br><span class="line">years = range(<span class="number">1979</span>, <span class="number">2018</span>)</span><br></pre></td></tr></table></figure>
<h3 id="3-EOF"><a href="#3-EOF" class="headerlink" title="3 EOF"></a>3 EOF</h3><p><strong>NCL</strong>:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">eof=eofunc_Wrap(dot,3,False)</span><br><span class="line">pc=eofunc_ts_Wrap(dot,eof,False)</span><br><span class="line">pc=dim_standardize_n(eof_ts,1,1)</span><br><span class="line">copy_VarMeta(dot(:,:,0),eof1);将维度信息重新赋值给新数组</span><br><span class="line">copy_VarMeta(dot(:,:,0),eof2)</span><br></pre></td></tr></table></figure>
<p><strong>Python</strong>:利用EOF库</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">solver = Eof(dot)</span><br><span class="line">eof = solver.eofsAsCorrelation(neofs=<span class="number">2</span>)</span><br><span class="line">pc = solver.pcs(npcs=<span class="number">2</span>, pcscaling=<span class="number">1</span>)</span><br><span class="line">var = solver.varianceFraction()</span><br></pre></td></tr></table></figure>
<h3 id="4-1-绘图:建立画布"><a href="#4-1-绘图:建立画布" class="headerlink" title="4.1 绘图:建立画布"></a>4.1 绘图:建立画布</h3><p>NCL的有些绘图参数并不是必要的,由于年代久远,我记不清起每条语句对应的详细功能了。</p>
<p><strong>NCL</strong>:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">wks=gsn_open_wks("pdf","tmp")</span><br><span class="line">res = True </span><br><span class="line">res@gsnMaximize = False</span><br><span class="line">res@gsnDraw = False</span><br><span class="line">res@gsnFrame = False</span><br><span class="line">res@gsnDraw=False</span><br><span class="line">res@gsnFrame=False</span><br><span class="line">respc=res;实际上是设置PC图形的基础绘图参数</span><br></pre></td></tr></table></figure>
<p><strong>Python</strong>:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">fig = plt.figure(figsize=(<span class="number">15</span>,<span class="number">15</span>))</span><br></pre></td></tr></table></figure>
<h3 id="4-2-绘图:绘制EOF"><a href="#4-2-绘图:绘制EOF" class="headerlink" title="4.2 绘图:绘制EOF"></a>4.2 绘图:绘制EOF</h3><p><strong>NCL</strong>:其绘图思路是每一条语句指定一个绘图效果,通过不断的”叠BUFF“实现全部要素的叠加,先将共同要素叠给res,然后通过res1=res, res2=res赋值后,再对res1和res2分别添加各自的属性。</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">res@mpMaxLatF=90;设置经纬度边界</span><br><span class="line">res@mpMinLatF=0</span><br><span class="line">res@mpMaxLonF=160</span><br><span class="line">res@mpMinLonF=0</span><br><span class="line">res@mpFillOn =False;地图设置</span><br><span class="line">res@mpOutlineOn = True</span><br><span class="line">res@mpDataBaseVersion = "MediumRes" </span><br><span class="line">res@mpDataSetName = "/data/home/Earth..4"</span><br><span class="line">res@cnFillPalette = "MPL_bwr"</span><br><span class="line">res@cnFillOn = True</span><br><span class="line">res@cnFillDrawOrder = "PreDraw"</span><br><span class="line">res@cnLinesOn = False</span><br><span class="line">res@cnLineLabelsOn = False</span><br><span class="line">res@gsnLeftString=""</span><br><span class="line">res@pmTickMarkDisplayMode = "Always" </span><br><span class="line">res@cnLevelSelectionMode="ExplicitLevels"</span><br><span class="line">res@cnLevels =(/-0.05,-0.04,-0.03,-0.02,-0.01,0,0.01,0.02,0.03,0.04,0.05/)</span><br><span class="line">res1=res</span><br><span class="line">res2=res</span><br><span class="line">res1@gsnRightString = "41.84%"</span><br><span class="line">res1@gsnLeftString = "EOF1"</span><br><span class="line">res1@lbLabelBarOn=False </span><br><span class="line">res2@gsnRightString = "14.59%"</span><br><span class="line">res2@gsnLeftString = "EOF2"</span><br><span class="line">res2@lbLabelBarOn=True</span><br><span class="line">map1 = gsn_csm_contour_map(wks,eof1,res1) ;绘图</span><br><span class="line">map2 = gsn_csm_contour_map(wks,eof2,res2)</span><br></pre></td></tr></table></figure>
<p><strong>Python</strong>:与NCL相似的地方在于需要对每个axes添加参数,不同的地方在于其一条指令可以包含多个效果(比如将所有设置填色绘图的参数全部加在f_ax1.contourf里)。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">proj = ccrs.PlateCarree(central_longitude=<span class="number">80</span>) <span class="comment">#投影</span></span><br><span class="line">leftlon, rightlon, lowerlat, upperlat = (<span class="number">0</span>,<span class="number">160</span>,<span class="number">10</span>,<span class="number">90</span>) <span class="comment">#地图边界</span></span><br><span class="line">img_extent = [leftlon, rightlon, lowerlat, upperlat]</span><br><span class="line">f_ax1 = fig.add_axes([<span class="number">0.1</span>, <span class="number">0.32</span>, <span class="number">0.3</span>, <span class="number">0.4</span>],projection = proj)<span class="comment">#EOF1</span></span><br><span class="line">contour_map(f_ax1,img_extent,<span class="number">20</span>) <span class="comment">#利用前边自定义的绘图函数,目的是省去绘制相同图形时需要再次设置地形,湖泊,轴刻度等参数</span></span><br><span class="line">f_ax1.set_title(<span class="string">'(a) EOF1'</span>,loc=<span class="string">'left'</span>)<span class="comment">#左标题</span></span><br><span class="line">f_ax1.set_title( <span class="string">'%.2f%%'</span> % (var[<span class="number">0</span>]*<span class="number">100</span>),loc=<span class="string">'right'</span>)<span class="comment">#右标题,解释方差</span></span><br><span class="line">f_ax1.contourf(lon,lat, eof[<span class="number">0</span>,:,:], levels=np.arange(<span class="number">-0.9</span>,<span class="number">1.0</span>,<span class="number">0.1</span>), zorder=<span class="number">0</span>, extend=<span class="string">'both'</span>,transform=ccrs.PlateCarree(), cmap=plt.cm.RdBu_r)<span class="comment">#绘制填色</span></span><br><span class="line">f_ax2 = fig.add_axes([<span class="number">0.1</span>, <span class="number">0.1</span>, <span class="number">0.3</span>, <span class="number">0.4</span>],projection = proj)<span class="comment">#EOF2</span></span><br><span class="line">contour_map(f_ax2,img_extent,<span class="number">20</span>)</span><br><span class="line">f_ax2.set_title(<span class="string">'(c) EOf'</span>,loc=<span class="string">'left'</span>)</span><br><span class="line">f_ax2.set_title( <span class="string">'%.2f%%'</span> % (var[<span class="number">1</span>]*<span class="number">100</span>),loc=<span class="string">'right'</span>)</span><br><span class="line">c2=f_ax2.contourf(lon,lat, eof[<span class="number">1</span>,:,:], levels=np.arange(<span class="number">-0.9</span>,<span class="number">1.0</span>,<span class="number">0.1</span>), zorder=<span class="number">0</span>, extend=<span class="string">'both'</span>, transform=ccrs.PlateCarree(), cmap=plt.cm.RdBu_r)</span><br><span class="line"><span class="comment">#绘制色标</span></span><br><span class="line">position=fig.add_axes([<span class="number">0.1</span>, <span class="number">0.17</span>, <span class="number">0.3</span>, <span class="number">0.017</span>])</span><br><span class="line">fig.colorbar(c2,cax=position,orientation=<span class="string">'horizontal'</span>,format=<span class="string">'%.1f'</span>,)</span><br></pre></td></tr></table></figure>
<h3 id="4-3-绘图:绘制PC"><a href="#4-3-绘图:绘制PC" class="headerlink" title="4.3 绘图:绘制PC"></a>4.3 绘图:绘制PC</h3><p><strong>NCL</strong>:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">respc@gsnYRefLine=0</span><br><span class="line">respc@trYMinF=-3</span><br><span class="line">respc@trYMaxF=3</span><br><span class="line">res9 = respc</span><br><span class="line">respc@tmYLLabelDeltaF=-1</span><br><span class="line">respc@trXMinF=1979</span><br><span class="line">respc@trXMaxF=2017</span><br><span class="line">respc@tiYAxisOn=False</span><br><span class="line">respc@tmXTOn =False</span><br><span class="line">respc@tmYROn = False</span><br><span class="line">respc@vpHeightF=0.39</span><br><span class="line">respc@vpWidthF=0.6</span><br><span class="line">respc@gsnLeftStringOrthogonalPosF = 0.04</span><br><span class="line">respc1 = respc</span><br><span class="line">respc1@gsnLeftString = "PC1"</span><br><span class="line">respc2 = respc</span><br><span class="line">respc2@gsnLeftString = "PC2"</span><br><span class="line">pc1= gsn_csm_xy(wks,x,eoft1,respc1)</span><br><span class="line">pc2= gsn_csm_xy(wks,x,eoft2,respc2)</span><br><span class="line">pc1_9 = runave_n_Wrap(eoft1, 9, 0, 0);9年滑动平均</span><br><span class="line">pc2_9 = runave_n_Wrap(eoft2, 9, 0, 0)</span><br><span class="line">res9@xyLineColor = "red"</span><br><span class="line">res9@xyLineThicknesses = 4</span><br><span class="line">plotpc9_1 = gsn_csm_xy(wks, x, pc1_9, res9)</span><br><span class="line">plotpc9_2 = gsn_csm_xy(wks, x, pc2_9, res9)</span><br><span class="line">overlay(pc1, plotpc9_1);叠加</span><br><span class="line">overlay(pc2, plotpc9_2)</span><br></pre></td></tr></table></figure>
<p><strong>Python</strong>:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">f_ax3 = fig.add_axes([<span class="number">0.45</span>, <span class="number">0.44</span>, <span class="number">0.3</span>, <span class="number">0.156</span>])<span class="comment">#绘制PC1</span></span><br><span class="line">f_ax3.set_title(<span class="string">'(b) PC1'</span>,loc=<span class="string">'left'</span>)</span><br><span class="line">f_ax3.set_ylim(<span class="number">-3</span>,<span class="number">3</span>)<span class="comment">#y轴上下限</span></span><br><span class="line">f_ax3.axhline(<span class="number">0</span>,linestyle=<span class="string">"-"</span>,c=<span class="string">'k'</span>)<span class="comment">#水平参考线</span></span><br><span class="line">f_ax3.plot(years,pc[:,<span class="number">0</span>],c=<span class="string">'k'</span>)<span class="comment">#绘制折线</span></span><br><span class="line">pc1_9 = np.convolve(pc[:,<span class="number">0</span>], np.repeat(<span class="number">1</span>/<span class="number">9</span>, <span class="number">9</span>), mode=<span class="string">'valid'</span>)<span class="comment">#计算九年滑动平均</span></span><br><span class="line">f_ax3.plot(years[<span class="number">4</span>:<span class="number">-4</span>],pc1_9,c=<span class="string">'r'</span>,lw=<span class="number">2</span>)<span class="comment">#绘制滑动平均</span></span><br><span class="line">f_ax4 = fig.add_axes([<span class="number">0.45</span>, <span class="number">0.22</span>, <span class="number">0.3</span>, <span class="number">0.156</span>])<span class="comment">#绘制PC2</span></span><br><span class="line">f_ax4.set_title(<span class="string">'(d) PC2'</span>,loc=<span class="string">'left'</span>)</span><br><span class="line">f_ax4.set_ylim(<span class="number">-3</span>,<span class="number">3</span>)</span><br><span class="line">f_ax4.axhline(<span class="number">0</span>,linestyle=<span class="string">"-"</span>,c=<span class="string">'k'</span>)</span><br><span class="line">f_ax4.plot(years,pc[:,<span class="number">1</span>],c=<span class="string">'k'</span>)</span><br><span class="line">pc2_9 = np.convolve(pc[:,<span class="number">1</span>], np.repeat(<span class="number">1</span>/<span class="number">9</span>, <span class="number">9</span>), mode=<span class="string">'valid'</span>)</span><br><span class="line">f_ax4.plot(years[<span class="number">4</span>:<span class="number">-4</span>],pc2_9,c=<span class="string">'r'</span>,lw=<span class="number">2</span>)</span><br></pre></td></tr></table></figure>
<h3 id="5-收尾工作"><a href="#5-收尾工作" class="headerlink" title="5 收尾工作"></a>5 收尾工作</h3><p><strong>NCL</strong>:将各个子图组合起来,并整体添加色标。由于NCL在一开始建立画布时就指定了输出文件和格式,因此这里不再需要。</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">resp=True</span><br><span class="line">resp@gsnPanelRowSpec=True</span><br><span class="line">resp@gsnPanelFigureStrings=(/"a","b","c","d"/)</span><br><span class="line">resp@gsnPanelFigureStringsFontHeightF=0.01</span><br><span class="line">resp@amJust="TopLeft"</span><br><span class="line">gsn_panel(wks,(/map1,pc1,map2,pc2/),(/2,2/),resp)</span><br></pre></td></tr></table></figure>
<p><strong>Python</strong>:图形输出。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment">#plt.show()</span></span><br><span class="line">plt.savefig(<span class="string">"eof.pdf"</span>)</span><br></pre></td></tr></table></figure>
<h3 id="6-小节"><a href="#6-小节" class="headerlink" title="6 小节"></a>6 小节</h3><p>就个人感觉而言,Python语言还是会更简洁,思路更清晰一些,尤其是在指定各个绘图参数的时候。由于这个示例并不涉及复杂数据处理部分,因此没有很好的体现python的优势。但是就图形本身而言,NCL毕竟作为专业的绘图工具还是有优势的,当然从审美的角度来看各花入个眼,看个人风格喜好吧。本来想的是可以将代码块分成两个纵列,逐条对比,但是首先MD编辑器不允许代码块分列,其次两种语言的差异也没办法逐条对比,最终只能妥协成现在这样。后边<strong>有时间的话</strong>会继续补充一些其它的示例,从数据处理等其它方面继续对比一下两种语言的差异。</p>
]]></content>
<categories>
<category>Paper</category>
</categories>
<tags>
<tag>Python</tag>
<tag>Matplotlib</tag>
</tags>
</entry>
<entry>
<title>泰勒图</title>
<url>/2023/12/11/TaylorDiagram/</url>
<content><![CDATA[<p> 目前可以用<a href="https://pypi.org/project/SkillMetrics/" target="_blank" rel="noopener">SkillMetrics</a>这个库中的相关函数来快速实现泰勒图的绘制。虽然总体效果还是差强人意,美感比NCL差不少,但好在简便可以快速出图了。</p>
<p>可以通过</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">pip3 install SkillMetrics</span><br></pre></td></tr></table></figure>
<p>来安装这个库。</p>
<p>直接上绘图代码:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> skill_metrics <span class="keyword">as</span> sm </span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="comment"># 提供数据,SD标准差(也可以是相对标准差),CC相关系数,rmsd均方根误差。 存放顺序分别为(观测,模式1,模式2,模式3...)所以SD和CC的第一个数值是1。</span></span><br><span class="line">sd = np.array([<span class="number">1</span>,<span class="number">0.82</span>,<span class="number">1.12</span>,<span class="number">1.48</span>,<span class="number">0.65</span>,<span class="number">0.8</span>])</span><br><span class="line">cc = np.array([<span class="number">1</span>,<span class="number">0.48</span>,<span class="number">0.36</span>,<span class="number">0.74</span>,<span class="number">0.54</span>,<span class="number">0.61</span>])</span><br><span class="line">rmsd = np.array([<span class="number">0</span>,<span class="number">1.68</span>,<span class="number">1.57</span>,<span class="number">1.92</span>,<span class="number">2.34</span>,<span class="number">2.18</span>])</span><br><span class="line">label=[<span class="string">'obs'</span>,<span class="string">'model_1'</span>,<span class="string">'model_2'</span>,<span class="string">'model_3'</span>,<span class="string">'model_4'</span>,<span class="string">'model_5'</span>]</span><br><span class="line"></span><br><span class="line">fig = plt.figure(figsize=(<span class="number">12</span>,<span class="number">8</span>))</span><br><span class="line">ax = fig.add_axes([<span class="number">0.1</span>, <span class="number">0.6</span>, <span class="number">0.6</span>, <span class="number">0.6</span>])</span><br><span class="line"><span class="comment"># 绘图核心函数</span></span><br><span class="line">sm.taylor_diagram(sd,rmsd,cc,markerLabel = label,markercolor=<span class="string">"k"</span>,markerSize=<span class="number">5</span>,markerLegend = <span class="string">'on'</span>,<span class="comment">#基本参数</span></span><br><span class="line"> colCOR=<span class="string">"k"</span>,styleCOR=<span class="string">"--"</span>,widthCOR=<span class="number">.4</span>, <span class="comment">#CC相关设置</span></span><br><span class="line"> colSTD=<span class="string">"k"</span>,widthSTD=<span class="number">.9</span>,styleSTD=<span class="string">"--"</span>,axismax=<span class="number">1.7</span>, <span class="comment">#SD相关设置</span></span><br><span class="line"> widthRMS=<span class="number">0.5</span>,labelRMS=<span class="string">''</span>,colRMS=<span class="string">'k'</span>, <span class="comment">#RMSD相关设置</span></span><br><span class="line"> colOBS=<span class="string">"r"</span>,styleOBS=<span class="string">"-"</span>,widthOBS=<span class="number">1</span>,markerObs=<span class="string">""</span>,titleOBS=<span class="string">"Observation"</span>, <span class="comment">#观测值设置</span></span><br><span class="line"> )</span><br><span class="line"></span><br><span class="line">ax.grid(<span class="literal">False</span>)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure>
<p>图形输出:</p>
<p><img src="/image/taylor_diagram.png" alt="image-20200523154901802"></p>
<p>以下是sm.taylor_diagram函数所支持的参数:</p>
<h2 id="基础参数"><a href="#基础参数" class="headerlink" title="基础参数"></a>基础参数</h2><table>
<thead>
<tr>
<th>参数</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>alpha</td>
<td>Blending of symbol face color (0.0 transparent through 1.0 opaque) (Default: 1.0)</td>
</tr>
<tr>
<td>axisMax</td>
<td>Maximum for the radial contours</td>
</tr>
<tr>
<td>colFrame</td>
<td>Color for the y and x spines</td>
</tr>
<tr>
<td>colorMap</td>
<td>‘on’ / ‘off’ (default): Switch to map color shading of markers to colormap (“on”) or min to max range of RMSDz values (“off”). Set to same value as option “nonRMSDz”.</td>
</tr>
<tr>
<td>labelWeight</td>
<td>Weight of the x & y axis labels</td>
</tr>
<tr>
<td>numberPanels</td>
<td>1 or 2: Panels to display (1 for positive correlations, 2 for positive and negative correlations). Default value depends on correlations (CORs).</td>
</tr>
<tr>
<td>overlay</td>
<td>‘on’ / ‘off’ (default): Switch to overlay current statistics on Taylor diagram. Only markers will be displayed.</td>
</tr>
</tbody></table>
<h3 id="当ColorMap-‘on’-时:"><a href="#当ColorMap-‘on’-时:" class="headerlink" title="当ColorMap = ‘on’ 时:"></a>当ColorMap = ‘on’ 时:</h3><table>
<thead>
<tr>
<th>参数</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>cmap</td>
<td>Choice of colormap. (Default: ‘jet’)</td>
</tr>
<tr>
<td>cmap_marker</td>
<td>Marker to use with colormap (Default: ‘d’)</td>
</tr>
<tr>
<td>cmap_vmax</td>
<td>Maximum range of colormap (Default: None)</td>
</tr>
<tr>
<td>cmap_vmin</td>
<td>Minimum range of colormap (Default: None)</td>
</tr>
</tbody></table>
<h2 id="Marker-设置"><a href="#Marker-设置" class="headerlink" title="Marker 设置"></a>Marker 设置</h2><table>
<thead>
<tr>
<th>参数</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>MarkerDisplayed</td>
<td>‘marker’ (default): Experiments are represented by individual symbols</td>
</tr>
<tr>
<td></td>
<td>‘colorBar’: Experiments are represented by a color described in a colorbar</td>
</tr>
</tbody></table>
<h3 id="当-MarkerDisplayed-‘marker’"><a href="#当-MarkerDisplayed-‘marker’" class="headerlink" title="当 MarkerDisplayed = ‘marker’"></a>当 MarkerDisplayed = ‘marker’</h3><table>
<thead>
<tr>
<th>参数</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>markerColor</td>
<td>Single color to use for all markers</td>
</tr>
<tr>
<td>markerColors</td>
<td>Dictionary with up to two colors as keys (‘face’, ‘edge’) to use for all markers when ‘markerlegend’ == ‘off’ or None. If None or ‘markerlegend’ == ‘on’, then uses only the value of ‘markercolor’. (Default: None)</td>
</tr>
<tr>
<td>markerLabel</td>
<td>Labels for markers</td>
</tr>
<tr>
<td>markerLabelColor</td>
<td>Marker label color (Default: black)</td>
</tr>
<tr>
<td>markerLayout</td>
<td>Matrix layout for markers in legend [nrow, ncolumn], e.g. [4,None] for 4 rows and [None,3] for 3 columns. (Default [15, no. markers/15] )</td>
</tr>
<tr>
<td>markerLegend</td>
<td>‘on’ / ‘off’ (default): Use legend for markers</td>
</tr>
<tr>
<td>markers</td>
<td>Dictionary providing individual control of the marker label, label color, symbol, size, face color, and edge color (Default: None)</td>
</tr>
<tr>
<td>markerSize</td>
<td>Marker size (Default: 10)</td>
</tr>
<tr>
<td>markerSymbol</td>
<td>Marker symbol (Default: ‘o’)</td>
</tr>
</tbody></table>
<h3 id="当MarkerDisplayed-‘colorbar’时:"><a href="#当MarkerDisplayed-‘colorbar’时:" class="headerlink" title="当MarkerDisplayed = ‘colorbar’时:"></a>当MarkerDisplayed = ‘colorbar’时:</h3><table>
<thead>
<tr>
<th>参数</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>cmapZData</td>
<td>Data values to use for color mapping of markers, e.g. RMSD or BIAS (Default empty). Used to make range of values appear beside color bar.</td>
</tr>
<tr>
<td>locationColorBar</td>
<td>Location for the colorbar, ‘NorthOutside’ or ‘EastOutside’.</td>
</tr>
<tr>
<td>titleColorBar</td>
<td>Title of the colorbar</td>
</tr>
</tbody></table>
<h2 id="RMSD的相关设置"><a href="#RMSD的相关设置" class="headerlink" title="RMSD的相关设置"></a>RMSD的相关设置</h2><table>
<thead>
<tr>
<th>参数</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>colRMS</td>
<td>RMS grid and tick labels color. (Default: green)</td>
</tr>
<tr>
<td>labelRMS</td>
<td>RMS axis label (Default: ‘RMSD’)</td>
</tr>
<tr>
<td>rincRMS</td>
<td>Axis tick increment for RMS values</td>
</tr>
<tr>
<td>rmsLabelFormat</td>
<td>String format for RMS contour labels, e.g. ‘0:.2f’. (Default ‘0’, format as specified by str function.)</td>
</tr>
<tr>
<td>showlabelsRMS</td>
<td>‘on’ / ‘off’ (default): Show the RMS tick labels</td>
</tr>
<tr>
<td>styleRMS</td>
<td>Line style of the RMS grid</td>
</tr>
<tr>
<td>tickRMS</td>
<td>RMS values to plot gridding circles from observation point</td>
</tr>
<tr>
<td>tickRMSangle</td>
<td>Angle for RMS tick labels with the observation point. (Default: 135 deg.)</td>
</tr>
<tr>
<td>titleRMS</td>
<td>‘on’ / ‘off’ (default): Show RMSD axis title</td>
</tr>
<tr>
<td>titleRMSDangle</td>
<td>Angle at which to display the ‘RMSD’ label for the RMS contours (Default: 160 degrees)</td>
</tr>
<tr>
<td>widthRMS</td>
<td>Line width of the RMS grid</td>
</tr>
</tbody></table>
<h2 id="标准差的相关设置"><a href="#标准差的相关设置" class="headerlink" title="标准差的相关设置"></a>标准差的相关设置</h2><table>
<thead>
<tr>
<th>colSTD</th>
<th>STD grid and tick labels color. (Default: black)</th>
</tr>
</thead>
<tbody><tr>
<td>colsSTD</td>
<td>STD dictionary of grid colors with: ‘grid’, ‘tick_labels’, ‘title’ keys/values. If not provided or None, considers the monotonic ‘colSTD’ argument. (“Default: None”)</td>
</tr>
<tr>
<td>rincSTD</td>
<td>Axis tick increment for STD values</td>
</tr>
<tr>
<td>showlabelsSTD</td>
<td>‘on’ / ‘off’ (default): Show the STD tick labels</td>
</tr>
<tr>
<td>styleSTD</td>
<td>Line style of the STD grid</td>
</tr>
<tr>
<td>tickSTD</td>
<td>STD values to plot gridding circles from observation point</td>
</tr>
<tr>
<td>titleSTD</td>
<td>‘on’ / ‘off’ (default): Show STD axis title</td>
</tr>
<tr>
<td>widthSTD</td>
<td>Line width of the STD grid</td>
</tr>
</tbody></table>
<h2 id="相关系数的相关设置"><a href="#相关系数的相关设置" class="headerlink" title="相关系数的相关设置"></a>相关系数的相关设置</h2><table>
<thead>
<tr>
<th>参数</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>colCOR</td>
<td>CORRELATION grid color. (Default: blue)</td>
</tr>
<tr>
<td>colsCOR</td>
<td>CORRELATION dictionary of grid colors with: ‘grid’, ‘tick_labels’, ‘title’ keys/values. If not provided or None, considers the monotonic ‘colSTD’ argument. (“Default: None”)</td>
</tr>
<tr>
<td>showlabelsCOR</td>
<td>‘on’ (default) / ‘off’: Show the CORRELATION tick labels</td>
</tr>
<tr>
<td>styleCOR</td>
<td>Line style of the CORRELATION grid</td>
</tr>
<tr>
<td>tickCOR[panel]</td>
<td>Tick values for correlation coefficients for two types of panelsCOR grid values</td>
</tr>
<tr>
<td>titleCOR</td>
<td>‘on’ / ‘off’ (default): Show CORRELATION axis title</td>
</tr>
<tr>
<td>titleCORshape</td>
<td>The shape of the label ‘correlation coefficient’. Accepted values are ‘curved’ or ‘linear’. (Default: ‘curved’)</td>
</tr>
<tr>
<td>widthCOR</td>
<td>Line width of the COR grid</td>
</tr>
</tbody></table>
<h2 id="观测点设置"><a href="#观测点设置" class="headerlink" title="观测点设置"></a>观测点设置</h2><table>
<thead>
<tr>
<th>参数</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>colOBS</td>
<td>Observation STD color. (Default: magenta)</td>
</tr>
<tr>
<td>markerObs</td>
<td>Marker to use for x-axis indicating observed STD.A choice of ‘None’ will suppress appearance of marker. (Default None)</td>
</tr>
<tr>
<td>styleOBS</td>
<td>Line style for observation grid line. A choice of empty string (‘’) will suppress appearance of the grid line. (Default: ‘’)</td>
</tr>
<tr>
<td>titleOBS</td>
<td>Label for observation STD point on axis</td>
</tr>
<tr>
<td>widthOBS</td>
<td>Line width of the observation STD circle</td>
</tr>
</tbody></table>
<p>—————————————————以下是老版本,不删了留个记忆————————————————————</p>
<p>泰勒图绘制的核心思想是设计一个只有第一象限的极坐标,并将方差,相关系数进行捆绑,通过转化为极坐标系坐标进行绘制。为了实现泰勒图的绘制,设计了两个函数:</p>
<p>set_tayloraxes(fig, location=111) 和plot_taylor(axes, refsample, sample, <em>args, *</em>kwargs)</p>
<p>set_tayloraxes()函数用于建立一个泰勒图的坐标系,这个自定义函数一般情况下不建议修改,每一个参数都是经过多次调试得到的,很可能牵一发动全身。因此,将绘图部分的独立成为了plot_taylor函数(),这部分函数较为简单,目的就是将需要绘图的数据,转换为极坐标系坐标,通过plot函数将散点打在泰勒图上,这个函数模块较为简单,可以根据自己的输入数据情况进行调整。</p>
<p>下面直接给出两个函数的完整代码:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> matplotlib.projections <span class="keyword">import</span> PolarAxes</span><br><span class="line"><span class="keyword">from</span> mpl_toolkits.axisartist <span class="keyword">import</span> floating_axes</span><br><span class="line"><span class="keyword">from</span> mpl_toolkits.axisartist <span class="keyword">import</span> grid_finder</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">set_tayloraxes</span><span class="params">(fig, location=<span class="number">111</span>)</span>:</span></span><br><span class="line"> trans = PolarAxes.PolarTransform()</span><br><span class="line"> r1_locs = np.hstack((np.arange(<span class="number">1</span>,<span class="number">10</span>)/<span class="number">10.0</span>,[<span class="number">0.95</span>,<span class="number">0.99</span>]))</span><br><span class="line"> t1_locs = np.arccos(r1_locs) </span><br><span class="line"> gl1 = grid_finder.FixedLocator(t1_locs) </span><br><span class="line"> tf1 = grid_finder.DictFormatter(dict(zip(t1_locs, map(str,r1_locs))))</span><br><span class="line"> r2_locs = np.arange(<span class="number">0</span>,<span class="number">2</span>,<span class="number">0.25</span>)</span><br><span class="line"> r2_labels = [<span class="string">'0 '</span>, <span class="string">'0.25 '</span>, <span class="string">'0.50 '</span>, <span class="string">'0.75 '</span>, <span class="string">'REF '</span>, <span class="string">'1.25 '</span>, <span class="string">'1.50 '</span>, <span class="string">'1.75 '</span>]</span><br><span class="line"> gl2 = grid_finder.FixedLocator(r2_locs)</span><br><span class="line"> tf2 = grid_finder.DictFormatter(dict(zip(r2_locs, map(str,r2_labels))))</span><br><span class="line"> ghelper = floating_axes.GridHelperCurveLinear(trans,extremes=(<span class="number">0</span>,np.pi/<span class="number">2</span>,<span class="number">0</span>,<span class="number">1.75</span>),</span><br><span class="line"> grid_locator1=gl1,tick_formatter1=tf1,</span><br><span class="line"> grid_locator2=gl2,tick_formatter2=tf2)</span><br><span class="line"> ax = floating_axes.FloatingSubplot(fig, location, grid_helper=ghelper)</span><br><span class="line"> fig.add_subplot(ax)</span><br><span class="line"> ax.axis[<span class="string">"top"</span>].set_axis_direction(<span class="string">"bottom"</span>) </span><br><span class="line"> ax.axis[<span class="string">"top"</span>].toggle(ticklabels=<span class="literal">True</span>, label=<span class="literal">True</span>)</span><br><span class="line"> ax.axis[<span class="string">"top"</span>].major_ticklabels.set_axis_direction(<span class="string">"top"</span>)</span><br><span class="line"> ax.axis[<span class="string">"top"</span>].label.set_axis_direction(<span class="string">"top"</span>)</span><br><span class="line"> ax.axis[<span class="string">"top"</span>].label.set_text(<span class="string">"Correlation"</span>)</span><br><span class="line"> ax.axis[<span class="string">"left"</span>].set_axis_direction(<span class="string">"bottom"</span>) </span><br><span class="line"> ax.axis[<span class="string">"left"</span>].label.set_text(<span class="string">"Standard deviation"</span>)</span><br><span class="line"> ax.axis[<span class="string">"right"</span>].set_axis_direction(<span class="string">"top"</span>) </span><br><span class="line"> ax.axis[<span class="string">"right"</span>].toggle(ticklabels=<span class="literal">True</span>)</span><br><span class="line"> ax.axis[<span class="string">"right"</span>].major_ticklabels.set_axis_direction(<span class="string">"left"</span>)</span><br><span class="line"> ax.axis[<span class="string">"bottom"</span>].set_visible(<span class="literal">False</span>) </span><br><span class="line"> ax.grid()</span><br><span class="line"> polar_ax = ax.get_aux_axes(trans) </span><br><span class="line"> t = np.linspace(<span class="number">0</span>,np.pi/<span class="number">2</span>)</span><br><span class="line"> r = np.zeros_like(t) + <span class="number">1</span></span><br><span class="line"> polar_ax.plot(t,r,<span class="string">'k--'</span>)</span><br><span class="line"> polar_ax.text(np.pi/<span class="number">2</span>+<span class="number">0.042</span>,<span class="number">1.03</span>, <span class="string">" 1.00"</span>, size=<span class="number">10.5</span>,ha=<span class="string">"right"</span>, va=<span class="string">"top"</span>,</span><br><span class="line"> bbox=dict(boxstyle=<span class="string">"square"</span>,ec=<span class="string">'w'</span>,fc=<span class="string">'w'</span>))</span><br><span class="line"> <span class="keyword">return</span> polar_ax</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">plot_taylor</span><span class="params">(axes, refsample, sample, *args, **kwargs)</span>:</span></span><br><span class="line"> std = np.std(sample)</span><br><span class="line"> corr = np.corrcoef(refsample, sample) </span><br><span class="line"> theta = np.arccos(corr[<span class="number">0</span>,<span class="number">1</span>])</span><br><span class="line"> t,r = theta,std</span><br><span class="line"> d = axes.plot(t,r, *args, **kwargs) </span><br><span class="line"> <span class="keyword">return</span> d</span><br></pre></td></tr></table></figure>
<p>下面介绍下函数的具体用法:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">setup_axes(fig, rect=<span class="number">111</span>)</span><br></pre></td></tr></table></figure>
<p>输入:</p>
<p>fig: 需要绘图的figure</p>
<p>rect:图的位置,如111为1行1列第一个,122为1行2列第2个</p>
<p>输出:</p>
<p>polar_ax:泰勒坐标系</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">plot_taylor(axes, refsample, sample, *args, **kwargs)</span><br></pre></td></tr></table></figure>
<p>输入:</p>
<p>axes : setup_axes返回的泰勒坐标系</p>
<p>refsample :参照样本</p>
<p>sample :评估样本</p>
<p><em>args, *</em>kwargs :plt.plot()函数的相关参数,设置点的颜色,形状等等。</p>
<p>下面给出示例:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">x = np.linspace(<span class="number">0</span>,<span class="number">10</span>*np.pi,<span class="number">100</span>)</span><br><span class="line">data = np.sin(x) </span><br><span class="line">m1 = data + <span class="number">0.4</span>*np.random.randn(len(x)) </span><br><span class="line">m2 = <span class="number">0.3</span>*data + <span class="number">0.6</span>*np.random.randn(len(x)) </span><br><span class="line">m3 = np.sin(x-np.pi/<span class="number">10</span>) </span><br><span class="line">fig = plt.figure(figsize=(<span class="number">10</span>,<span class="number">4</span>))</span><br><span class="line">ax1 = set_tayloraxes(fig, <span class="number">121</span>)</span><br><span class="line">ax2 = set_tayloraxes(fig, <span class="number">122</span>)</span><br><span class="line">d1 = plot_taylor(ax2,data,m1, <span class="string">'bo'</span>)</span><br><span class="line">d2 = plot_taylor(ax2,data,m2, <span class="string">'ro'</span>)</span><br><span class="line">d3 = plot_taylor(ax2,data,m3, <span class="string">'go'</span>)</span><br></pre></td></tr></table></figure>
<p><img src="/image/image-20200523154901802.png" alt="image-20200523154901802"></p>
]]></content>
<categories>
<category>Plot</category>
</categories>
</entry>
<entry>
<title>单变量柱状图</title>
<url>/2020/09/03/bar1/</url>
<content><![CDATA[<p>同样使用折线图示例中使用过的数据</p>
<p>最基础的柱状图绘制如下:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="comment">#数据读取</span></span><br><span class="line">ao = pd.read_csv(<span class="string">"AO.txt"</span>,sep=<span class="string">'\s+'</span>,header=<span class="literal">None</span>, names=[<span class="string">'year'</span>,<span class="string">'month'</span>,<span class="string">'AO'</span>]) </span><br><span class="line">ao_jan = ao[ao.month==<span class="number">1</span>]</span><br><span class="line"><span class="comment">#创建Figure及Axes</span></span><br><span class="line">fig = plt.figure(figsize=(<span class="number">10</span>, <span class="number">8</span>))</span><br><span class="line">ax1 = fig.add_subplot(<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>)</span><br><span class="line">ax1.set_title(<span class="string">'1950-2019 January AO Index'</span>)</span><br><span class="line"><span class="comment">#绘制柱状图</span></span><br><span class="line">ax1.bar(np.arange(<span class="number">1950</span>,<span class="number">2020</span>,<span class="number">1</span>),ao_jan.AO)</span><br><span class="line"><span class="comment">#添加0值参考线</span></span><br><span class="line">ax1.axhline(<span class="number">0</span>,c=<span class="string">'k'</span>)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure>
<p>输出图形如下:</p>
<p><img src="/image/bar1-1.png" alt="image-20200702161610554"></p>
<p>为了更鲜明的区分正值和负值,我们常将正负值的bar设置为不同颜色,方法如下:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="comment">#数据读取</span></span><br><span class="line">ao = pd.read_csv(<span class="string">"AO.txt"</span>,sep=<span class="string">'\s+'</span>,header=<span class="literal">None</span>, names=[<span class="string">'year'</span>,<span class="string">'month'</span>,<span class="string">'AO'</span>]) </span><br><span class="line">ao_jan = ao[ao.month==<span class="number">1</span>]</span><br><span class="line"><span class="comment">#创建颜色数组</span></span><br><span class="line">colors = np.zeros(ao_jan.AO.shape,dtype=np.str)</span><br><span class="line">colors[ao_jan.AO>=<span class="number">0</span>] = <span class="string">'red'</span></span><br><span class="line">colors[ao_jan.AO<<span class="number">0</span>] = <span class="string">'blue'</span></span><br><span class="line"><span class="comment">#创建Figure及Axes</span></span><br><span class="line">fig = plt.figure(figsize=(<span class="number">10</span>, <span class="number">8</span>))</span><br><span class="line">ax1 = fig.add_subplot(<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>)</span><br><span class="line">ax1.set_title(<span class="string">'1950-2019 January AO Index'</span>)</span><br><span class="line"><span class="comment">#绘制柱状图</span></span><br><span class="line">ax1.bar(np.arange(<span class="number">1950</span>,<span class="number">2020</span>,<span class="number">1</span>),ao_jan.AO,color=colors)</span><br><span class="line"><span class="comment">#添加0值参考线</span></span><br><span class="line">ax1.axhline(<span class="number">0</span>,c=<span class="string">'k'</span>)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure>
<p>输出图形如下:</p>
<p><img src="/image/bar1-2.png" alt="image-20200702161610554"></p>
]]></content>
<categories>
<category>Plot</category>
</categories>
</entry>
<entry>
<title>多变量柱状图</title>
<url>/2020/09/03/bar2/</url>
<content><![CDATA[<p>数据同样利用折线图示例中所使用的AO.txt</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="comment">#数据读取</span></span><br><span class="line">ao = pd.read_csv(<span class="string">"AO.txt"</span>,sep=<span class="string">'\s+'</span>,header=<span class="literal">None</span>, names=[<span class="string">'year'</span>,<span class="string">'month'</span>,<span class="string">'AO'</span>]) </span><br><span class="line">ao_dec = ao[ao.month==<span class="number">12</span>]</span><br><span class="line">ao_jan = ao[ao.month==<span class="number">1</span>]</span><br><span class="line">ao_feb = ao[ao.month==<span class="number">2</span>]</span><br><span class="line"><span class="comment">#创建Figure及Axes</span></span><br><span class="line">fig = plt.figure(figsize=(<span class="number">10</span>, <span class="number">8</span>))</span><br><span class="line">ax1 = fig.add_subplot(<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>)</span><br><span class="line">ax1.set_title(<span class="string">'1979-2019 DJF AO Index'</span>)</span><br><span class="line"><span class="comment">#绘制柱状图</span></span><br><span class="line">ax1.bar(np.arange(<span class="number">2000</span>,<span class="number">2020</span>,<span class="number">1</span>)<span class="number">-0.25</span>,ao_dec.AO[<span class="number">50</span>:],width=<span class="number">0.25</span>,color=<span class="string">'r'</span>,label=<span class="string">'Dec'</span>)</span><br><span class="line">ax1.bar(np.arange(<span class="number">2000</span>,<span class="number">2020</span>,<span class="number">1</span>),ao_jan.AO[<span class="number">50</span>:],width=<span class="number">0.25</span>,color=<span class="string">'b'</span>,label=<span class="string">'Jan'</span>)</span><br><span class="line">ax1.bar(np.arange(<span class="number">2000</span>,<span class="number">2020</span>,<span class="number">1</span>)+<span class="number">0.25</span>,ao_feb.AO[<span class="number">50</span>:],width=<span class="number">0.25</span>,color=<span class="string">'g'</span>,label=<span class="string">'Feb'</span>)</span><br><span class="line"><span class="comment">#添加0值参考线</span></span><br><span class="line">ax1.axhline(<span class="number">0</span>,c=<span class="string">'k'</span>)</span><br><span class="line"><span class="comment">#添加图例</span></span><br><span class="line">ax1.legend()</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure>
<p>输出图形如下:</p>
<p><img src="/image/bar2-1.png" alt="image-20200702161610554"></p>
]]></content>
<categories>
<category>Plot</category>
</categories>
</entry>
<entry>
<title>Bash for Download</title>
<url>/2020/05/23/bashfordownload/</url>
<content><![CDATA[<p>利用Bash脚本下载资料(默认用于NOAA网站相关资料集)。使用时修改https内容。格式化函数${i}使用方法类似Python语言的format函数。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="keyword">for</span> (( i = 1948; i < 2023; i++))</span><br><span class="line"><span class="keyword">do</span></span><br><span class="line"> wget --no-check-certificate https://downloads.psl.noaa.gov/Datasets/ncep.reanalysis.dailyavgs/surface_gauss/air.2m.gauss.<span class="variable">${i}</span>.nc </span><br><span class="line"><span class="keyword">done</span></span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>Other</category>
</categories>
<tags>
<tag>Python</tag>
<tag>Plot</tag>
</tags>
</entry>
<entry>
<title>CDO简介及常用语法</title>
<url>/2020/06/07/cdo/</url>
<content><![CDATA[<p>Climate Data Operators (CDO) 是用来处理气候数据的软件,可以在linux环境下直接对数据文件进行处理,通过筛选,删除,修改等操作从原始数据文件中得到自己所需的资料格式,配合Python,NCL等语言的使用十分方便。</p>
<a id="more"></a>
<h2 id="一、-CDO安装"><a href="#一、-CDO安装" class="headerlink" title="一、 CDO安装"></a>一、 CDO安装</h2><p>仍然是推荐在CONDA环境下使用CDO,安装也十分的方便:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">conda install -c conda-forge cdo</span><br></pre></td></tr></table></figure>
<p>使用或者使用Ubuntu系统的安装指令也可:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">apt-get install cdo</span><br></pre></td></tr></table></figure>
<h2 id="二、基本语法"><a href="#二、基本语法" class="headerlink" title="二、基本语法"></a>二、基本语法</h2><p>CDO的使用很简单,基本语法只有一条:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">cdo [ Options ] Operator1 [ -Operator2 [ -OperatorN ] ]</span><br></pre></td></tr></table></figure>
<p>这么看起来还是麻烦,那么再简化就是:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">cdo [ Options ] Operator</span><br></pre></td></tr></table></figure>
<p>cdo起头,表明这是cdo语法,接一个Options表明一些参数选项(可选,无特殊需求可省略),接Operator 表明操作的行为(命令+数据文件)。</p>
<p>以下一些Options是针对所有Operator可用的(更多请见<a href="/image/cdo.rar">原文档</a>):</p>
<ol>
<li>-a 生成一个绝对时间坐标 (适用于数据时间信息丢失时)</li>
<li>-b <nbits> 指定数据格式,<nbits>可选:I8/I16/I32/F32/F64</li>
<li>-f <format> 设置输出文件格式(一般默认.nc结尾即可,所以该选项一般可忽略)</li>
</ol>
<p>第二条可能最常用一些,比如报错信息包含数据精度问题时,指定 -b F64 即可。</p>
<h2 id="三、多文件操作"><a href="#三、多文件操作" class="headerlink" title="三、多文件操作"></a>三、多文件操作</h2><h3 id="3-1-连锁命令"><a href="#3-1-连锁命令" class="headerlink" title="3.1 连锁命令"></a>3.1 连锁命令</h3><p>连锁命令指的是用一条指令,对一个文件进行一系列处理,比如对一个文件,用一条命令实现提取冬半年数据,删除闰年2.29日,提取500hPa数据,提取北半球数据这四个操作。这就要求Operator1的输出文件可以作为Operator2的输入文件,形成一个链条。</p>
<p>个人还是不建议新手使用这种方式,容易出问题。</p>
<p>比如从u.nc和v.nc中提取500hPa数据,并拼接为一个文件时,完整的操作:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">cdo sellevel,500 u.nc u500.nc</span><br><span class="line">cdo sellevel,500 v.nc v500.nc</span><br><span class="line">cdo merge u500.nc v500.nc 500.nc</span><br></pre></td></tr></table></figure>
<p>利用连锁命令为:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">cdo merge -sellevel,500 u.nc -sellevel,500 v.nc 500.nc</span><br></pre></td></tr></table></figure>
<h3 id="3-2-多文件操作"><a href="#3-2-多文件操作" class="headerlink" title="3.2 多文件操作"></a>3.2 多文件操作</h3><p>多文件操作指的是,比如说每年都有一个文件,想要将这些文件合成或者其他操作,通过*来代替字符。</p>
<p>比如,文件为1979.nc,1980.nc,1981.nc…2017.nc,将这些文件按时间合成,有两种办法</p>
<p>一种是:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">cdo mergetime 1979.nc 1980.nc 1981.nc ..... 2017.nc 1979-2017.nc</span><br></pre></td></tr></table></figure>
<p>…部分是需要完整填写的。</p>
<p>这样就很麻烦,可以用*代替:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">cdo mergetime *.nc 1979-2017.nc</span><br></pre></td></tr></table></figure>
<p>前提是该文件夹下仅有这些以.nc结尾的文件。</p>
<h2 id="四、常用命令"><a href="#四、常用命令" class="headerlink" title="四、常用命令"></a>四、常用命令</h2><h3 id="4-1-对文件操作"><a href="#4-1-对文件操作" class="headerlink" title="4.1 对文件操作"></a>4.1 对文件操作</h3><table>
<thead>
<tr>
<th align="center">命令(Operator)</th>
<th align="center">作用</th>
<th align="center">用法</th>
</tr>
</thead>
<tbody><tr>
<td align="center">cat</td>
<td align="center">链接数据集</td>
<td align="center">cdo cat infile1 infile2 infile3 outfile</td>
</tr>
<tr>
<td align="center">mergegrid</td>
<td align="center">合并从infile2到infile1的所有变量的网格点,并将结果写入outfile。<br/>infile2的水平网格应该更小或等于infile1的网格,且分辨率必须相同。<br/>只有直线网格是支持。<br/>两个输入文件需要具有相同的变量和相同的时间步长。</td>
<td align="center">cdo mergegrid infile1 infile2 outfile</td>
</tr>
<tr>
<td align="center">merge</td>
<td align="center">合并数据集</td>
<td align="center">cdo merge infile1 infile2 infile3 outfile</td>
</tr>
<tr>
<td align="center">mergetime</td>
<td align="center">按时间合并数据集</td>
<td align="center">cdo mergetime infile1 infile2 infile3</td>
</tr>
<tr>
<td align="center">splitname</td>
<td align="center">按变量名切片数据集</td>
<td align="center">cdo <operator> infiles outfile</td>
</tr>
<tr>
<td align="center">splitlevel</td>
<td align="center">按高度层数切片数据集</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">splithour</td>
<td align="center">按小时时间数切片数据集</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">splitday</td>
<td align="center">按日期天切片数据集</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">splitseas</td>
<td align="center">按季节切片数据集</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">splityear</td>
<td align="center">按年切片数据集</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">splityearmon</td>
<td align="center">按年和月切片数据集</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">splitmon</td>
<td align="center">按月切片数据集</td>
<td align="center"></td>
</tr>
</tbody></table>
<h3 id="4-2-对文件选取"><a href="#4-2-对文件选取" class="headerlink" title="4.2 对文件选取"></a>4.2 对文件选取</h3><table>
<thead>
<tr>
<th align="center">命令(Operator)</th>
<th align="center">作用</th>
<th align="center">用法</th>
</tr>
</thead>
<tbody><tr>
<td align="center">select</td>
<td align="center">选择</td>
<td align="center">cdo <operator>,parameter infiles outfile</td>
</tr>
<tr>
<td align="center">delete</td>
<td align="center">删除</td>
<td align="center">cdo <operator>,parameter infiles outfile</td>
</tr>
<tr>
<td align="center">selparam</td>
<td align="center">选择变量</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">delparam</td>
<td align="center">删除变量</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">selname</td>
<td align="center">按变量名选择变量</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">delname</td>
<td align="center">按变量名删除变量</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">sellevel</td>
<td align="center">选择指定层数</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">sellevidx</td>
<td align="center">按索引标号选择层数</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">selgrid</td>
<td align="center">选择格点</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">seltimestep</td>
<td align="center">选择时间步长</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">seltime</td>
<td align="center">选择时间</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">selhour</td>
<td align="center">选择小时</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">selday</td>
<td align="center">选择天</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">selmonth</td>
<td align="center">选择月</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">selyear</td>
<td align="center">选择年</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">selseason</td>
<td align="center">选择季节</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">seldate</td>
<td align="center">选择日期</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">sellonlatbox</td>
<td align="center">选择经纬度范围</td>
<td align="center">sellonlatbox,西,东,南,北 infile outfile</td>
</tr>
</tbody></table>
<p>这些的用法均是<operator>,parameter </p>
<p>parameter有以下选择:</p>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>格式</th>
<th>填写规则</th>
</tr>
</thead>
<tbody><tr>
<td>name</td>
<td>string</td>
<td>逗号分隔的变量名列表</td>
</tr>
<tr>
<td>level</td>
<td>float</td>
<td>逗号分隔的高度列表</td>
</tr>
<tr>
<td>date</td>
<td>string</td>
<td>逗号分隔的日期列表,格式YYYY-MM-DDThh:mm:ss</td>
</tr>
<tr>
<td>startdate</td>
<td>string</td>
<td>起始日期,格式YYYY-MM-DDThh:mm:ss</td>
</tr>
<tr>
<td>enddate</td>
<td>string</td>
<td>结束日期,格式YYYY-MM-DDThh:mm:ss</td>
</tr>
<tr>
<td>hour</td>
<td>integer</td>
<td>逗号分隔的小时</td>
</tr>
<tr>
<td>day</td>
<td>integer</td>
<td>逗号分隔的天</td>
</tr>
<tr>
<td>month</td>
<td>integer</td>
<td>逗号分隔的月</td>
</tr>
<tr>
<td>season</td>
<td>srting</td>
<td>逗号分隔的季节(DJFMAMJJASOND的子字符串)</td>
</tr>
<tr>
<td>year</td>
<td>integer</td>
<td>逗号分隔的年</td>
</tr>
<tr>
<td>timestep</td>
<td>integer</td>
<td>逗号分隔的时间步长</td>
</tr>
</tbody></table>
<p>比如,删除一个数据文件中所有的2月29号的数据:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">cdo delete,month=2,day=29 input.nc output.nc</span><br></pre></td></tr></table></figure>
<h3 id="4-3-插值"><a href="#4-3-插值" class="headerlink" title="4.3 插值"></a>4.3 插值</h3><table>
<thead>
<tr>
<th align="center">命令(Operator)</th>
<th align="center">作用</th>
<th align="center">用法</th>
</tr>
</thead>
<tbody><tr>
<td align="center">remapbil</td>
<td align="center">线性插值</td>
<td align="center">cdo remapbil,grid infile outfile</td>
</tr>
</tbody></table>
<p>CDO提供的插值有很多,这里我只简单的介绍一种线性插值,常用于讲粗(细)网格插值到另一种分辨率的细(粗)网格。grid指的是格点的描述名或者描述文件。</p>
<p>比如从1°×1°的数据,插值到2.5°×2.5°的数据。</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">cdo remapbil,r144x73 input.nc output.nc</span><br></pre></td></tr></table></figure>
<p>r144x73指的便是经度144点,纬度73点的标准2.5°×2.5°的网格。</p>
]]></content>
<categories>
<category>Paper</category>
</categories>
<tags>
<tag>Other</tag>
<tag>Data</tag>
</tags>
</entry>
<entry>
<title>堆叠柱状图</title>
<url>/2020/09/03/bar3/</url>
<content><![CDATA[<p>(纵向)堆叠柱状图主要是用于横向对比累计分布。绘制方法如下:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"></span><br><span class="line"><span class="comment">#创建数据,A,B,C,D四个变量,每个变量又有v1,v2,v3三个子分量,std表示样本标准差(这里随机创建的)</span></span><br><span class="line">labels = [<span class="string">'A'</span>, <span class="string">'B'</span>, <span class="string">'C'</span>, <span class="string">'D'</span>]</span><br><span class="line">v1 = np.array([<span class="number">20</span>, <span class="number">35</span>, <span class="number">30</span>, <span class="number">35</span>])</span><br><span class="line">v2 = np.array([<span class="number">25</span>, <span class="number">32</span>, <span class="number">34</span>, <span class="number">20</span>])</span><br><span class="line">v3 = np.array([<span class="number">11</span>, <span class="number">14</span>, <span class="number">20</span>, <span class="number">18</span>])</span><br><span class="line">v1_std = np.array([<span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">1</span>])</span><br><span class="line">v2_std = np.array([<span class="number">3</span>, <span class="number">5</span>, <span class="number">2</span>, <span class="number">3</span>])</span><br><span class="line">v3_std = np.array([<span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">1</span>])</span><br><span class="line"><span class="comment">#bar宽度</span></span><br><span class="line">width = <span class="number">0.35</span></span><br><span class="line"><span class="comment">#注意bottom的设置</span></span><br><span class="line">fig = plt.figure(figsize=(<span class="number">10</span>, <span class="number">8</span>))</span><br><span class="line">ax1 = fig.add_subplot(<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>)</span><br><span class="line">ax1.bar(labels, v1, width, yerr=v1_std, label=<span class="string">'v1'</span>)</span><br><span class="line">ax1.bar(labels, v2, width, yerr=v2_std, bottom=v1,label=<span class="string">'v2'</span>)</span><br><span class="line">ax1.bar(labels, v3, width, yerr=v3_std, bottom=v2+v1,label=<span class="string">'v3'</span>)</span><br><span class="line">ax1.legend()</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure>
<p>输出图形如下:</p>
<p><img src="/image/zhexian3-1.png" alt="image-20200702161610554"></p>
]]></content>
<categories>
<category>Plot</category>
</categories>
</entry>
<entry>
<title>Use CDO in Python</title>
<url>/2020/05/23/cdopython/</url>
<content><![CDATA[<p>在Python中调用CDO批量处理文件(非cdo-python库)。</p>
<p>实际上可以利用CDO的chain方式连锁处理,代码会更简洁。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="comment">#批量文件路径</span></span><br><span class="line">filePath = <span class="string">'/CMIP6/hist/ta/CESM2/r1i1p1f1/'</span></span><br><span class="line"><span class="comment">#获取文件名</span></span><br><span class="line">filename = os.listdir(filePath)</span><br><span class="line"><span class="comment">#将全部文件进行筛选,进保留文件名以ta开头的文件</span></span><br><span class="line">filename = list(filter(<span class="keyword">lambda</span> x:x.startswith(<span class="string">'ta'</span>), filename))</span><br><span class="line"><span class="comment">#对文件循环,注意每条语句的输入和输出,根据需要修改和开启/关闭指令</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(len(filename)):</span><br><span class="line"><span class="comment"># os.system('cdo sellevel,50000 {}{} {}tmp1.nc'.format(filePath,filename[i],filePath))</span></span><br><span class="line"> os.system(<span class="string">'cdo remapbil,r144x73 {}{} {}no{}.nc'</span>.format(filePath,filename[i],filePath,i))</span><br><span class="line"><span class="comment"># os.system('cdo sellonlatbox,-180,180,0,90 {}tmp2.nc {}no{}.nc'.format(filePath,filePath,i)) </span></span><br><span class="line"><span class="comment"># os.system('cdo delete,month=2,day=29 {}tmp3.nc {}no{}.nc'.format(filePath,filePath,i)) </span></span><br><span class="line"><span class="comment">#删掉中间文件</span></span><br><span class="line"> os.system(<span class="string">'rm -f {}tmp*'</span>.format(filePath)) </span><br><span class="line"><span class="comment">#合并</span></span><br><span class="line">os.system(<span class="string">'cdo -b 32 mergetime {}no* {}ta.nc'</span>.format(filePath,filePath)) </span><br><span class="line"><span class="comment">#删掉中间文件</span></span><br><span class="line">os.system(<span class="string">'rm -f {}no*'</span>.format(filePath))</span><br></pre></td></tr></table></figure>
<p>可使用的CDO指令可以参考:</p>
<div class="row">
<embed src="/image/cdo_refcard.pdf" width="100%" height="550" type="application/pdf">
</div>
]]></content>
<categories>
<category>Other</category>
</categories>
<tags>
<tag>Python</tag>
<tag>Plot</tag>
</tags>
</entry>
<entry>
<title>CMA热带气旋最佳路径数据集读取与绘制</title>
<url>/2020/09/18/cma-tc-best-path/</url>
<content><![CDATA[<p>以前在简书分享过一个路径绘制的方法,然而对于更多情况的路径绘制来说(比如台风路径),每次的路径长度都是不一致的,同时也需要从一个数据文件里很复杂的读取。这次分享一个可以方便读取CMA热带气旋最佳路径数据集的方法。</p>
<a id="more"></a>
<p>首先展示该数据集的结构:</p>
<p><img src="/image/cmatcpath1.png" alt="image-20200702161610554"></p>
<p>不难发现每次tc的路径长度均是不一致的。那么我们要做的就是,给出一个tc的id,读取该tc的路径信息。以下自定义函数便可实现该功能。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> pathlib <span class="keyword">import</span> Path</span><br><span class="line"><span class="keyword">from</span> typing <span class="keyword">import</span> List</span><br><span class="line"><span class="keyword">from</span> typing <span class="keyword">import</span> Union</span><br><span class="line"><span class="keyword">from</span> typing <span class="keyword">import</span> Tuple</span><br><span class="line"><span class="keyword">from</span> matplotlib.collections <span class="keyword">import</span> LineCollection</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="keyword">import</span> cartopy.crs <span class="keyword">as</span> ccrs</span><br><span class="line"><span class="keyword">import</span> cartopy.feature <span class="keyword">as</span> cfeature</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">reader</span><span class="params">(</span></span></span><br><span class="line"><span class="function"><span class="params"> typhoon_txt: os.PathLike, code: Union[str, int]</span></span></span><br><span class="line"><span class="function"><span class="params">)</span> -> Tuple[List[str], pd.DataFrame]:</span></span><br><span class="line"> typhoon_txt = Path(typhoon_txt)</span><br><span class="line"> <span class="keyword">if</span> isinstance(code, int):</span><br><span class="line"> code = <span class="string">"{:04}"</span>.format(code)</span><br><span class="line"> <span class="keyword">with</span> open(typhoon_txt, <span class="string">"r"</span>) <span class="keyword">as</span> txt_handle:</span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> header = txt_handle.readline().split()</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> header:</span><br><span class="line"> <span class="keyword">raise</span> ValueError(<span class="string">f"没有在文件里找到编号为<span class="subst">{code}</span>的台风"</span>)</span><br><span class="line"> <span class="keyword">if</span> header[<span class="number">4</span>].strip() == code:</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> [txt_handle.readline() <span class="keyword">for</span> _ <span class="keyword">in</span> range(int(header[<span class="number">2</span>]))]</span><br><span class="line"> data_path = pd.read_table(</span><br><span class="line"> txt_handle,</span><br><span class="line"> sep=<span class="string">r"\s+"</span>,</span><br><span class="line"> header=<span class="literal">None</span>,</span><br><span class="line"> names=[<span class="string">"TIME"</span>, <span class="string">"I"</span>, <span class="string">"LAT"</span>, <span class="string">"LONG"</span>, <span class="string">"PRES"</span>, <span class="string">"WND"</span>, <span class="string">"OWD"</span>],</span><br><span class="line"> nrows=int(header[<span class="number">2</span>]),</span><br><span class="line"> dtype={</span><br><span class="line"> <span class="string">"I"</span>: np.int,</span><br><span class="line"> <span class="string">"LAT"</span>: np.float32,</span><br><span class="line"> <span class="string">"LONG"</span>: np.float32,</span><br><span class="line"> <span class="string">"PRES"</span>: np.float32,</span><br><span class="line"> <span class="string">"WND"</span>: np.float32,</span><br><span class="line"> <span class="string">"OWD"</span>: np.float32,</span><br><span class="line"> },</span><br><span class="line"> parse_dates=<span class="literal">True</span>,</span><br><span class="line"> date_parser=<span class="keyword">lambda</span> x: pd.to_datetime(x, format=<span class="string">f"%Y%m%d%H"</span>),</span><br><span class="line"> index_col=<span class="string">"TIME"</span>,</span><br><span class="line"> )</span><br><span class="line"> data_path[<span class="string">"LAT"</span>] = data_path[<span class="string">"LAT"</span>] / <span class="number">10</span></span><br><span class="line"> data_path[<span class="string">"LONG"</span>] = data_path[<span class="string">"LONG"</span>] / <span class="number">10</span></span><br><span class="line"> <span class="keyword">return</span> header, data_path</span><br></pre></td></tr></table></figure>
<p>比如说,我们读取2006年的08号tc的相关信息:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">head, dat = reader(<span class="string">r"./CH2006BST.txt"</span>,<span class="string">'0608'</span>)</span><br><span class="line">lat = dat.LAT</span><br><span class="line">lon = dat.LONG</span><br><span class="line">level = dat.I</span><br><span class="line">pressure = dat.PRES</span><br></pre></td></tr></table></figure>
<p>绘图:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment">#创建Figure</span></span><br><span class="line">fig = plt.figure(figsize=(<span class="number">15</span>, <span class="number">12</span>))</span><br><span class="line"><span class="comment">#绘制台风路径</span></span><br><span class="line">ax1 = fig.add_subplot(<span class="number">1</span>,<span class="number">2</span>,<span class="number">1</span>, projection=ccrs.PlateCarree())</span><br><span class="line"><span class="comment">#设置ax1的范围</span></span><br><span class="line">ax1.set_extent([<span class="number">100</span>,<span class="number">160</span>,<span class="number">-10</span>,<span class="number">40</span>])</span><br><span class="line"><span class="comment">#为ax1添加海岸线和陆地</span></span><br><span class="line">ax1.coastlines()</span><br><span class="line">ax1.add_feature(cfeature.LAND) <span class="comment">#添加大陆特征</span></span><br><span class="line"><span class="comment">#为ax1添加地理经纬度标签及刻度</span></span><br><span class="line">ax1.set_xticks(np.arange(<span class="number">100</span>,<span class="number">170</span>,<span class="number">10</span>), crs=ccrs.PlateCarree())</span><br><span class="line">ax1.set_yticks(np.arange(<span class="number">-10</span>,<span class="number">50</span>,<span class="number">10</span>), crs=ccrs.PlateCarree())</span><br><span class="line">ax1.xaxis.set_major_formatter(cticker.LongitudeFormatter())</span><br><span class="line">ax1.yaxis.set_major_formatter(cticker.LatitudeFormatter())</span><br><span class="line"><span class="comment">#将绘制台风路径,并将逐六小时坐标点及其对应的台风强度标记</span></span><br><span class="line">ax1.plot(lon,lat,linewidth=<span class="number">2</span>)</span><br><span class="line">s1 = ax1.scatter(lon,lat,c=pressure,s=(level+<span class="number">1</span>)*<span class="number">13</span>,cmap=<span class="string">'Reds_r'</span>,vmax=<span class="number">1050</span>,vmin=<span class="number">900</span>,alpha=<span class="number">1</span>)</span><br><span class="line">fig.colorbar(s1,ax=ax1,fraction=<span class="number">0.04</span>)</span><br><span class="line"><span class="comment">#绘制台风路径</span></span><br><span class="line">ax2 = fig.add_subplot(<span class="number">1</span>,<span class="number">2</span>,<span class="number">2</span>, projection=ccrs.PlateCarree())</span><br><span class="line"><span class="comment">#设置ax2的范围</span></span><br><span class="line">ax2.set_extent([<span class="number">100</span>,<span class="number">160</span>,<span class="number">-10</span>,<span class="number">40</span>])</span><br><span class="line"><span class="comment">#为ax1添加海岸线</span></span><br><span class="line">ax2.coastlines()</span><br><span class="line">ax2.add_feature(cfeature.LAND) <span class="comment">#添加大陆特征</span></span><br><span class="line"><span class="comment">#为ax2添加地理经纬度标签及刻度</span></span><br><span class="line">ax2.set_xticks(np.arange(<span class="number">100</span>,<span class="number">170</span>,<span class="number">10</span>), crs=ccrs.PlateCarree())</span><br><span class="line">ax2.set_yticks(np.arange(<span class="number">-10</span>,<span class="number">50</span>,<span class="number">10</span>), crs=ccrs.PlateCarree())</span><br><span class="line">ax2.xaxis.set_major_formatter(cticker.LongitudeFormatter())</span><br><span class="line">ax2.yaxis.set_major_formatter(cticker.LatitudeFormatter())</span><br><span class="line"><span class="comment">#将经纬度数据点存入同一数组</span></span><br><span class="line">points = np.array([lon, lat]).T.reshape(<span class="number">-1</span>, <span class="number">1</span>, <span class="number">2</span>)</span><br><span class="line">segments = np.concatenate([points[:<span class="number">-1</span>], points[<span class="number">1</span>:]], axis=<span class="number">1</span>)</span><br><span class="line"><span class="comment">#设置色标的标准化范围(即将Z维度的数据对应为颜色数组)</span></span><br><span class="line">norm = plt.Normalize(<span class="number">0</span>, <span class="number">80</span>)</span><br><span class="line"><span class="comment">#设置颜色线条</span></span><br><span class="line">lc = LineCollection(segments, cmap=<span class="string">'jet'</span>, norm=norm,transform=ccrs.PlateCarree()) </span><br><span class="line">lc.set_array(dat.WND[:<span class="number">-1</span>])</span><br><span class="line"><span class="comment">#绘制线条</span></span><br><span class="line">line = ax2.add_collection(lc) </span><br><span class="line">fig.colorbar(lc,ax=ax2,fraction=<span class="number">0.04</span>)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure>
<p>输出图形:</p>
<p><img src="/image/cmatcpath2.png" alt="image-20200702161610554"></p>
<p>对于左图来说,点大小对应台风等级,点颜色对应台风中心气压,对于有图来说,颜色对应风速大小。</p>
<p>测试文件下载:<a href="/image/CH2006BST.txt">点此下载</a></p>
]]></content>
<categories>
<category>Paper</category>
</categories>
<tags>
<tag>data</tag>
</tags>
</entry>
<entry>
<title>Python绘图如何自定义或使用NCL中的colormap</title>
<url>/2020/06/06/color/</url>
<content><![CDATA[<p>相比于NCL,Matplotlib提供的colormap不够丰富,本文介绍Matplotlib的自带色板,并介绍Python绘图如何使用NCL中的colormap,甚至自定义色板(比如使用气象家园调色盘生成的色板)。</p>
<a id="more"></a>
<h3 id="一、Matplotlib-自带colormap"><a href="#一、Matplotlib-自带colormap" class="headerlink" title="一、Matplotlib 自带colormap"></a>一、Matplotlib 自带colormap</h3><p>在绘制等高线图也就是contourf时,需要设置合适的colormap(cmap)。下面给出Matplotlib自带的colormap。</p>
<p>(需要说明的是,在字串末尾添加“_r”,可以反转色标,比如bwr -> bwr_r)</p>
<p>[‘viridis’, ‘plasma’, ‘inferno’, ‘magma’, ‘cividis’]</p>
<img src="/image/sphx_glr_colormap_reference_001.png"/>
<p>[‘Greys’, ‘Purples’, ‘Blues’, ‘Greens’, ‘Oranges’, ‘Reds’, ‘YlOrBr’, ‘YlOrRd’, ‘OrRd’, ‘PuRd’, ‘RdPu’, ‘BuPu’, ‘GnBu’, ‘PuBu’, ‘YlGnBu’, ‘PuBuGn’, ‘BuGn’, ‘YlGn’]</p>
<img src="/image/sphx_glr_colormap_reference_002.png"/>
<p>[‘binary’, ‘gist_yarg’, ‘gist_gray’, ‘gray’, ‘bone’, ‘pink’,<br> ‘spring’, ‘summer’, ‘autumn’, ‘winter’, ‘cool’, ‘Wistia’,<br> ‘hot’, ‘afmhot’, ‘gist_heat’, ‘copper’]</p>
<img src="/image/sphx_glr_colormap_reference_003.png"/>
<p>[‘PiYG’, ‘PRGn’, ‘BrBG’, ‘PuOr’, ‘RdGy’, ‘RdBu’,’RdYlBu’, ‘RdYlGn’, ‘Spectral’, ‘coolwarm’, ‘bwr’, ‘seismic’]</p>
<img src="/image/sphx_glr_colormap_reference_004.png"/>
<p>[‘twilight’, ‘twilight_shifted’, ‘hsv’]</p>
<img src="/image/sphx_glr_colormap_reference_005.png"/>
<p>[‘Pastel1’, ‘Pastel2’, ‘Paired’, ‘Accent’,’Dark2’, ‘Set1’, ‘Set2’, ‘Set3’,’tab10’, ‘tab20’, ‘tab20b’, ‘tab20c’]</p>
<img src="/image/sphx_glr_colormap_reference_006.png"/>
<p>[‘flag’, ‘prism’, ‘ocean’, ‘gist_earth’, ‘terrain’, ‘gist_stern’,’gnuplot’, ‘gnuplot2’, ‘CMRmap’, ‘cubehelix’, ‘brg’,’gist_rainbow’, ‘rainbow’, ‘jet’, ‘nipy_spectral’, ‘gist_ncar’]</p>
<img src="/image/sphx_glr_colormap_reference_007.png"/>
<h3 id="二、-颜色对应名称"><a href="#二、-颜色对应名称" class="headerlink" title="二、 颜色对应名称"></a>二、 颜色对应名称</h3><p>在绘制折线图,散点图等时,需要指定某些线的颜色,这就需要知道颜色对应的名称,这里给出列表:</p>
<img src="/image/sphx_glr_named_colors_001.png"/>
<img src="/image/sphx_glr_named_colors_002.png"/>
<img src="/image/sphx_glr_named_colors_003.png"/>
<h3 id="三、-使用NCL色板-使用调色盘文件思路相同"><a href="#三、-使用NCL色板-使用调色盘文件思路相同" class="headerlink" title="三、 使用NCL色板(使用调色盘文件思路相同)"></a>三、 使用NCL色板(使用调色盘文件思路相同)</h3><p>NCL的色板十分丰富,几乎可以涵盖平常所需。详见:<a href="http://www.ncl.ucar.edu/Document/Graphics/color_table_gallery.shtml" target="_blank" rel="noopener">传送门</a></p>
<p>那么我们能否将NCL的色板用在python中呢?答案当然是可以的。</p>
<p>我在气象家园发现了个帖子,楼主自己封装了一个包,可以在python中调用NCL的色板,详见:<a href="http://bbs.06climate.com/forum.php?mod=viewthread&tid=43521" target="_blank" rel="noopener">传送门</a></p>
<p>其基本原理就是读取NCL色板的.rgb文件,将其信息转换为颜色数组,形成matplotlib色板。那么下面,我就根据这个思路,解释下其过程和原理。首先我将NCL已有色板.rgb文件整理上传了,下载<a href="/image/colormaps.rar">点这里</a>,下载后将压缩包内文件夹解压。</p>
<p>.rgb文件内容如下(以3gauss.rgb为例):</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">ncolors = 254</span><br><span class="line"># r g b</span><br><span class="line">0 0 255</span><br><span class="line">0 0 255</span><br><span class="line">1 2 254</span><br><span class="line">2 4 253</span><br><span class="line">3 6 252</span><br><span class="line">...</span><br><span class="line">...</span><br><span class="line">...</span><br></pre></td></tr></table></figure>
<p>ncolors = 254,代表该色板有254个色号,第二行为注释内容,表明接下来的每一行,颜色存放都是red,green,blue的顺序。那么接下来我们只需要读取这个文件,将颜色存为一个[254,3]的数组,然后将数组除255即可。除255的原因是,python的颜色值位于[0,1]之间,而rgb信息位于[0,255]之间,所以除255就可以将颜色信息映射在[0,1]之间。</p>
<p>但是!有一个问题,我查看了NCL的一些色板,这些色板的格式并不统一,有些是直接映射在[0,1]之间了,有些文件头有很多行,总之很杂乱,用之前还是需要统一格式,做好质量控制的。(我后边有时间的话考虑将这些文件统一格式再重新上传。)</p>
<p>下面给出一个使用NCL色板的示例:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> matplotlib.colors <span class="keyword">import</span> ListedColormap</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="comment">#读取.rgb文件</span></span><br><span class="line">rgb = pd.read_csv(<span class="string">'./colormaps/3gauss.rgb'</span>,sep=<span class="string">'\s+'</span>,skiprows=<span class="number">2</span>,names=[<span class="string">'r'</span>,<span class="string">'g'</span>,<span class="string">'b'</span>]).values/<span class="number">255</span></span><br><span class="line"><span class="comment">#将rgb信息映射为colormap</span></span><br><span class="line">colormap = ListedColormap(rgb)</span><br><span class="line"><span class="comment">#创建100个随机数</span></span><br><span class="line">colors = np.random.randint(<span class="number">0</span>,<span class="number">100</span>,size=<span class="number">100</span>)</span><br><span class="line">x,y = np.random.rand(<span class="number">100</span>),np.random.rand(<span class="number">100</span>)</span><br><span class="line"><span class="comment">#绘制散点图,使用NCL中的3gauss色板</span></span><br><span class="line">sct = plt.scatter(x, y, s=<span class="number">100</span>, c=colors,cmap=colormap,edgecolors=<span class="string">'black'</span>)</span><br><span class="line">plt.colorbar(sct)</span><br></pre></td></tr></table></figure>