forked from yxy-biubiubiu/yxy-biubiubiu.github.io
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
1223 lines (583 loc) · 510 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>经度坐标180°与360°的转换</title>
<link href="/2023/03/24/%E7%BB%8F%E5%BA%A6%E5%9D%90%E6%A0%87%E8%BD%AC%E6%8D%A2/"/>
<url>/2023/03/24/%E7%BB%8F%E5%BA%A6%E5%9D%90%E6%A0%87%E8%BD%AC%E6%8D%A2/</url>
<content type="html"><![CDATA[<p>经度坐标系从-180°<del>180°转为0°</del>360°。</p><a id="more"></a><p>假使数据默认经度坐标系为-180°~180°</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><xarray.Dataset></span><br><span class="line">Dimensions: (lat: <span class="number">181</span>, lon: <span class="number">360</span>)</span><br><span class="line">Coordinates:</span><br><span class="line"> * lat (lat) int64 <span class="number">90</span> <span class="number">89</span> <span class="number">88</span> <span class="number">87</span> <span class="number">86</span> <span class="number">85</span> <span class="number">84</span> <span class="number">83</span> ... <span class="number">-84</span> <span class="number">-85</span> <span class="number">-86</span> <span class="number">-87</span> <span class="number">-88</span> <span class="number">-89</span> <span class="number">-90</span></span><br><span class="line"> * lon (lon) int64 <span class="number">-180</span> <span class="number">-179</span> <span class="number">-178</span> <span class="number">-177</span> <span class="number">-176</span> <span class="number">-175</span> ... <span class="number">175</span> <span class="number">176</span> <span class="number">177</span> <span class="number">178</span> <span class="number">179</span></span><br><span class="line">Data variables:</span><br><span class="line"> pop (lat, lon) float64 ...</span><br></pre></td></tr></table></figure><p>对其进行坐标系变换:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">f = xr.open_dataset(<span class="string">"/mnt/f/population/pop_1x1_2000.nc"</span>)</span><br><span class="line">f.coords[<span class="string">'lon'</span>] = np.mod(f[<span class="string">'lon'</span>], <span class="number">360</span>)</span><br><span class="line">f = f.reindex({ <span class="string">'lon'</span> : np.sort(f[<span class="string">'lon'</span>])})</span><br><span class="line">print(f)</span><br></pre></td></tr></table></figure><p>输出结果为:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><xarray.Dataset></span><br><span class="line">Dimensions: (lat: 181, lon: 360)</span><br><span class="line">Coordinates:</span><br><span class="line"> * lon (lon) int64 0 1 2 3 4 5 6 7 8 ... 352 353 354 355 356 357 358 359</span><br><span class="line"> * lat (lat) int64 90 89 88 87 86 85 84 83 ... -84 -85 -86 -87 -88 -89 -90</span><br><span class="line">Data variables:</span><br><span class="line"> pop (lat, lon) float64 ...</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> Paper </category>
</categories>
<tags>
<tag> Python </tag>
<tag> Matplotlib </tag>
</tags>
</entry>
<entry>
<title>处理闰年2月29号的两种方法</title>
<link href="/2023/03/15/%E5%A4%84%E7%90%86%E9%97%B0%E5%B9%B42%E6%9C%8829%E5%8F%B7%E7%9A%84%E4%B8%A4%E7%A7%8D%E6%96%B9%E6%B3%95/"/>
<url>/2023/03/15/%E5%A4%84%E7%90%86%E9%97%B0%E5%B9%B42%E6%9C%8829%E5%8F%B7%E7%9A%84%E4%B8%A4%E7%A7%8D%E6%96%B9%E6%B3%95/</url>
<content type="html"><![CDATA[<p>关于处理闰年2月29号数据的两种方法。</p><a id="more"></a><p>这里以一个2008年的SLP数据为例(2008年为闰年,有2月29号,共366天)。</p><p>首先读取数据:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><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="comment">#############读入数据########</span></span><br><span class="line">f_in = xr.open_dataset(<span class="string">'./slp.2008.nc'</span>)</span><br><span class="line">print(f_in,<span class="string">'\n'</span>)</span><br></pre></td></tr></table></figure><p>输出结果是这样的:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><xarray.Dataset></span><br><span class="line">Dimensions: (lat: 73, lon: 144, time: 366)</span><br><span class="line">Coordinates:</span><br><span class="line"> * lat (lat) float32 90.0 87.5 85.0 82.5 80.0 ... -82.5 -85.0 -87.5 -90.0</span><br><span class="line"> * lon (lon) float32 0.0 2.5 5.0 7.5 10.0 ... 350.0 352.5 355.0 357.5</span><br><span class="line"> * time (time) datetime64[ns] 2008-01-01 2008-01-02 ... 2008-12-31</span><br><span class="line">Data variables:</span><br><span class="line"> slp (time, lat, lon) float32 ...</span><br><span class="line">Attributes:</span><br><span class="line"> Conventions: COARDS</span><br><span class="line"> title: mean daily NMC reanalysis (2008)</span><br><span class="line"> description: Data is from NMC initialized reanalysis\n(4x/day). It co...</span><br><span class="line"> platform: Model</span><br><span class="line"> history: created 2007/12 by Hoop (netCDF2.3)\nConverted to chunked...</span><br><span class="line"> dataset_title: NCEP-NCAR Reanalysis 1</span><br><span class="line"> References: http://www.psl.noaa.gov/data/gridded/data.ncep.reanalysis...</span><br></pre></td></tr></table></figure><p>我们想删去其中的2月29日,这里提供两种方法。</p><p><strong>第一种</strong>暴力一点,直接利用CDO把数据文件中的2.29这一天删去(一旦删去不可恢复,注意备份文件)。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">!cdo delete,month=<span class="number">2</span>,day=<span class="number">29</span> <span class="string">'./slp.2008.nc'</span> <span class="string">'./out1.nc'</span></span><br><span class="line">f_out1 = xr.open_dataset(<span class="string">'./out1.nc'</span>)</span><br><span class="line">print(f_out1,<span class="string">'\n'</span>)</span><br></pre></td></tr></table></figure><p>这三行代码可以直接在jupyter notebook的脚本中运行,!为调用外部指令的意思,也可使用os.system()方法调用。还可以去掉“!”符号,直接用cdo指令在shell中使用。输出结果为:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><xarray.Dataset></span><br><span class="line">Dimensions: (lat: 73, lon: 144, time: 365)</span><br><span class="line">Coordinates:</span><br><span class="line"> * time (time) datetime64[ns] 2008-01-01 2008-01-02 ... 2008-12-31</span><br><span class="line"> * lon (lon) float32 0.0 2.5 5.0 7.5 10.0 ... 350.0 352.5 355.0 357.5</span><br><span class="line"> * lat (lat) float32 90.0 87.5 85.0 82.5 80.0 ... -82.5 -85.0 -87.5 -90.0</span><br><span class="line">Data variables:</span><br><span class="line"> slp (time, lat, lon) float32 ...</span><br><span class="line">Attributes:</span><br><span class="line"> CDI: Climate Data Interface version 2.1.1 (https://mpimet.mpg....</span><br><span class="line"> Conventions: COARDS</span><br><span class="line"> title: mean daily NMC reanalysis (2008)</span><br><span class="line"> description: Data is from NMC initialized reanalysis\n(4x/day). It co...</span><br><span class="line"> platform: Model</span><br><span class="line"> history: Wed Mar 15 16:03:16 2023: cdo delete,month=2,day=29 ./slp...</span><br><span class="line"> dataset_title: NCEP-NCAR Reanalysis 1</span><br><span class="line"> References: http://www.psl.noaa.gov/data/gridded/data.ncep.reanalysis...</span><br><span class="line"> CDO: Climate Data Operators version 2.1.1 (https://mpimet.mpg....</span><br></pre></td></tr></table></figure><p><strong>第二种</strong>则是利用xarray的索引来避免选择2月29这一天,对原文件不进行操作:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">slp = f_in.slp.loc[~((f_in.time.dt.month==<span class="number">2</span>)&(f_in.time.dt.day==<span class="number">29</span>))]</span><br><span class="line">print(slp)</span><br></pre></td></tr></table></figure><p>~在python中为取反的含义,因此索引中的内容实际为,选择月为2且日为29的反集。输出结果为:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><xarray.DataArray 'slp' (time: 365, lat: 73, lon: 144)></span><br><span class="line">[3836880 values with dtype=float32]</span><br><span class="line">Coordinates:</span><br><span class="line"> * lat (lat) float32 90.0 87.5 85.0 82.5 80.0 ... -82.5 -85.0 -87.5 -90.0</span><br><span class="line"> * lon (lon) float32 0.0 2.5 5.0 7.5 10.0 ... 350.0 352.5 355.0 357.5</span><br><span class="line"> * time (time) datetime64[ns] 2008-01-01 2008-01-02 ... 2008-12-31</span><br><span class="line">Attributes:</span><br><span class="line"> long_name: mean Daily Sea Level Pressure</span><br><span class="line"> units: Pascals</span><br><span class="line"> precision: 0</span><br><span class="line"> GRIB_id: 2</span><br><span class="line"> GRIB_name: PRMSL</span><br><span class="line"> var_desc: Sea Level Pressure</span><br><span class="line"> dataset: NCEP Reanalysis Daily Averages</span><br><span class="line"> level_desc: Sea Level</span><br><span class="line"> statistic: Mean</span><br><span class="line"> parent_stat: Individual Obs</span><br><span class="line"> actual_range: [ 93755. 109700.]</span><br><span class="line"> valid_range: [ 87000. 115000.]</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> Paper </category>
</categories>
<tags>
<tag> Python </tag>
<tag> Matplotlib </tag>
</tags>
</entry>
<entry>
<title>修改显著性打点的颜色</title>
<link href="/2022/11/28/contourf2/"/>
<url>/2022/11/28/contourf2/</url>
<content type="html"><![CDATA[<p>以一个序列和一个场的相关系数为例,绘制带显著性检验的填色图。</p><p>通过contourf函数的hatch功能实现的显著性打点的颜色默认为黑色,然后当填色背景色调较深时,黑色的显著性打点会不明显,这里提供一个修改显著性打点颜色的方案:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><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> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="comment"># 随机生成一个二维数据用于绘制图形</span></span><br><span class="line">x = np.linspace(<span class="number">-3</span>, <span class="number">5</span>, <span class="number">150</span>).reshape(<span class="number">1</span>, <span class="number">-1</span>)</span><br><span class="line">y = np.linspace(<span class="number">-3</span>, <span class="number">5</span>, <span class="number">120</span>).reshape(<span class="number">-1</span>, <span class="number">1</span>)</span><br><span class="line">z = np.cos(x) + np.sin(y)</span><br><span class="line">x, y = x.flatten(), y.flatten()</span><br><span class="line"><span class="comment">#x,y,z的形状分别为(150,) (120,) (120, 150)</span></span><br></pre></td></tr></table></figure><p>利用contourf的hatch功能进行图形填充(思路是通过对contourf对象的collections属性进行更加具体的设置,以实现contourf函数中参数不能实现的部分):</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">plt.figure()</span><br><span class="line">n_levels = <span class="number">6</span><span class="comment">#6个水平层级,对应8个填充区间</span></span><br><span class="line">plt.contour(x, y, z, n_levels, colors=<span class="string">'black'</span>, linestyles=<span class="string">'-'</span>)</span><br><span class="line">cs = plt.contourf(</span><br><span class="line"> x, y, z, n_levels, colors=<span class="string">'none'</span>,</span><br><span class="line"> hatches=[<span class="string">'.'</span>, <span class="string">'/'</span>, <span class="string">'\\'</span>, <span class="literal">None</span>, <span class="string">'\\\\'</span>, <span class="string">'*'</span>],</span><br><span class="line"> extend=<span class="string">'lower'</span>,)</span><br><span class="line"><span class="comment">#8个填充区间的填充颜色</span></span><br><span class="line">colors = [<span class="string">'maroon'</span>, <span class="string">'red'</span>, <span class="string">'darkorange'</span>, <span class="string">'gold'</span>, <span class="string">'forestgreen'</span>,</span><br><span class="line"> <span class="string">'darkturquoise'</span>, <span class="string">'dodgerblue'</span>, <span class="string">'darkviolet'</span>]</span><br><span class="line"><span class="comment"># 指定每个区间形状填充的颜色</span></span><br><span class="line"><span class="keyword">for</span> i, collection <span class="keyword">in</span> enumerate(cs.collections):</span><br><span class="line"> collection.set_edgecolor(colors[i % len(colors)])</span><br><span class="line"><span class="comment"># 将边界填充粗细设置为0</span></span><br><span class="line"><span class="keyword">for</span> collection <span class="keyword">in</span> cs.collections:</span><br><span class="line"> collection.set_linewidth(<span class="number">0</span>)</span><br></pre></td></tr></table></figure><p>输出图形如下:</p><p><img src="https://raw.githubusercontent.com/yxy-biubiubiu/Resources/main/images/contourf2.png" alt=""></p>]]></content>
<categories>
<category> Plot </category>
</categories>
</entry>
<entry>
<title>奇异值分解(SVD)</title>
<link href="/2022/11/27/f1-5-1-2/"/>
<url>/2022/11/27/f1-5-1-2/</url>
<content type="html"><![CDATA[<p>本文将直接介绍该库的安装及使用,关于SVD的原理不做介绍。</p><h4 id="一、安装"><a href="#一、安装" class="headerlink" title="一、安装"></a>一、安装</h4><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install xMCA</span><br></pre></td></tr></table></figure><h4 id="二、使用介绍"><a href="#二、使用介绍" class="headerlink" title="二、使用介绍"></a>二、使用介绍</h4><p>首先import</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> xMCA <span class="keyword">import</span> xMCA</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> xarray <span class="keyword">as</span> xr</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><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">contour_map</span><span class="params">(fig,img_extent,spec1,spec2)</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+spec1,spec1), crs=ccrs.PlateCarree())</span><br><span class="line"> fig.set_yticks(np.arange(lowerlat,upperlat+spec2,spec2), 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><p>该库有几个基本函数是必须掌握的,我们一一介绍。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">svd = xMCA(a, b).solver()</span><br><span class="line">lp, rp = svd.patterns(n=<span class="number">2</span>)</span><br><span class="line">le, re = svd.expansionCoefs(n=<span class="number">2</span>)</span><br><span class="line">frac = svd.covFracs(n=<span class="number">2</span>)</span><br></pre></td></tr></table></figure><p>svd = xMCA(a, b).solver()建立一个SVD分解器,a,b为要进行分解的两个变量,</p><p>svd.patterns(n=2),svd.expansionCoefs(n=2),svd.covFracs(n=2)分别取出前两个模态的空间模态,时间系数和方差。lx为左场,rx为右场。</p><h4 id="三、示例"><a href="#三、示例" class="headerlink" title="三、示例"></a>三、示例</h4><p>我们以北大西洋海温和东亚区域夏季降水的分解为例,展示SVD分析完整的Python实现。</p><p>数据为GPCP逐月降水数据和哈德来中心的逐月海温数据。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#读取海温数据(sst格式为时间,纬度,经度)</span></span><br><span class="line">f_sst = xr.open_dataset(<span class="string">'sst.nc'</span>)</span><br><span class="line">sst = f_sst[<span class="string">'sst'</span>].loc[f_sst.time.dt.month.isin([<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>])].loc[<span class="string">'1979-06-01'</span>:<span class="string">'2018-08-31'</span>,<span class="number">60</span>:<span class="number">-30</span>,<span class="number">-100</span>:<span class="number">-0</span>]</span><br><span class="line">sst_lat = sst.coords[<span class="string">'latitude'</span>]</span><br><span class="line">sst_lon = sst.coords[<span class="string">'longitude'</span>]</span><br><span class="line"><span class="comment">#读取降水数据(pre格式为时间,纬度,经度)</span></span><br><span class="line">f_pre = xr.open_dataset(<span class="string">'precip.mon.total.v2020.nc'</span>)</span><br><span class="line">pre = f_pre[<span class="string">'precip'</span>].loc[f_pre.time.dt.month.isin([<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>])].loc[<span class="string">'1979-06-01'</span>:<span class="string">'2018-08-31'</span>,<span class="number">55</span>:<span class="number">20</span>,<span class="number">70</span>:<span class="number">140</span>]</span><br><span class="line">pre_lat = pre.coords[<span class="string">'lat'</span>]</span><br><span class="line">pre_lon = pre.coords[<span class="string">'lon'</span>]</span><br><span class="line"><span class="comment">#数据标准化,添补缺测值,并处理为DataArray格式</span></span><br><span class="line">time = np.arange(<span class="number">1979</span>,<span class="number">2019</span>,<span class="number">1</span>)</span><br><span class="line">sst_summer = np.array(sst).reshape((<span class="number">40</span>,<span class="number">3</span>,sst_lat.shape[<span class="number">0</span>],sst_lon.shape[<span class="number">0</span>])).mean((<span class="number">1</span>))</span><br><span class="line">pre_summer = np.array(pre).reshape((<span class="number">40</span>,<span class="number">3</span>,pre_lat.shape[<span class="number">0</span>],pre_lon.shape[<span class="number">0</span>])).mean((<span class="number">1</span>))</span><br><span class="line">pre_summer[np.isnan(pre_summer)] = <span class="number">0</span></span><br><span class="line">sst_summer = (sst_summer - np.mean(sst_summer,axis = <span class="number">0</span>)) / np.std(sst_summer,axis = <span class="number">0</span>)</span><br><span class="line">pre_summer = (pre_summer - np.mean(pre_summer,axis = <span class="number">0</span>)) / np.std(pre_summer,axis = <span class="number">0</span>)</span><br><span class="line">pre_summer[np.isnan(pre_summer)] = <span class="number">0</span></span><br><span class="line">sst_summer = xr.DataArray(sst_summer, coords=[time,sst_lat,sst_lon], dims=[<span class="string">'time'</span>, <span class="string">'lat'</span>, <span class="string">'lon'</span>])</span><br><span class="line">pre_summer = xr.DataArray(pre_summer, coords=[time,pre_lat,pre_lon], dims=[<span class="string">'time'</span>, <span class="string">'lat'</span>, <span class="string">'lon'</span>])</span><br><span class="line"><span class="comment">#SVD分解</span></span><br><span class="line">svd = xMCA(sst_summer, pre_summer)</span><br><span class="line">svd.solver()</span><br><span class="line">lp, rp = svd.patterns(n=<span class="number">2</span>)</span><br><span class="line">le, re = svd.expansionCoefs(n=<span class="number">2</span>)</span><br><span class="line">frac = svd.covFracs(n=<span class="number">2</span>)</span><br></pre></td></tr></table></figure><p>以下是绘图部分,我们先给出其中不重复的部分,文章最末会给出完整代码:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">fig1 = plt.figure(figsize=(<span class="number">12</span>,<span class="number">8</span>))</span><br><span class="line"></span><br><span class="line">f1_ax1 = fig1.add_axes([<span class="number">0.1</span>, <span class="number">0.6</span>, <span class="number">0.5</span>, <span class="number">0.5</span>],projection = ccrs.PlateCarree(central_longitude=<span class="number">-50</span>))</span><br><span class="line">leftlon, rightlon, lowerlat, upperlat = (<span class="number">-100</span>,<span class="number">0</span>,<span class="number">-30</span>,<span class="number">60</span>)</span><br><span class="line">img_extent = [leftlon, rightlon, lowerlat, upperlat]</span><br><span class="line">contour_map(f1_ax1,img_extent,<span class="number">25</span>,<span class="number">30</span>)</span><br><span class="line">f1_ax1.set_title(<span class="string">'1st pattern of left'</span>,loc=<span class="string">'center'</span>,fontsize=<span class="number">18</span>)</span><br><span class="line">f1_ax1.set_title(<span class="string">'(a)'</span>,loc=<span class="string">'left'</span>,fontsize=<span class="number">18</span>)</span><br><span class="line">c1 = f1_ax1.contourf(sst_lon,sst_lat, lp[<span class="number">0</span>], zorder=<span class="number">0</span>, extend = <span class="string">'both'</span>, levels =np.arange(<span class="number">-1</span>,<span class="number">1.1</span>,<span class="number">0.1</span>),transform=ccrs.PlateCarree(), cmap=plt.cm.RdBu_r)</span><br><span class="line"></span><br><span class="line">f1_ax2 = fig1.add_axes([<span class="number">0.15</span>, <span class="number">0.1</span>, <span class="number">0.4</span>, <span class="number">0.4</span>],projection = ccrs.PlateCarree(central_longitude=<span class="number">105</span>))</span><br><span class="line">leftlon, rightlon, lowerlat, upperlat = (<span class="number">70</span>,<span class="number">140</span>,<span class="number">20</span>,<span class="number">55</span>)</span><br><span class="line">img_extent = [leftlon, rightlon, lowerlat, upperlat]</span><br><span class="line">b = contour_map(f1_ax2,img_extent,<span class="number">35</span>,<span class="number">7</span>)</span><br><span class="line">f1_ax2.set_title(<span class="string">'1st pattern of right'</span>,loc=<span class="string">'center'</span>,fontsize=<span class="number">18</span>)</span><br><span class="line">f1_ax2.set_title(<span class="string">'(c)'</span>,loc=<span class="string">'left'</span>,fontsize=<span class="number">18</span>)</span><br><span class="line">c2 = f1_ax2.contourf(pre_lon,pre_lat, rp[<span class="number">0</span>], zorder=<span class="number">0</span>, extend = <span class="string">'both'</span>, levels =np.arange(<span class="number">-1</span>,<span class="number">1.1</span>,<span class="number">0.1</span>), transform=ccrs.PlateCarree(), cmap=plt.cm.RdBu_r)</span><br><span class="line"></span><br><span class="line">position=fig1.add_axes([<span class="number">0.16</span>, <span class="number">0.085</span>, <span class="number">0.35</span>, <span class="number">0.025</span>])</span><br><span class="line">fig1.colorbar(c2,cax=position,orientation=<span class="string">'horizontal'</span>,format=<span class="string">'%.1f'</span>,)</span><br><span class="line"></span><br><span class="line">f1_ax3 = fig1.add_axes([<span class="number">0.6</span>, <span class="number">0.6</span>, <span class="number">0.4</span>, <span class="number">0.5</span>])</span><br><span class="line">f1_ax3.plot(time,le[<span class="number">0</span>])</span><br><span class="line">f1_ax3.set_title(<span class="string">'(b)'</span>,loc=<span class="string">'left'</span>,fontsize=<span class="number">18</span>)</span><br><span class="line">f1_ax3.set_title(<span class="string">'1st time series of left'</span>,loc=<span class="string">'center'</span>,fontsize=<span class="number">18</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">f1_ax4 = fig1.add_axes([<span class="number">0.6</span>, <span class="number">0.15</span>, <span class="number">0.4</span>, <span class="number">0.3</span>])</span><br><span class="line">f1_ax4.plot(time,re[<span class="number">0</span>])</span><br><span class="line">f1_ax4.set_title(<span class="string">'(d)'</span>,loc=<span class="string">'left'</span>,fontsize=<span class="number">18</span>)</span><br><span class="line">f1_ax4.set_title(<span class="string">'1st time series of right'</span>,loc=<span class="string">'center'</span>,fontsize=<span class="number">18</span>)</span><br></pre></td></tr></table></figure><p><img src="https://raw.githubusercontent.com/yxy-biubiubiu/Resources/main/images/f1_5_1_2.png" alt=""></p>]]></content>
<categories>
<category> Function </category>
</categories>
</entry>
<entry>
<title>Python vs NCL</title>
<link href="/2021/06/23/NCL.vs.Python/"/>
<url>/2021/06/23/NCL.vs.Python/</url>
<content type="html"><![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="gutter"><pre><span class="line">1</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><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>Python调用CDO及其它系统指令(下载资料)</title>
<link href="/2021/06/17/cdoinpython/"/>
<url>/2021/06/17/cdoinpython/</url>
<content type="html"><![CDATA[<p>之前一篇文章简单介绍了Climate Data Operators (CDO) 如何处理气候数据的软件,并提到配合Python可以方便的使用,这里就再进一步讲解如何在Python中调用CDO,以及其它系统指令。虽然CDO发布了Python-cdo提供了直接使用的方法,但是这里给一些不能安装python-cdo或者其它原因不使用这个库的用户一个其它的方法。</p><a id="more"></a><h2 id="一、-Python调用CDO"><a href="#一、-Python调用CDO" class="headerlink" title="一、 Python调用CDO"></a>一、 Python调用CDO</h2><p>这里只需要使用os库(操作系统接口)即可完成,更确切的说,是os.system()函数。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> os</span><br></pre></td></tr></table></figure><p>system函数可以将字符串转化成命令在服务器上运行;其原理是每一条system函数执行时,其会创建一个子进程在系统上执行命令行,子进程的执行结果无法影响主进程。有了这个函数,我们就可以在python脚本里随意使用CDO了。比如:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">os.system(<span class="string">'cdo selname,t2m ./in.nc ./out.nc'</span>)</span><br></pre></td></tr></table></figure><p>通常而言,我们会利用CDO批量处理一些数据,一条一条输入太过麻烦,这时候灵活利用循环format格式化函数就可以实现,如我们下载了NCEP再分析资料1948-2020年逐日的pressure level的温度数据,我们需要提取每年500 hPa的数据并且合并成1个文件:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> os</span><br><span class="line">filePath = <span class="string">'./data/'</span></span><br><span class="line">filename = os.listdir(filePath)<span class="comment">#获取文件名</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(len(filename)):<span class="comment">#对文件循环</span></span><br><span class="line"> os.system(<span class="string">'cdo sellevel,500 {}{} {}t500_{}.nc'</span>.format(filePath,filename[i],filePath,i)) <span class="comment">#对每个文件提取500hpa 变量,并输出为名为500_x.nc的文件x=0,1,2,3....</span></span><br><span class="line">os.system(<span class="string">'cdo -b 32 mergetime {}t500_* {}t500.nc'</span>.format(filePath,filePath)) <span class="comment">#合并</span></span><br><span class="line">os.system(<span class="string">'rm -f {}t500_*'</span>.format(filePath)) <span class="comment">#删除所有中间文件</span></span><br></pre></td></tr></table></figure><p>这里需要注意的是格式化函数的匹配,比如对os.system(‘cdo sellevel,500 {}{} {}t500_{}.nc’.format(filePath,filename[i],filePath,i))这行代码而言,代码中一共有四个{},分别对应filePath,filename[i],filePath和i。</p><h2 id="二、Python调用其它系统指令"><a href="#二、Python调用其它系统指令" class="headerlink" title="二、Python调用其它系统指令"></a>二、Python调用其它系统指令</h2><p>既然python可以通过os.system函数调用CDO,那同样也可以调用其它指令,实际上在上边一个示例的最后一行代码已经涉及到了,调用了系统的rm函数删除了中间文件。</p><p>我在<a href="https://yxy-biubiubiu.github.io/2020/05/13/%E4%BD%BF%E7%94%A8python%E6%89%B9%E9%87%8F%E4%B8%8B%E8%BD%BDECMWF%E6%95%B0%E6%8D%AE/" target="_blank" rel="noopener">批量下载气象数据(EC;NCEP;CMIP)</a>介绍过使用bash脚本批量下载数据的方法,这里我们进行一点简单的修改,就可以在python里实现批量下载。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><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> os</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> np.arange(<span class="number">1948</span>,<span class="number">2021</span>,<span class="number">1</span>):</span><br><span class="line"> os.system(<span class="string">'wget ftp://ftp2.psl.noaa.gov/Datasets/ncep.reanalysis.dailyavgs/pressure/hgt.{}.nc'</span>.format(i))</span><br></pre></td></tr></table></figure><p>对于不熟悉shell语言的伙伴们,看到这样的方法可能会更亲切一点吧。需要注意的是wget语句会默认将文件下载到python脚本所在路径,通过-O 参数可以指定下载路径。</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wget -O ./data/1948.nc ftp://ftp2.psl.noaa.gov/Datasets/ncep.reanalysis.dailyavgs/pressure/hgt.1948.nc</span><br></pre></td></tr></table></figure><p>当然wget还有更多参数,有兴趣的可以参考<a href="https://blog.csdn.net/qq_27870421/article/details/91951402" target="_blank" rel="noopener">wget参数</a>。</p><p>当然如果你使用的是jupyternotebook,那可能你无法看到下载进度了。当然也有一个不是办法的应对办法,安装一个进度条库:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install tqdm</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><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> os</span><br><span class="line"><span class="keyword">from</span> tqdm.notebook <span class="keyword">import</span> tqdm</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> tqdm(np.arange(<span class="number">1948</span>,<span class="number">2021</span>,<span class="number">1</span>)):</span><br><span class="line"> os.system(<span class="string">'wget ftp://ftp2.psl.noaa.gov/Datasets/ncep.reanalysis.dailyavgs/pressure/hgt.{}.nc'</span>.format(i))</span><br></pre></td></tr></table></figure><p>这时再试试看使用了tqdm有什么区别呢?</p>]]></content>
<categories>
<category> Paper </category>
</categories>
<tags>
<tag> Other </tag>
<tag> Data </tag>
</tags>
</entry>
<entry>
<title>关于绘图思路法人一点想法</title>
<link href="/2021/06/15/%E6%B5%85%E8%B0%88%E7%BB%98%E5%9B%BE%E6%80%9D%E8%B7%AF/"/>
<url>/2021/06/15/%E6%B5%85%E8%B0%88%E7%BB%98%E5%9B%BE%E6%80%9D%E8%B7%AF/</url>
<content type="html"><![CDATA[<p>有大半年没有打开简书了(愧对各位默默关注我的读者),得空看了下简书后台的评论,整理了下发现很多新入坑的伙伴的主要问题还是针对绘图和数据处理的(比如很多小伙伴不知道自己要画什么图,或者知道自己要画什么但是不知道怎么把手中的数据变成需要的图),这里就一并合在一起谈谈我对数据处理和绘图思路的理解(主要是思路),若有不妥还请指正。主要是针对新入门的。</p><a id="more"></a><p>把绘图说的正式一点,就是数据可视化,其本质还是对于数据的呈现方式,所以所有的图片本身不过还是数据而已。对于计算机来说就是二维的像素矩阵,每个像素有自己的颜色,所以呈现出了一张平面图片。对于我们要做的气象绘图而言,也不过是把形式不同的数据变成最终想要的图片。所以在绘图前应该是首先确定自己要呈现怎样的效果,为了这个效果来制定符合的图片类型,然后再分析这种图片类型是由什么格式的数据实现的,最后再去寻找响应的数据并处理。实际上这是一个逆向的思维过程,那我们先从简单的折线图开始。</p><p><img src="/image/htsl1.png" alt="图1-折线图1"></p><p>比如说我们在文献中看到了类似<strong>图1-折线图1</strong>,需要模仿绘制。那么首先观察这幅图的特征,其本质就是200个点连起来的折线,所以这幅图的本质就是200个点构成的序列,假设这幅图是近200年的区域平均降水量,而我们手中的数据是(年,月,经度,纬度)的降水量数据,那么我们对月平均和经度,纬度这三个纬度进行平均,就可以得到数据格式为(年)的序列。之后利用绘制折线图的函数ax.plot(x,y)就可以了(如果是温度廓线,那么对应的x就是温度,y就是高度;如果是某变量如阻塞指数沿经度分布,那么y就是阻塞指数,x就是经度,灵活应用即可)。</p><p>那么现在把折线图变得复杂一些:</p><p><img src="/image/htsl2.png" alt="图2-折线图2"></p><p>这种图常见于预估类的文献,阴影区间表示浮动范围(假如是正负一倍标准差), 那么我们需要计算的就是中间的序列,以及它的浮动范围,本质上依然是三条折线(折线本身+(折线+1δ)+(折线-1δ))。如果不知道绘制阴影的函数,将其绘制成三条折线的效果也是一样的,浮动范围可以用虚线。如果想要绘制阴影,百度下”matplotlib如何绘制阴影区间”也可以搜到plt.fill_between这个函数。把图换成柱状图本质也是一样的(一条序列)。</p><p>提到预估类的工作就不得不提到箱线图(主要用来分析和对比数据分布情况的,分布情况主要指的是离散程度,分位数位置等等),这里就献丑以我自己的一个工作来展示。</p><p><img src="/image/htsl3.png" alt="图3-箱线图1"></p><p>我这里是对比了四个时间区段的情况,图例清楚的说明了箱体和箱须分别代表的含义。那么需要怎样的数据来实现这幅图呢?首先可以确定的这是四组数据(肯定是四组由数字构成的一维数组),对于python来说,不需要我们事先计算每组数据的均值,中位数,分位数等等,只需将原始数据放入绘图函数ax.boxplot即可。所以我们只在指定的X轴的对应位置使用四次ax.boxplot函数。</p><p>接下来再说说等值线图:</p><p><img src="/image/htsl4.png" alt="图4-等值线图1"></p><p>不要看它是N条线组成的就以为它的组成数组是N个序列!高中地理就都学过等高面图,就是把相等大小的点连在一起。所以可以看到<strong>图4-等值线图1</strong>每条线的颜色是不一样的,因为颜色是反应组成这条线的数的大小。所以实际上这幅图是由N*M个点组成的,每个点都有一个数字,把大小相同的数字连接起来构成等值线图(等下用填色图更好理解)。所以这张图需要一个(N,M)的数组通过ax.contour函数实现。这个(N,M)数组的获取方式,需要分析N是什么,M是什么。如果是空间分布,那就是将原数据保留经纬度,将其它维度(时间,高度)处理,如果是纬高分布,那就将纬度和高度保留,同理,如果是纬度-时间分布,就保留纬度和时间。</p><p><img src="/image/htsl5.png" alt="图5-填色图1"></p><p>现在将空白区域进行了填色,处于两条等值线之间的区域为同一颜色。也就是说,处于同一个区间范围的,为同一种颜色。</p><p><img src="/image/htsl6.png" alt="图6-填色图2"></p><p>我进一步对每一个点进行了标记来方便理解。这幅图就是由这么多个点的同样形状的(N,M)数组构成,每个点都有自己的大小(也就对应了其颜色)。</p><p>再进一步的,我们通常要进行显著性检验,也就是对填色图进行一个”打点”的操作。让过检部分加上阴影或者dots。实现思路是这样的:打点或者添加阴影本质也是一种填色,只不过填的不是颜色,而是一种特殊的标记。所以我们只需要在过检部分填色就好了,设置方法是通过ax.contourf函数的level参数设置填色区间,用hatches参数设置填色标记,我们在进行检验计算时,都会返回对应的P值数组,P<0.05为通过0.05显著性检验,所以这时只需对P值数组0-0.05范围进行标记填充即可。</p><p>再来说说矢量绘制:</p><p><img src="/image/htsl7.png" alt="图7-矢量图1"></p><p>我们首先要知道,矢量的构成,要表达矢量,需要有两个要素,也就是大小和方向,通过正交分解则变成了i矢量和j矢量。对于风场来说,就是u,v。对于上边的前边的填色图来说,是由(N,M)的数组构成,颜色反应每个点的数值。那对于矢量场来说,依然是(N,M)的数组组成的,箭头反应每个点的矢量,特殊的在于,需要同时使用u,和v才能正确表达矢量。所以本质应该是u(N,M)和v(N,M)的叠加。所以绘制时只需要对ax.quiver()函数同时输入u,v即可。</p><p>对于散点图而言,它就像缺失了很多数据的填色图一样(或者理解为仅保留了部分点的填色图),所以它一定不是(N,M)数组构成的了。要绘制填色图,我们首先要知道每个点的x和y的位置,其次也要知道这个点的大小(反应为颜色),所以它是由(n,3)组成的,n指n个点,3分别为x,y和点本身的大小。</p><p>总的来说,先根据自己需要画的图来设计目标数据(比如我要画折线图,那我就需要1条序列;我需要填色图,我就需要1个(N,M)数组),确定自己目标数据的形状,然后再根据目标数据的形状来处理原始数据。同样的,在模仿一幅图的时候,先确定它的数据形状,再根据它的X,Y轴确定它图形背后数组的实际意义,才能有针对性的获取和处理数据。至于其它细节性的修饰,如何让图更美观,就考验后期的调整了。当然matplotlib官方本身已经提供了大量的示例,几乎包含了常规图形,不妨收藏在书签栏,画图前看看有没有类似自己需要的,直接拿来修改当然是最方便的。最后一定要善于利用度娘,搜索matoplotlib如何绘制xxxxx,或者python如何让折线图更美观等等。</p>]]></content>
<categories>
<category> Paper </category>
</categories>
<tags>
<tag> Python </tag>
<tag> Matplotlib </tag>
</tags>
</entry>
<entry>
<title>多轨迹绘制</title>
<link href="/2021/06/15/guiji1/"/>
<url>/2021/06/15/guiji1/</url>
<content type="html"><![CDATA[<p>之前在简书有发布过<a href="https://www.jianshu.com/p/454de73985ea" target="_blank" rel="noopener">Python气象数据处理与绘图(12):轨迹(台风路径,寒潮路径,水汽轨迹)绘制</a>,提问的人比较多,这里我给出比较完整的方法和代码。实际上本质还是循环(应该还有更简便的办法,有思路的小伙伴可以留言反馈)。由于之前的文件过于复杂,这次我重新使用Hysplit模式追踪了一些路径,<a href="/image/trajs.rar">数据文件</a>供大家测试使用。</p><p>数据文件结构如下:</p><p><img src="/image/traj1.png" alt="数据结构"></p><p>这里解释一下红色框住的部分,(Hysplit模式运行一次默认从10,500,1000米三个高度追踪三条轨迹)第一个框为三条轨迹的序号,第二个框为追踪事件,这里-1.0指的是后向模拟1小时,我文件提供的是后向5天的追踪,所以最后会到-120。第三个框就是三维位置了。我一共提供了5次模拟的数据,一共是5*3=15条轨迹,每个轨迹为121(120+1起点)个时间点。</p><p>读取文件:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><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> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="comment">#建立空数组存放三维位置</span></span><br><span class="line">x = np.zeros((<span class="number">5</span>,<span class="number">3</span>,<span class="number">121</span>),<span class="string">"float"</span>)</span><br><span class="line">y = np.zeros((<span class="number">5</span>,<span class="number">3</span>,<span class="number">121</span>),<span class="string">"float"</span>)</span><br><span class="line">z = np.zeros((<span class="number">5</span>,<span class="number">3</span>,<span class="number">121</span>),<span class="string">"float"</span>)</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(<span class="number">5</span>):</span><br><span class="line"> f_tmp = pd.read_csv(<span class="string">"./{}"</span>.format(i),sep=<span class="string">'\s+'</span>,skiprows=<span class="number">11</span>,header=<span class="literal">None</span>, names=[<span class="string">'a'</span>,<span class="string">'b'</span>,<span class="string">'c'</span>,<span class="string">'d'</span>,<span class="string">'e'</span>,<span class="string">'f'</span>,<span class="string">'g'</span>,<span class="string">'h'</span>,<span class="string">'i'</span>,<span class="string">'j'</span>,<span class="string">'k'</span>,<span class="string">'l'</span>,<span class="string">'m'</span>]) </span><br><span class="line"> f_tmp = np.array(f_tmp).reshape((<span class="number">121</span>,<span class="number">3</span>, <span class="number">13</span>))</span><br><span class="line"> x[i,<span class="number">0</span>,:] = f_tmp[:,<span class="number">0</span>,<span class="number">10</span>]</span><br><span class="line"> y[i,<span class="number">0</span>,:] = f_tmp[:,<span class="number">0</span>,<span class="number">9</span>]</span><br><span class="line"> z[i,<span class="number">0</span>,:] = f_tmp[:,<span class="number">0</span>,<span class="number">11</span>]</span><br><span class="line"> x[i,<span class="number">1</span>,:] = f_tmp[:,<span class="number">1</span>,<span class="number">10</span>]</span><br><span class="line"> y[i,<span class="number">1</span>,:] = f_tmp[:,<span class="number">1</span>,<span class="number">9</span>]</span><br><span class="line"> z[i,<span class="number">1</span>,:] = f_tmp[:,<span class="number">1</span>,<span class="number">11</span>]</span><br><span class="line"> x[i,<span class="number">2</span>,:] = f_tmp[:,<span class="number">2</span>,<span class="number">10</span>]</span><br><span class="line"> y[i,<span class="number">2</span>,:] = f_tmp[:,<span class="number">2</span>,<span class="number">9</span>]</span><br><span class="line"> z[i,<span class="number">2</span>,:] = f_tmp[:,<span class="number">2</span>,<span class="number">11</span>]</span><br></pre></td></tr></table></figure><p>绘制图形(这里只画了5条序号为2的轨迹):</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><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> 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="comment">#地图底图</span></span><br><span class="line">fig = plt.figure(figsize=(<span class="number">12</span>,<span class="number">7</span>)) </span><br><span class="line">proj = ccrs.PlateCarree(central_longitude=<span class="number">95</span>)</span><br><span class="line">leftlon, rightlon, lowerlat, upperlat = (<span class="number">90</span>,<span class="number">150</span>,<span class="number">20</span>,<span class="number">60</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.1</span>, <span class="number">0.8</span>, <span class="number">0.6</span>],projection = proj)</span><br><span class="line">f_ax1.set_extent(img_extent, crs=ccrs.PlateCarree())</span><br><span class="line">f_ax1.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>)) </span><br><span class="line">f_ax1.add_feature(cfeature.LAKES, alpha=<span class="number">0.5</span>)</span><br><span class="line">f_ax1.set_xticks(np.arange(leftlon,rightlon+<span class="number">20</span>,<span class="number">20</span>), crs=ccrs.PlateCarree())</span><br><span class="line">f_ax1.set_yticks(np.arange(lowerlat,upperlat+<span class="number">20</span>,<span class="number">20</span>), 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">f_ax1.xaxis.set_major_formatter(lon_formatter)</span><br><span class="line">f_ax1.yaxis.set_major_formatter(lat_formatter)</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(<span class="number">5</span>):</span><br><span class="line"> lon = x[i,<span class="number">2</span>,:]</span><br><span class="line"> lat = y[i,<span class="number">2</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 class="comment">#整合经纬度</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"> norm = plt.Normalize(<span class="number">0</span>, <span class="number">2000</span>)<span class="comment">#按0-2000的高度对色标标准化</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(z[i,<span class="number">2</span>,<span class="number">1</span>:])<span class="comment">#颜色色组指定为高度,两个点中间为一条线,所以颜色数组应为点数减1,所以是z[i,2,1:]</span></span><br><span class="line"> line = f_ax1.add_collection(lc) </span><br><span class="line"><span class="comment">#色标</span></span><br><span class="line">position=fig.add_axes([<span class="number">0.32</span>, <span class="number">0.01</span>, <span class="number">0.35</span>, <span class="number">0.025</span>])</span><br><span class="line">fig.colorbar(line,cax=position,orientation=<span class="string">'horizontal'</span>,format=<span class="string">'%d'</span>) </span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p>输出图形如下:</p><p><img src="/image/traj2.png" alt="traj"></p>]]></content>
<categories>
<category> Plot </category>
</categories>
</entry>
<entry>
<title>带显著性检验的填色图</title>
<link href="/2021/04/22/contourf1/"/>
<url>/2021/04/22/contourf1/</url>
<content type="html"><![CDATA[<p>以一个序列和一个场的相关系数为例,绘制带显著性检验的填色图。</p><p>对于一个序列 a(T)和一个场 b(T, M, N), T可理解为时间维度,如40年,M,N分别为纬度和经度。其相关系数及对应的P值为:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><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">from</span> scipy.stats <span class="keyword">import</span> pearsonr</span><br><span class="line">r = np.zeros((M,N))</span><br><span class="line">p = np.zeros((M,N))</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(M):</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> range(N):</span><br><span class="line"> r[i,j], p[i,j] = pearsonr(a, b[:,i,j])</span><br></pre></td></tr></table></figure><p>p值小于0.01(0.05)则为通过0.01(0.05)置信度显著性检验的区域,以此类推。</p><p>图形绘制:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><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="comment">#选择投影</span></span><br><span class="line">proj = ccrs.PlateCarree(central_longitude=<span class="number">245</span>)</span><br><span class="line"><span class="comment">#创建图形</span></span><br><span class="line">fig = plt.figure(figsize=(<span class="number">12</span>,<span class="number">8</span>))</span><br><span class="line">fig_ax1 = fig.add_axes([<span class="number">0.1</span>, <span class="number">0.1</span>, <span class="number">0.5</span>, <span class="number">0.5</span>],projection = proj)</span><br><span class="line"><span class="comment">#设置边界</span></span><br><span class="line">leftlon, rightlon, lowerlat, upperlat = (<span class="number">130</span>,<span class="number">360</span>,<span class="number">-20</span>,<span class="number">70</span>)</span><br><span class="line">img_extent = [leftlon, rightlon, lowerlat, upperlat]</span><br><span class="line">fig_ax1.set_extent(img_extent, crs=ccrs.PlateCarree())</span><br><span class="line"><span class="comment">#绘制海岸线和湖泊等地理特征</span></span><br><span class="line">fig_ax1.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>)) </span><br><span class="line">fig_ax1.add_feature(cfeature.LAKES, alpha=<span class="number">0.5</span>)</span><br><span class="line"><span class="comment">#设置刻度及刻度标签格式</span></span><br><span class="line">fig_ax1.set_xticks(np.arange(leftlon,rightlon+<span class="number">30</span>,<span class="number">30</span>), crs=ccrs.PlateCarree())</span><br><span class="line">fig_ax1.set_yticks(np.arange(lowerlat,upperlat+<span class="number">30</span>,<span class="number">30</span>), 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_ax1.xaxis.set_major_formatter(lon_formatter)</span><br><span class="line">fig_ax1.yaxis.set_major_formatter(lat_formatter)</span><br><span class="line"><span class="comment">#绘制相关系数填色</span></span><br><span class="line">cf1 = fig_ax1.contourf(lon,lat,r, zorder=<span class="number">0</span>, levels =np.arange(<span class="number">-1</span>,<span class="number">1.1</span>,<span class="number">0.1</span>) , extend = <span class="string">'both'</span>,transform=ccrs.PlateCarree(), cmap=plt.cm.RdBu_r)</span><br><span class="line"><span class="comment">#绘制显著性打点。思路为将0-0.05范围内的区域用点的标记来填充,来表示显著性95%水平。</span></span><br><span class="line">cf2 = fig_ax1.contourf(lon,lat, p, [<span class="number">0</span>,<span class="number">0.05</span>,<span class="number">1</span>] , </span><br><span class="line"> zorder=<span class="number">1</span>,hatches=[<span class="string">'...'</span>, <span class="literal">None</span>],colors=<span class="string">"none"</span>, transform=ccrs.PlateCarree())</span><br><span class="line"><span class="comment">#色标</span></span><br><span class="line">position=fig3.add_axes([<span class="number">0.1</span>, <span class="number">0.08</span>, <span class="number">0.35</span>, <span class="number">0.025</span>])</span><br><span class="line">fig3.colorbar(cf1,cax=position,orientation=<span class="string">'horizontal'</span>,format=<span class="string">'%.2f'</span>,)</span><br><span class="line"><span class="comment">#显示</span></span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p>输出图形如下:</p><p><img src="/image/contourf1-1.png" alt="image-20200702161610554"></p>]]></content>
<categories>
<category> Plot </category>
</categories>
</entry>
<entry>
<title>绘图函数封装</title>
<link href="/2021/04/22/huitufengzhuang/"/>
<url>/2021/04/22/huitufengzhuang/</url>
<content type="html"><![CDATA[<p>绘制带有地理底图时调用。</p><p>默认添加海岸线,湖泊,设置地图边界及X,Y轴经纬度刻度。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><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><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">contour_map</span><span class="params">(fig,img_extent,spec1,spec2)</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+spec1,spec1), crs=ccrs.PlateCarree())</span><br><span class="line"> fig.set_yticks(np.arange(lowerlat,upperlat+spec2,spec2), 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><p>使用示例:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#创建图像</span></span><br><span class="line">fig = plt.figure(figsize=(<span class="number">12</span>,<span class="number">8</span>))</span><br><span class="line">f_ax1 = fig3.add_axes([<span class="number">0.1</span>, <span class="number">0.1</span>, <span class="number">0.5</span>, <span class="number">0.5</span>],projection = proj)</span><br><span class="line"><span class="comment">#设置边界</span></span><br><span class="line">leftlon, rightlon, lowerlat, upperlat = (<span class="number">130</span>,<span class="number">360</span>,<span class="number">-20</span>,<span class="number">70</span>)</span><br><span class="line">img_extent = [leftlon, rightlon, lowerlat, upperlat]</span><br><span class="line"><span class="comment">#调用函数</span></span><br><span class="line">contour_map(f3_ax1,img_extent,<span class="number">30</span>,<span class="number">30</span>)</span><br><span class="line"><span class="comment">#绘图</span></span><br><span class="line">cf1 = f_ax1.contourf(lon,lat,r, zorder=<span class="number">0</span>, levels =np.arange(<span class="number">-1</span>,<span class="number">1.1</span>,<span class="number">0.1</span>) , extend = <span class="string">'both'</span>,transform=ccrs.PlateCarree(), cmap=plt.cm.RdBu_r)</span><br><span class="line">cf2 = f_ax1.contourf(lon,lat, p, [<span class="number">0</span>,<span class="number">0.05</span>,<span class="number">1</span>] , </span><br><span class="line"> zorder=<span class="number">1</span>,hatches=[<span class="string">'...'</span>, <span class="literal">None</span>],colors=<span class="string">"none"</span>, transform=ccrs.PlateCarree())</span><br><span class="line"><span class="comment">#绘制色标</span></span><br><span class="line">position=fig3.add_axes([<span class="number">0.2</span>, <span class="number">0.08</span>, <span class="number">0.35</span>, <span class="number">0.025</span>])</span><br><span class="line">fig3.colorbar(cf1,cax=position,orientation=<span class="string">'horizontal'</span>,format=<span class="string">'%.2f'</span>,)</span><br><span class="line"><span class="comment">#显示</span></span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p>输出图形如下:</p><p><img src="/image/contourf1-1.png" alt="image-20200702161610554"></p>]]></content>
<categories>
<category> Plot </category>
</categories>
</entry>
<entry>
<title>CMA热带气旋最佳路径数据集读取与绘制</title>
<link href="/2020/09/18/cma-tc-best-path/"/>
<url>/2020/09/18/cma-tc-best-path/</url>
<content type="html"><![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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><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>小波变换(测试中)</title>
<link href="/2020/09/13/wavelet/"/>
<url>/2020/09/13/wavelet/</url>
<content type="html"><![CDATA[<p>该方法仍在测试中,欢迎大家使用,如有问题请及时与我联系,联系方式详见右侧边栏about页面。</p><p>算法主体:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br></pre></td><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">from</span> numpy <span class="keyword">import</span> fft</span><br><span class="line"><span class="keyword">from</span> numpy.fft <span class="keyword">import</span> ifft</span><br><span class="line"><span class="keyword">from</span> scipy.special <span class="keyword">import</span> gamma</span><br><span class="line"><span class="keyword">from</span> scipy.stats.distributions <span class="keyword">import</span> chi2</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="function"><span class="keyword">def</span> <span class="title">wave_bases</span><span class="params">(mother,k,scale,param)</span>:</span></span><br><span class="line"> n = k.shape[<span class="number">0</span>]</span><br><span class="line"> k_tmp = k.copy()</span><br><span class="line"> k_tmp[k_tmp><span class="number">0</span>]=<span class="number">1</span></span><br><span class="line"> k_tmp[k_tmp<=<span class="number">0</span>]=<span class="number">0</span></span><br><span class="line"> <span class="keyword">if</span> (mother ==<span class="string">'MORLET'</span>):</span><br><span class="line"> k0 = param</span><br><span class="line"> expnt = (<span class="number">-1</span>)*(scale*k - k0)**<span class="number">2</span>/<span class="number">2</span>*k_tmp</span><br><span class="line"> norm = np.sqrt(scale*k[<span class="number">1</span>])*(np.pi**(<span class="number">-0.25</span>))*np.sqrt(n)</span><br><span class="line"> daughter = norm*np.exp(expnt)</span><br><span class="line"> daughter = daughter*k_tmp </span><br><span class="line"> fourier_factor = (<span class="number">4</span>*np.pi)/(k0 + np.sqrt(<span class="number">2</span> + k0**<span class="number">2</span>))</span><br><span class="line"> coi = fourier_factor/np.sqrt(<span class="number">2</span>)</span><br><span class="line"> dofmin = <span class="number">2</span></span><br><span class="line"> <span class="keyword">elif</span> (mother ==<span class="string">'PAUL'</span>):</span><br><span class="line"> m = param</span><br><span class="line"> expnt = (<span class="number">-1</span>)*(scale*k)*k_tmp</span><br><span class="line"> norm = np.sqrt(scale*k[<span class="number">1</span>])*(<span class="number">2</span>**m/np.sqrt(m*np.prod(np.arange(<span class="number">2</span>,<span class="number">2</span>*m))))*np.sqrt(n)</span><br><span class="line"> daughter = norm*((scale*k)**m)*np.exp(expnt)</span><br><span class="line"> daughter = daughter*k_tmp </span><br><span class="line"> fourier_factor = <span class="number">4</span>*np.pi/(<span class="number">2</span>*m+<span class="number">1</span>)</span><br><span class="line"> coi = fourier_factor*np.sqrt(<span class="number">2</span>)</span><br><span class="line"> dofmin = <span class="number">2</span></span><br><span class="line"> <span class="keyword">elif</span> (mother ==<span class="string">'DOG'</span>):</span><br><span class="line"> m = param</span><br><span class="line"> expnt = (<span class="number">-1</span>)*(scale*k)**<span class="number">2</span>/<span class="number">2.0</span></span><br><span class="line"> norm = np.sqrt(scale*k[<span class="number">1</span>]/gamma(m+<span class="number">0.5</span>))*np.sqrt(n)</span><br><span class="line"> daughter = (<span class="number">-1</span>)*norm*((<span class="number">1j</span>)**m)*((scale*k)**m)*np.exp(expnt)</span><br><span class="line"> fourier_factor = <span class="number">2</span>*np.pi*np.sqrt(<span class="number">2</span>/(<span class="number">2</span>*m+<span class="number">1</span>))</span><br><span class="line"> coi = fourier_factor/np.sqrt(<span class="number">2</span>)</span><br><span class="line"> dofmin = <span class="number">1</span></span><br><span class="line"> <span class="keyword">return</span> daughter,fourier_factor,coi,dofmin</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">wavelet</span><span class="params">(Y,dt,pad,dj,s0,J1,mother,param)</span>:</span></span><br><span class="line"> n1 = Y.shape[<span class="number">0</span>]</span><br><span class="line"> x = (Y - Y.mean())</span><br><span class="line"> <span class="keyword">if</span> (pad == <span class="number">1</span>):</span><br><span class="line"> base2 = np.trunc(np.log(n1)/np.log(<span class="number">2</span>) + <span class="number">0.4999</span>).astype(<span class="string">'int32'</span>)</span><br><span class="line"> x = np.hstack((x,np.zeros((<span class="number">2</span>**(base2+<span class="number">1</span>)-n1))))</span><br><span class="line"> n = x.shape[<span class="number">0</span>]</span><br><span class="line"> k = np.arange(<span class="number">1</span>,n//<span class="number">2</span>+<span class="number">1</span>,<span class="number">1</span>)</span><br><span class="line"> k = k*((<span class="number">2</span>*np.pi)/(n*dt))</span><br><span class="line"> k = np.hstack((<span class="number">0</span>,k,((<span class="number">-1</span>)*k[np.arange((n<span class="number">-1</span>)//<span class="number">2</span><span class="number">-1</span>,<span class="number">-1</span>,<span class="number">-1</span>)])))</span><br><span class="line"> f = np.fft.fft(x)</span><br><span class="line"> scale = s0*<span class="number">2</span>**(np.arange(<span class="number">0</span>,J1+<span class="number">1</span>)*dj)</span><br><span class="line"> period = scale</span><br><span class="line"> wave = np.zeros((np.array(J1+<span class="number">1</span>).astype(<span class="string">'int32'</span>),n))</span><br><span class="line"> wave = wave + (<span class="number">1j</span>)*wave</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">1</span>,np.array(J1+<span class="number">2</span>).astype(<span class="string">'int32'</span>)):</span><br><span class="line"> daughter,fourier_factor,coi,dofmin = wave_bases(mother,k,scale[i<span class="number">-1</span>],param)</span><br><span class="line"> wave[i<span class="number">-1</span>,:] = ifft(f*daughter)</span><br><span class="line"> period = fourier_factor*scale</span><br><span class="line"> coi = coi*dt*np.hstack((<span class="number">1e-5</span>,np.arange(<span class="number">1</span>,(n1+<span class="number">1</span>)//<span class="number">2</span>,<span class="number">1</span>),np.arange(<span class="number">1</span>,n1//<span class="number">2</span>,<span class="number">1</span>)[::<span class="number">-1</span>],<span class="number">1e-5</span>))</span><br><span class="line"> wave = wave[:,:n1]</span><br><span class="line"> <span class="keyword">return</span> wave,period,scale,coi</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">wave_signif</span><span class="params">(Y,dt,scale1,sigtest,lag1,siglvl,dof,mother,param)</span>:</span></span><br><span class="line"> n1 = np.array([Y]).shape</span><br><span class="line"> J1 = scale1.shape[<span class="number">0</span>] - <span class="number">1</span></span><br><span class="line"> scale[:J1+<span class="number">1</span>] = scale1</span><br><span class="line"> s0 = np.min(scale)</span><br><span class="line"> dj = np.log(scale[<span class="number">1</span>]/scale[<span class="number">0</span>])/np.log(<span class="number">2</span>)</span><br><span class="line"> variance = Y</span><br><span class="line"> <span class="keyword">if</span> (mother ==<span class="string">'MORLET'</span>):</span><br><span class="line"> k0 = param</span><br><span class="line"> fourier_factor = (<span class="number">4</span>*np.pi)/(k0 + np.sqrt(<span class="number">2</span> + k0**<span class="number">2</span>))</span><br><span class="line"> empir = np.array([<span class="number">2.</span>,<span class="number">-1</span>,<span class="number">-1</span>,<span class="number">-1</span>])</span><br><span class="line"> <span class="keyword">if</span> (k0==<span class="number">6</span>):</span><br><span class="line"> empir[<span class="number">1</span>:]= np.array([<span class="number">0.776</span>,<span class="number">2.32</span>,<span class="number">0.60</span>])</span><br><span class="line"> <span class="keyword">elif</span> (mother ==<span class="string">'PAUL'</span>):</span><br><span class="line"> m = param</span><br><span class="line"> fourier_factor = <span class="number">4</span>*np.pi/(<span class="number">2</span>*m+<span class="number">1</span>)</span><br><span class="line"> empir = np.array([<span class="number">2.</span>,<span class="number">-1</span>,<span class="number">-1</span>,<span class="number">-1</span>])</span><br><span class="line"> <span class="keyword">if</span> (m==<span class="number">4</span>):</span><br><span class="line"> empir[<span class="number">1</span>:]= np.array([<span class="number">1.132</span>,<span class="number">1.17</span>,<span class="number">1.5</span>])</span><br><span class="line"> <span class="keyword">elif</span> (mother ==<span class="string">'DOG'</span>):</span><br><span class="line"> m = param</span><br><span class="line"> fourier_factor = <span class="number">2</span>*np.pi*np.sqrt(<span class="number">2</span>/(<span class="number">2</span>*m+<span class="number">1</span>))</span><br><span class="line"> empir = np.array([<span class="number">1</span>,<span class="number">-1</span>,<span class="number">-1</span>,<span class="number">-1</span>])</span><br><span class="line"> <span class="keyword">if</span> (m==<span class="number">2</span>):</span><br><span class="line"> empir[<span class="number">1</span>:]= np.array([<span class="number">3.541</span>,<span class="number">1.43</span>,<span class="number">1.4</span>])</span><br><span class="line"> <span class="keyword">elif</span> (m==<span class="number">6</span>):</span><br><span class="line"> empir[<span class="number">1</span>:]= np.array([<span class="number">1.966</span>,<span class="number">1.37</span>,<span class="number">0.97</span>])</span><br><span class="line"> period = scale*fourier_factor</span><br><span class="line"> dofmin = empir[<span class="number">0</span>]</span><br><span class="line"> Cdelta = empir[<span class="number">1</span>]</span><br><span class="line"> gamma_fac = empir[<span class="number">2</span>]</span><br><span class="line"> dj0 = empir[<span class="number">3</span>]</span><br><span class="line"> freq = dt / period</span><br><span class="line"> fft_theor = (<span class="number">1</span>-lag1**<span class="number">2</span>) / (<span class="number">1</span><span class="number">-2</span>*lag1*np.cos(freq*<span class="number">2</span>*np.pi)+lag1**<span class="number">2</span>)</span><br><span class="line"> fft_theor = variance*fft_theor</span><br><span class="line"> signif = fft_theor</span><br><span class="line"> <span class="keyword">if</span> (np.array(dof).sum() == <span class="number">-1</span>):</span><br><span class="line"> dof = dofmin</span><br><span class="line"> <span class="keyword">if</span> (sigtest == <span class="number">0</span>):</span><br><span class="line"> dof = dofmin</span><br><span class="line"> chisquare = chi2.ppf(siglvl,dof)/dof</span><br><span class="line"> signif = fft_theor*chisquare</span><br><span class="line"> <span class="keyword">elif</span> (sigtest == <span class="number">1</span>):</span><br><span class="line"> <span class="keyword">if</span> (dof.shape[<span class="number">0</span>] == <span class="number">1</span>):</span><br><span class="line"> dof=np.zeros((J1+<span class="number">1</span>))+dof</span><br><span class="line"> dof[dof<<span class="number">1</span>]=<span class="number">1</span></span><br><span class="line"> dof = dofmin*np.sqrt(<span class="number">1</span> + (dof*dt/gamma_fac/ scale)**<span class="number">2</span> )</span><br><span class="line"> dof[dof<dofmin]=dofmin</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> np.arange(<span class="number">1</span>,J1+<span class="number">2</span>):</span><br><span class="line"> chisquare = chi2.ppf(siglvl,dof[i<span class="number">-1</span>])/dof[i<span class="number">-1</span>]</span><br><span class="line"> signif[i<span class="number">-1</span>] = fft_theor[i<span class="number">-1</span>]*chisquare</span><br><span class="line"> <span class="keyword">elif</span> (sigtest == <span class="number">2</span>):</span><br><span class="line"> s1 = dof[<span class="number">0</span>]</span><br><span class="line"> s2 = dof[<span class="number">1</span>]</span><br><span class="line"> avg = np.array(np.where((scale >= s1)&(scale < s2))).reshape(<span class="number">-1</span>)</span><br><span class="line"> navg = avg.shape[<span class="number">0</span>]</span><br><span class="line"> Savg = <span class="number">1</span>/np.sum(<span class="number">1</span>/ scale[avg],axis=(<span class="number">0</span>))</span><br><span class="line"> Smid = np.exp((np.log(s1)+np.log(s2))/<span class="number">2.</span>)</span><br><span class="line"> dof = (dofmin*navg*Savg/Smid)*np.sqrt(<span class="number">1</span> + (navg*dj/dj0)**<span class="number">2</span>)</span><br><span class="line"> fft_theor = Savg*np.sum(fft_theor[avg]/ scale[avg])</span><br><span class="line"> chisquare = chi2.ppf(siglvl,dof)/dof</span><br><span class="line"> signif = (dj*dt/Cdelta/Savg)*fft_theor*chisquare </span><br><span class="line"> <span class="keyword">return</span> signif,fft_theor</span><br></pre></td></tr></table></figure><ol><li><p>wave_bases(mother,k,scale,param)函数(生成小波函数,仅在wavelet函数中调用,无需处理)</p></li><li><p>wavelet(Y,dt,pad,dj,s0,J1,mother,param)函数 (小波变换本体函数)</p><p>各参数含义如下:</p><p>Y:输入数据,一维序列</p><p>pad:是否开启边缘扩展。若为1,则将边缘值填补为0</p><p>dt : 数据分辨率</p><p>dj: 最小尺度,越小越精细,但计算绘图越慢</p><p>s0:小波最小尺度,一般为2*dt</p><p>j1: 刻度数(不太好理解),范围从s0到s0×2^(j1×dj);一般取j1 = (log2(N×dt/s0))/dj</p><p>mother: 小波族,可选’MORLET’,’PAUL’,’DOG’三种小波</p><p>param:小波族对应的常量,morlet为6;paul 为4; dog为2</p><p>函数返回值:</p><p>wave,period,scale,coi</p></li></ol><ol start="3"><li><p>wave_signif(Y,dt,scale1,sigtest,lag1,siglvl,dof,mother,param) 函数 (显著性检验函数)</p><p>各参数含义如下:</p><p>scale1:wavelet函数返回的scale</p><p>sigtest:显著性检验方法: 0为常规卡方检验;1为时间平均检验,对于局部小波,dof=np.nan,对于全局小波dof=N(N为时间序列的点数);2为尺度平均检验,dof为一个[s1,s2]型,例如一个尺度的尺度平均在2-8之间,则自由度dof=[2,8]</p><p>lag1:噪声自相关,用于显著性水平</p><p>siglvl:显著性水平,0.95为95%显著性</p><p>dof: 自由度</p></li></ol><h2 id="参数设置十分复杂,就目前而言还没找到能简单设置的方法,但是大部分参数是不需要修改的。"><a href="#参数设置十分复杂,就目前而言还没找到能简单设置的方法,但是大部分参数是不需要修改的。" class="headerlink" title="参数设置十分复杂,就目前而言还没找到能简单设置的方法,但是大部分参数是不需要修改的。"></a>参数设置十分复杂,就目前而言还没找到能简单设置的方法,但是大部分参数是不需要修改的。</h2><p>给出一个具体示例,首先是计算部分:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">np.set_printoptions(threshold=np.inf)</span><br><span class="line"><span class="comment">#读数据,与数据标准化,数据为126年季节平均的nino3指数(1871-1997年)</span></span><br><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line">sst = np.array(pd.read_table(<span class="string">'/data/home/zenggang/yxy/sst_nino3.dat'</span>,header =<span class="literal">None</span>)).reshape((<span class="number">-1</span>))</span><br><span class="line">variance = sst.std()*sst.std()</span><br><span class="line">sst = ((sst - sst.mean())/sst.std())</span><br><span class="line"><span class="comment">#参数设置</span></span><br><span class="line">n = sst.shape[<span class="number">0</span>]</span><br><span class="line">dt = <span class="number">0.25</span> </span><br><span class="line">time = np.arange(n)*dt + <span class="number">1871.0</span> ; <span class="comment">#年份数据</span></span><br><span class="line">pad = <span class="number">1</span>; <span class="comment"># 边缘效应</span></span><br><span class="line">dj = <span class="number">0.25</span> <span class="comment"># </span></span><br><span class="line">s0 = <span class="number">2</span>*dt <span class="comment"># 最小尺度从逐6个月开始</span></span><br><span class="line">j1 = <span class="number">7</span>/dj <span class="comment"># </span></span><br><span class="line">lag1 = <span class="number">0.72</span> <span class="comment"># </span></span><br><span class="line">mother = <span class="string">'MORLET'</span></span><br><span class="line"><span class="comment">#计算小波</span></span><br><span class="line">wave,period,scale,coi = wavelet(sst,dt,pad,dj,s0,j1,mother,<span class="number">6</span>)</span><br><span class="line">power = (np.abs(wave))**<span class="number">2</span></span><br><span class="line"><span class="comment">#显著性检验</span></span><br><span class="line">signif,fft_theor = wave_signif(<span class="number">1</span>,dt,scale,<span class="number">0</span>,lag1,<span class="number">0.95</span>,<span class="number">0</span>,mother,<span class="number">6</span>);</span><br><span class="line">sig95 = (signif.T).reshape((<span class="number">-1</span>,<span class="number">1</span>))*(np.zeros((n))+<span class="number">1</span>).reshape((<span class="number">1</span>,<span class="number">-1</span>))</span><br><span class="line">sig95 = power/ sig95</span><br><span class="line"></span><br><span class="line">global_ws = variance*(np.sum(power.T,axis = <span class="number">0</span>)/n)</span><br><span class="line">dof = n - scale</span><br><span class="line">global_signif,_ = wave_signif(variance,dt,scale,<span class="number">1</span>,lag1,<span class="number">0.95</span>,dof,mother,<span class="number">6</span>)</span><br><span class="line">avg = np.where((scale >= <span class="number">2</span>)&(scale < <span class="number">8</span>))</span><br><span class="line">Cdelta = <span class="number">0.776</span></span><br><span class="line">scale_avg = (scale.T).reshape((<span class="number">-1</span>,<span class="number">1</span>))*(np.zeros((n))+<span class="number">1</span>).reshape((<span class="number">1</span>,<span class="number">-1</span>))</span><br><span class="line">scale_avg = power/ scale_avg</span><br><span class="line">scale_avg = variance*dj*dt/Cdelta*np.sum(scale_avg[avg,:],axis = (<span class="number">0</span>,<span class="number">1</span>))</span><br><span class="line">scaleavg_signif,_ = wave_signif(variance,dt,scale,<span class="number">2</span>,lag1,<span class="number">0.95</span>,np.array([<span class="number">2</span>,<span class="number">7.9</span>]),mother,<span class="number">6</span>)</span><br></pre></td></tr></table></figure><p>接下来是作图部分:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#原始数据序列</span></span><br><span class="line">xlim = np.array([<span class="number">1870</span>,<span class="number">2000</span>])</span><br><span class="line">fig = plt.figure(figsize=(<span class="number">15</span>,<span class="number">15</span>))</span><br><span class="line">f_ax1 = fig.add_axes([<span class="number">0.1</span>,<span class="number">0.75</span>,<span class="number">0.65</span>,<span class="number">0.2</span>])</span><br><span class="line">f_ax1.plot(time,sst)</span><br><span class="line">f_ax1.set_xlabel(<span class="string">'Time (year)'</span>)</span><br><span class="line">f_ax1.set_ylabel(<span class="string">'NINO3 SST (degC)'</span>)</span><br><span class="line">f_ax1.set_title(<span class="string">'a) NINO3 Sea Surface Temperature (seasonal)'</span>)</span><br><span class="line"><span class="comment">#小波</span></span><br><span class="line">f_ax2 = fig.add_axes([<span class="number">0.1</span>, <span class="number">0.37</span> ,<span class="number">0.65</span> ,<span class="number">0.28</span>])</span><br><span class="line">levels = [<span class="number">0.0625</span>,<span class="number">0.125</span>,<span class="number">0.25</span>,<span class="number">0.5</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="number">8</span>,<span class="number">16</span>]</span><br><span class="line">Yticks = np.arange(<span class="number">2</span>**np.trunc(np.log2(np.min(period))),<span class="number">2</span>**np.trunc(np.log2(np.max(period)))+<span class="number">1</span>,<span class="number">1</span>)</span><br><span class="line">f_ax2.contourf(time,np.log2(period),np.log2(power),np.log2(levels),extend=<span class="string">'both'</span>)</span><br><span class="line">f_ax2.set_xlabel(<span class="string">'Time (year)'</span>)</span><br><span class="line">f_ax2.set_ylabel(<span class="string">'Period (years)'</span>)</span><br><span class="line">f_ax2.set_title(<span class="string">'b) NINO3 SST Wavelet Power Spectrum'</span>)</span><br><span class="line">f_ax2.set_ylim(np.log2(np.max(period)),np.log2(np.min(period)))</span><br><span class="line">f_ax2.contour(time,np.log2(period),sig95,levels=[<span class="number">-99</span>,<span class="number">1</span>],colors =<span class="string">'k'</span>)</span><br><span class="line">f_ax2.plot(time,np.log2(coi),<span class="string">'k'</span>)</span><br><span class="line">f_ax2.set_yticks(np.log2(Yticks)[[<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">9</span>,<span class="number">14</span>,<span class="number">19</span>,<span class="number">29</span>,<span class="number">49</span>]])</span><br><span class="line">f_ax2.set_yticklabels(Yticks[[<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">9</span>,<span class="number">14</span>,<span class="number">19</span>,<span class="number">29</span>,<span class="number">49</span>]])</span><br><span class="line"><span class="comment">#全局功率谱</span></span><br><span class="line">f_ax3 = fig.add_axes([<span class="number">0.77</span>, <span class="number">0.37</span>, <span class="number">0.2</span>, <span class="number">0.28</span>])</span><br><span class="line">f_ax3.plot(global_ws,np.log2(period))</span><br><span class="line">f_ax3.plot(global_signif,np.log2(period),<span class="string">'--'</span>)</span><br><span class="line">f_ax3.set_xlabel(<span class="string">'Power (degC^2)'</span>)</span><br><span class="line">f_ax3.set_title(<span class="string">'c) Global Wavelet Spectrum'</span>)</span><br><span class="line">f_ax3.set_ylim(np.log2([np.max(period),np.min(period)]))</span><br><span class="line">f_ax3.set_yticks(np.log2(Yticks))</span><br><span class="line">f_ax3.set_yticklabels(<span class="string">''</span>)</span><br><span class="line">f_ax3.set_xlim(<span class="number">0</span>,<span class="number">1.25</span>*np.max(global_ws))</span><br><span class="line"><span class="comment">#局部功率谱</span></span><br><span class="line">f_ax4 = fig.add_axes([<span class="number">0.1</span>,<span class="number">0.07</span> ,<span class="number">0.65</span>, <span class="number">0.2</span>])</span><br><span class="line">f_ax4.plot(xlim,scaleavg_signif+np.array([<span class="number">0</span>,<span class="number">0</span>]),<span class="string">'--'</span>)</span><br><span class="line">f_ax4.plot(time,scale_avg)</span><br><span class="line">f_ax4.set_xlabel(<span class="string">'Time (year)'</span>)</span><br><span class="line">f_ax4.set_ylabel(<span class="string">'Avg variance (degC^2)'</span>)</span><br><span class="line">f_ax4.set_title(<span class="string">'d) 2-8 yr Scale-average Time Series'</span>)</span><br><span class="line"></span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p>输出图形如下:</p><p><img src="/image/wavelet.png" alt="image-20200527155848450"></p><p>测试数据下载:<a href="/image/sst_nino3.dat">sst_nino3.dat</a></p><p>作为一个数学基础很差的人,理解这些算法实在是太难了,我在编译的过程中很多东西完全是从最后的图形结果倒推算法每一步的含义。程序几乎是参考C. Torrence(1998)的matlab程序完成的。如果大家在程序运行过程中发现Bug请及时向我反馈,关于参数设置问题,还是不要来为难我了,很多东西我只是有个模糊的概念,很难具体解释出来。不过在翻译过程中还是发现python相对于matlab在有些地方还是很方便的,比如傅里叶转换和逆转换,以及卡方检验的实现等等。</p><p>最后感谢大家一直以来的的支持和关注。</p>]]></content>
<categories>
<category> Function </category>
</categories>
</entry>
<entry>
<title>Cartopy地图投影绘制</title>
<link href="/2020/09/09/map/"/>
<url>/2020/09/09/map/</url>
<content type="html"><![CDATA[<p>整理常用的地图投影绘制,包括源码及示例。</p><a id="more"></a><p>简单讲,matplotlib库创建的每个子图称为axes,axes是不具有地图投影性质的,也就是说axes绘制的图形是等距网格的形式,而我们需要绘制带有地图投影的图形时,就需要使用Cartopy库将axes变为具有地图投影性质的GeoAxes,而GeoAxes的网格则是经过地图投影缩放的。那本文主要展示如何将Axes变为不同地图投影的GeoAxes。</p><h2 id="一-、-转换基础,等经纬距离网格投影"><a href="#一-、-转换基础,等经纬距离网格投影" class="headerlink" title="一 、 转换基础,等经纬距离网格投影"></a>一 、 转换基础,等经纬距离网格投影</h2><p>本节介绍如何将Axes转换为GeoAxes,以及如何添加基础地理要素。</p><p>首先先给出代码示例:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><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">fig = plt.figure(figsize=[<span class="number">10</span>, <span class="number">5</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">ax1.set_xticks(np.arange(<span class="number">-180</span>,<span class="number">240</span>,<span class="number">60</span>), crs=ccrs.PlateCarree())</span><br><span class="line">ax1.set_yticks(np.arange(<span class="number">-90</span>,<span class="number">120</span>,<span class="number">30</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">ax1.gridlines() <span class="comment">#添加网格线</span></span><br><span class="line">ax1.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'110m'</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(central_longitude = <span class="number">120</span>))</span><br><span class="line">ax2.set_xticks(np.arange(<span class="number">-180</span>,<span class="number">240</span>,<span class="number">60</span>), crs=ccrs.PlateCarree())</span><br><span class="line">ax2.set_yticks(np.arange(<span class="number">-90</span>,<span class="number">120</span>,<span class="number">30</span>), crs=ccrs.PlateCarree())</span><br><span class="line">ax2.xaxis.set_major_formatter(cticker.LongitudeFormatter())<span class="comment">#设置经纬度刻度格式</span></span><br><span class="line">ax2.yaxis.set_major_formatter(cticker.LatitudeFormatter())</span><br><span class="line">ax2.gridlines() <span class="comment">#添加网格线</span></span><br><span class="line">ax2.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'110m'</span>))<span class="comment">#添加海岸线</span></span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p>首先通过fig = plt.figure(figsize=[10, 5])语句创建了画布</p><p>接着利用fig.add_subplot语句创建了一个axes,然而与之前不同的是,这里给出了一个projection参数</p><p>projection=ccrs.PlateCarree()参数的设置就使得axes转换成为了一个GeoAxes</p><p>PlateCarree投影是Cartopy库中的基本投影,即等经纬距离网格投影,通常绘制全球平面图时便使用此投影。</p><p>ccrs.PlateCarree中可以传递一个central_longitude参数,即为投影的中心经度,也就是图形中轴线的经度。</p><p><img src="/image/map1-1.png" alt="image-20200702161610554"></p><h2 id="二-、-兰伯特投影"><a href="#二-、-兰伯特投影" class="headerlink" title="二 、 兰伯特投影"></a>二 、 兰伯特投影</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><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">fig = plt.figure(figsize=[<span class="number">10</span>, <span class="number">5</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.LambertConformal())</span><br><span class="line">gl1 = ax1.gridlines(draw_labels=<span class="literal">True</span>,x_inline=<span class="literal">False</span>, y_inline=<span class="literal">False</span>) <span class="comment">#添加网格线</span></span><br><span class="line">gl1.rotate_labels = <span class="literal">False</span></span><br><span class="line">ax1.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'110m'</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.LambertConformal(central_longitude=<span class="number">120</span>,cutoff=<span class="number">0</span>))</span><br><span class="line">gl2 = ax2.gridlines(draw_labels=<span class="literal">True</span>,x_inline=<span class="literal">False</span>, y_inline=<span class="literal">False</span>) <span class="comment">#添加网格线</span></span><br><span class="line">gl2.rotate_labels = <span class="literal">False</span></span><br><span class="line">ax2.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'110m'</span>))</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p>兰伯特投影参数的设置除了central_longitude以外还有cutoff参数,意为截断纬度,即图形下边界纬度。</p><p><img src="/image/map1-2.png" alt="image-20200702161610554"></p><h2 id="三、麦卡托投影"><a href="#三、麦卡托投影" class="headerlink" title="三、麦卡托投影"></a>三、麦卡托投影</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><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">fig = plt.figure(figsize=[<span class="number">10</span>, <span class="number">5</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.Mercator())</span><br><span class="line">ax1.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'110m'</span>))</span><br><span class="line">gl1 = ax1.gridlines(draw_labels=<span class="literal">True</span>,x_inline=<span class="literal">False</span>, y_inline=<span class="literal">False</span>) <span class="comment">#添加网格线</span></span><br><span class="line">gl1.rotate_labels = <span class="literal">False</span></span><br><span class="line">gl1.xlabels_top = <span class="literal">False</span></span><br><span class="line">gl1.ylabels_right = <span class="literal">False</span></span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="/image/map1-3.png" alt="image-20200702161610554"></p><h2 id="四、-极地投影"><a href="#四、-极地投影" class="headerlink" title="四、 极地投影"></a>四、 极地投影</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><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">fig = plt.figure(figsize=[<span class="number">10</span>, <span class="number">5</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.NorthPolarStereo())</span><br><span class="line">ax1.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'110m'</span>))</span><br><span class="line">gl1 = ax1.gridlines(draw_labels=<span class="literal">True</span>,x_inline=<span class="literal">False</span>, y_inline=<span class="literal">True</span>) <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.SouthPolarStereo())</span><br><span class="line">ax2.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'110m'</span>))</span><br><span class="line">gl2 = ax2.gridlines(draw_labels=<span class="literal">True</span>,x_inline=<span class="literal">False</span>, y_inline=<span class="literal">True</span>) <span class="comment">#添加网格线</span></span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="/image/map1-4.png" alt="image-20200702161610554"></p><h2 id="五、-图形边界问题"><a href="#五、-图形边界问题" class="headerlink" title="五、 图形边界问题"></a>五、 图形边界问题</h2><p>前几节介绍了四种投影的设置,但是还有一个重要的问题没有解决:地图的范围设置</p><p>这里以极地投影为例:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> matplotlib.path <span class="keyword">as</span> mpath</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> numpy <span class="keyword">as</span> np</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">fig = plt.figure(figsize=[<span class="number">5</span>, <span class="number">5</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>, projection=ccrs.NorthPolarStereo())</span><br><span class="line">ax1.set_extent([<span class="number">-180</span>, <span class="number">180</span>, <span class="number">30</span>, <span class="number">90</span>], ccrs.PlateCarree())</span><br><span class="line">gl1 = ax1.gridlines(draw_labels=<span class="literal">True</span>,x_inline=<span class="literal">False</span>, y_inline=<span class="literal">False</span>) <span class="comment">#添加网格线</span></span><br><span class="line">gl1.rotate_labels = <span class="literal">False</span> <span class="comment">#关闭标签旋转,设置为True时标签与网格线平行</span></span><br><span class="line">ax1.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>))</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="/image/map1-5.png" alt="image-20200702161610554"></p><p>然而却发现设置了地图范围后的边界变回了正方形,这是由于地图边界设置是矩形造成的。解决办法是通过设置一个圆形路径的边框来对GeoAxes进行mask。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> matplotlib.path <span class="keyword">as</span> mpath</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> numpy <span class="keyword">as</span> np</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">fig = plt.figure(figsize=[<span class="number">5</span>, <span class="number">5</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>, projection=ccrs.NorthPolarStereo())</span><br><span class="line">ax1.set_extent([<span class="number">-180</span>, <span class="number">180</span>, <span class="number">30</span>, <span class="number">90</span>], ccrs.PlateCarree())</span><br><span class="line">gl1 = ax1.gridlines(draw_labels=<span class="literal">True</span>,x_inline=<span class="literal">False</span>, y_inline=<span class="literal">False</span>) <span class="comment">#添加网格线</span></span><br><span class="line">ax1.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>))</span><br><span class="line"><span class="comment"># 生成一个圆形的Path</span></span><br><span class="line">theta = np.linspace(<span class="number">0</span>, <span class="number">2</span>*np.pi, <span class="number">100</span>)</span><br><span class="line">center, radius = [<span class="number">0.5</span>, <span class="number">0.5</span>], <span class="number">0.5</span></span><br><span class="line">verts = np.vstack([np.sin(theta), np.cos(theta)]).T</span><br><span class="line">circle = mpath.Path(verts * radius + center)</span><br><span class="line"><span class="comment"># 将该Path设置为GeoAxes的边界</span></span><br><span class="line">ax1.set_boundary(circle, transform=ax1.transAxes)</span><br></pre></td></tr></table></figure><p><img src="/image/map1-6.png" alt="image-20200702161610554"></p>]]></content>
<categories>
<category> Other </category>
</categories>
<tags>
<tag> Python </tag>
<tag> Plot </tag>
</tags>
</entry>
<entry>
<title>带地图投影的散点图(站点分布图)</title>
<link href="/2020/09/09/scatter2/"/>
<url>/2020/09/09/scatter2/</url>
<content type="html"><![CDATA[<p>散点图另一种常用的形式往往要结合地图投影来实现,也就是站点数据分布图的绘制。</p><p>关于地图投影,请见<a href="/2020/09/09/map/">Cartopy地图投影绘制</a></p><p>比如在这里,绘制了中国825气象站站点的三维分布图(经纬度,颜色代表海拔高度)。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><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="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> cartopy.mpl.ticker <span class="keyword">as</span> cticker</span><br><span class="line"><span class="keyword">import</span> cartopy.io.shapereader <span class="keyword">as</span> shpreader</span><br><span class="line">data = pd.read_csv(<span class="string">"./825station.txt"</span>,sep=<span class="string">'\s+'</span>,header=<span class="literal">None</span>, names=[<span class="string">'stat'</span>,<span class="string">'lat'</span>,<span class="string">'lon'</span>,<span class="string">'high'</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>,projection = ccrs.PlateCarree(central_longitude=<span class="number">105</span>) )</span><br><span class="line"><span class="comment">#设置图形范围及刻度</span></span><br><span class="line">ax1.set_extent([<span class="number">70</span>,<span class="number">140</span>,<span class="number">0</span>,<span class="number">60</span>], crs=ccrs.PlateCarree())</span><br><span class="line">ax1.set_xticks(np.arange(<span class="number">70</span>,<span class="number">120</span>,<span class="number">10</span>), crs=ccrs.PlateCarree())</span><br><span class="line">ax1.set_yticks(np.arange(<span class="number">30</span>,<span class="number">70</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">s = ax1.scatter(data.lon,data.lat,s = <span class="number">5</span>,c = data.high,cmap=<span class="string">'jet'</span>,transform=ccrs.PlateCarree())</span><br><span class="line"><span class="comment">#添加色标,fraction参数设置色标缩放比例</span></span><br><span class="line">fig.colorbar(s,ax=ax1,fraction=<span class="number">0.034</span>)</span><br><span class="line"><span class="comment">#添加海岸线等特征</span></span><br><span class="line">ax1.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>))</span><br><span class="line">china = shpreader.Reader(<span class="string">'/data/home/zenggang/yxy/shp/bou2_4l.dbf'</span>).geometries()</span><br><span class="line">ax1.add_geometries(china, ccrs.PlateCarree(),facecolor=<span class="string">'none'</span>, edgecolor=<span class="string">'black'</span>,zorder = <span class="number">1</span>)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p>输出图形如下:</p><p><img src="/image/scatter2-1.png" alt="image-20200702161610554"></p>]]></content>
<categories>
<category> Plot </category>
</categories>
</entry>
<entry>
<title>简单散点图</title>
<link href="/2020/09/09/scatter1/"/>
<url>/2020/09/09/scatter1/</url>
<content type="html"><![CDATA[<p>首先给出一个最基本的散点图示例:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><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">x = np.random.randn(<span class="number">1000</span>)</span><br><span class="line">y = np.random.randn(<span class="number">1000</span>)</span><br><span class="line">fig, ax = plt.subplots()</span><br><span class="line">ax.scatter(x, y)</span><br></pre></td></tr></table></figure><p>输出结果如下:</p><p><img src="/image/scatter1-1.png" alt="image-20200702161610554"></p><p>对于气象应用来说,往往是多组数据的散点对比,同时每组数据都要给出不同的图例及maker样式(比如这里给出了五组数据,每组数据有五个值):</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><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">rng = np.random.RandomState(<span class="number">0</span>)</span><br><span class="line">markers = [<span class="string">'o'</span>,<span class="string">'+'</span>,<span class="string">'*'</span>,<span class="string">'s'</span>,<span class="string">'<'</span>]</span><br><span class="line">labels = [<span class="string">'CNRM‐CM3'</span>,<span class="string">'GFDL‐CM2.0'</span>,<span class="string">'GISS‐AOM'</span>,<span class="string">'MIROC3.2'</span>,<span class="string">'CCSM3'</span>,<span class="string">'MME'</span>]</span><br><span class="line"><span class="comment">#绘制散点图</span></span><br><span class="line">fig = plt.figure()</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"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">5</span>):</span><br><span class="line"> ax1.scatter(rng.rand(<span class="number">5</span>),rng.rand(<span class="number">5</span>),marker=markers[i],label=labels[i])</span><br><span class="line"> ax1.legend()</span><br></pre></td></tr></table></figure><p>输出图形如下:</p><p><img src="/image/scatter1-2.png" alt="image-20200702161610554"></p>]]></content>
<categories>
<category> Plot </category>
</categories>
</entry>
<entry>
<title>zhexian5</title>
<link href="/2020/09/03/zhexian5/"/>
<url>/2020/09/03/zhexian5/</url>
<content type="html"><![CDATA[<p>这类图同常用填色区间表示折线的误差(标准差)区间,或是用于鲜明地表现出两条折线的差异。</p><p>绘制填色区间的关键函数为:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Axes.fill_between(self, x, y1, y2, where=<span class="literal">None</span>, interpolate=<span class="literal">False</span>)</span><br></pre></td></tr></table></figure><p>主要参数为:</p><p>1 x,横坐标</p><p>2 y1,y2为两条折线</p><p>3 where 条件,比如说将y1小于y2的地方填色,则where=(y1<y2)</p><p>4 interpolate 是否进行插值填充(后有示例展示区别)</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><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> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line">x = np.arange(<span class="number">-5</span>, <span class="number">5</span>, <span class="number">0.5</span>)</span><br><span class="line">y1 = <span class="number">-5</span>*x*x + x + <span class="number">10</span></span><br><span class="line">y2 = <span class="number">5</span>*x*x + x</span><br><span class="line"></span><br><span class="line">fig = plt.figure(figsize=(<span class="number">15</span>,<span class="number">5</span>))</span><br><span class="line"></span><br><span class="line">ax1 = fig.add_subplot(<span class="number">1</span>,<span class="number">2</span>,<span class="number">1</span>)</span><br><span class="line">ax1.plot(x, y1, x, y2, color=<span class="string">'black'</span>)</span><br><span class="line">ax1.fill_between(x, y1, y2, where=(y2 > y1), facecolor=<span class="string">'red'</span>, alpha=<span class="number">0.5</span>)</span><br><span class="line">ax1.fill_between(x, y1, y2, where=(y2 <= y1), facecolor=<span class="string">'blue'</span>, alpha=<span class="number">0.5</span>)</span><br><span class="line">ax1.set_title(<span class="string">'interpolate = False'</span>)</span><br><span class="line"></span><br><span class="line">ax2 = fig.add_subplot(<span class="number">1</span>,<span class="number">2</span>,<span class="number">2</span>)</span><br><span class="line">ax2.plot(x, y1, x, y2, color=<span class="string">'black'</span>)</span><br><span class="line">ax2.fill_between(x, y1, y2, where=(y2 > y1), facecolor=<span class="string">'red'</span>, alpha=<span class="number">0.5</span>,interpolate=<span class="literal">True</span>)</span><br><span class="line">ax2.fill_between(x, y1, y2, where=(y2 <= y1), facecolor=<span class="string">'blue'</span>, alpha=<span class="number">0.5</span>,interpolate=<span class="literal">True</span>)</span><br><span class="line">ax2.set_title(<span class="string">'interpolate = True'</span>)</span><br><span class="line"></span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p>输出图形如下:</p><p><img src="/image/zhexian5-1.png" alt="image-20200702161610554"></p><p>其中,y1,y2也可以为常值。</p>]]></content>
<categories>
<category> Plot </category>
</categories>
</entry>
<entry>
<title>堆叠柱状图</title>
<link href="/2020/09/03/bar3/"/>
<url>/2020/09/03/bar3/</url>
<content type="html"><![CDATA[<p>(纵向)堆叠柱状图主要是用于横向对比累计分布。绘制方法如下:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><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>多变量柱状图</title>
<link href="/2020/09/03/bar2/"/>
<url>/2020/09/03/bar2/</url>
<content type="html"><![CDATA[<p>数据同样利用折线图示例中所使用的AO.txt</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><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>单变量柱状图</title>
<link href="/2020/09/03/bar1/"/>
<url>/2020/09/03/bar1/</url>
<content type="html"><![CDATA[<p>同样使用折线图示例中使用过的数据</p><p>最基础的柱状图绘制如下:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><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>zhexian4</title>
<link href="/2020/09/01/zhexian4/"/>
<url>/2020/09/01/zhexian4/</url>
<content type="html"><![CDATA[<p>非等比例坐标轴折线图主要是指将y轴换为对数坐标轴或是其他格式。对于对数坐标轴来说,matplotlib提供了两种格式可供选择,分别是”symlog”以及”log”,就使用感觉而言,个人认为”symlog”更加方便(主要是坐标刻度ticklabels的设置更加方便)。</p><p>下图的绘制没有任何实际物理意义,仅供参考。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><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> 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="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="keyword">import</span> matplotlib.ticker <span class="keyword">as</span> ticker</span><br><span class="line"><span class="comment">#读取数据</span></span><br><span class="line">f = xr.open_dataset(<span class="string">'./data.nc'</span>)</span><br><span class="line">t = f[<span class="string">'air'</span>].loc[<span class="string">'2005-07-01'</span>,:,<span class="number">45</span>,<span class="number">120</span>]</span><br><span class="line">lev = t.level</span><br><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">5</span>))</span><br><span class="line"><span class="comment">#log</span></span><br><span class="line">ax1 = fig.add_subplot(<span class="number">1</span>,<span class="number">3</span>,<span class="number">1</span>)</span><br><span class="line">ax1.plot(t,lev)</span><br><span class="line">ax1.set_ylim(<span class="number">1000</span>,<span class="number">100</span>)</span><br><span class="line">ax1.set_yscale(<span class="string">'log'</span>)</span><br><span class="line">ax1.set_title(<span class="string">'log'</span>)</span><br><span class="line">ax1.set_yticks([<span class="number">1000</span>,<span class="number">850</span>,<span class="number">700</span>,<span class="number">500</span>,<span class="number">300</span>,<span class="number">200</span>,<span class="number">100</span>])</span><br><span class="line">ax1.set_yticklabels([<span class="number">1000</span>,<span class="number">850</span>,<span class="number">700</span>,<span class="number">500</span>,<span class="number">300</span>,<span class="number">200</span>,<span class="number">100</span>])</span><br><span class="line"><span class="comment">#隐藏掉次刻度,可以尝试注释下边这句代码会有怎样的效果?</span></span><br><span class="line">ax1.yaxis.set_minor_formatter(ticker.NullFormatter())</span><br><span class="line"><span class="comment">#symlog</span></span><br><span class="line">ax2 = fig.add_subplot(<span class="number">1</span>,<span class="number">3</span>,<span class="number">2</span>)</span><br><span class="line">ax2.plot(t,lev)</span><br><span class="line">ax2.set_ylim(<span class="number">1000</span>,<span class="number">100</span>)</span><br><span class="line">ax2.set_yscale(<span class="string">'symlog'</span>)</span><br><span class="line">ax2.set_title(<span class="string">'symlog'</span>)</span><br><span class="line">ax2.set_yticks([<span class="number">1000</span>,<span class="number">850</span>,<span class="number">700</span>,<span class="number">500</span>,<span class="number">300</span>,<span class="number">200</span>,<span class="number">100</span>])</span><br><span class="line">ax2.set_yticklabels([<span class="number">1000</span>,<span class="number">850</span>,<span class="number">700</span>,<span class="number">500</span>,<span class="number">300</span>,<span class="number">200</span>,<span class="number">100</span>])</span><br><span class="line"><span class="comment">#linear</span></span><br><span class="line">ax3 = fig.add_subplot(<span class="number">1</span>,<span class="number">3</span>,<span class="number">3</span>)</span><br><span class="line">ax3.plot(t,lev)</span><br><span class="line">ax3.invert_yaxis()</span><br><span class="line">ax3.set_yscale(<span class="string">'linear'</span>)</span><br><span class="line">ax3.set_title(<span class="string">'linear'</span>)</span><br><span class="line">ax3.set_yticks([<span class="number">1000</span>,<span class="number">850</span>,<span class="number">700</span>,<span class="number">500</span>,<span class="number">300</span>,<span class="number">200</span>,<span class="number">100</span>])</span><br><span class="line">ax3.set_yticklabels([<span class="number">1000</span>,<span class="number">850</span>,<span class="number">700</span>,<span class="number">500</span>,<span class="number">300</span>,<span class="number">200</span>,<span class="number">100</span>])</span><br></pre></td></tr></table></figure><p>输出图形如下:</p><p><img src="/image/zhexian4-1.png" alt="image-20200702161610554"></p>]]></content>
<categories>
<category> Plot </category>
</categories>
</entry>
<entry>
<title>多y轴折线图</title>
<link href="/2020/09/01/zhexian3/"/>
<url>/2020/09/01/zhexian3/</url>
<content type="html"><![CDATA[<p>多y轴折线图只具有3条甚至更多不同区间的y轴的折线图,不同于双y轴的绘制方法,多y轴绘制的要点在于创建多条依赖于同一axes的寄生轴。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> mpl_toolkits.axisartist.parasite_axes <span class="keyword">import</span> HostAxes, ParasiteAxes</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> numpy <span class="keyword">as</span> np</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">ao_djf = (ao_jan.AO.values+ao_feb.AO.values+ao_dec.AO.values)/<span class="number">3</span></span><br><span class="line"><span class="comment">#创建Figure</span></span><br><span class="line">fig = plt.figure() </span><br><span class="line"><span class="comment">#创建主轴</span></span><br><span class="line">ax = HostAxes(fig, [<span class="number">0</span>, <span class="number">0</span>, <span class="number">0.9</span>, <span class="number">0.9</span>]) <span class="comment">#[left, bottom, weight, height]</span></span><br><span class="line"><span class="comment">#创建共享x轴的其他y轴</span></span><br><span class="line">ax1 = ParasiteAxes(ax, sharex=ax)</span><br><span class="line">ax2 = ParasiteAxes(ax, sharex=ax)</span><br><span class="line">ax3 = ParasiteAxes(ax, sharex=ax)</span><br><span class="line">ax.parasites.append(ax1)</span><br><span class="line">ax.parasites.append(ax2)</span><br><span class="line">ax.parasites.append(ax3)</span><br><span class="line"><span class="comment">#将主轴的右轴隐藏,同时开始第二根轴的可见性</span></span><br><span class="line">ax.axis[<span class="string">'right'</span>].set_visible(<span class="literal">False</span>)</span><br><span class="line">ax1.axis[<span class="string">'right'</span>].set_visible(<span class="literal">True</span>)</span><br><span class="line">ax1.axis[<span class="string">'right'</span>].major_ticklabels.set_visible(<span class="literal">True</span>)</span><br><span class="line">ax1.axis[<span class="string">'right'</span>].label.set_visible(<span class="literal">True</span>)</span><br><span class="line"><span class="comment">#设置各轴标签</span></span><br><span class="line">ax.set_ylabel(<span class="string">'DJF'</span>)</span><br><span class="line">ax.set_xlabel(<span class="string">'year'</span>)</span><br><span class="line">ax1.set_ylabel(<span class="string">'Dec'</span>)</span><br><span class="line">ax2.set_ylabel(<span class="string">'Jan'</span>)</span><br><span class="line">ax3.set_ylabel(<span class="string">'Feb'</span>)</span><br><span class="line"><span class="comment">#设置第三根和第四根y轴的位置</span></span><br><span class="line">axisline2 = ax2.get_grid_helper().new_fixed_axis</span><br><span class="line">axisline3 = ax3.get_grid_helper().new_fixed_axis</span><br><span class="line">ax2.axis[<span class="string">'right2'</span>] = axisline2(loc=<span class="string">'right'</span>, axes=ax2, offset=(<span class="number">40</span>,<span class="number">0</span>))</span><br><span class="line">ax3.axis[<span class="string">'right3'</span>] = axisline3(loc=<span class="string">'right'</span>, axes=ax3, offset=(<span class="number">80</span>,<span class="number">0</span>))</span><br><span class="line"><span class="comment">#将设置好的主轴的Axes放在Figure上</span></span><br><span class="line">fig.add_axes(ax)</span><br><span class="line"><span class="comment">#绘制折线</span></span><br><span class="line">ax.plot(np.arange(<span class="number">1950</span>,<span class="number">2020</span>,<span class="number">1</span>), ao_djf, label=<span class="string">"DJF"</span>, color=<span class="string">'black'</span>)</span><br><span class="line">ax1.plot(np.arange(<span class="number">1950</span>,<span class="number">2020</span>,<span class="number">1</span>), ao_dec.AO, label=<span class="string">"Dec"</span>, color=<span class="string">'red'</span>)</span><br><span class="line">ax2.plot(np.arange(<span class="number">1950</span>,<span class="number">2020</span>,<span class="number">1</span>), ao_jan.AO, label=<span class="string">"Jan"</span>, color=<span class="string">'green'</span>)</span><br><span class="line">ax3.plot(np.arange(<span class="number">1950</span>,<span class="number">2020</span>,<span class="number">1</span>), ao_feb.AO, label=<span class="string">"Feb"</span>, color=<span class="string">'orange'</span>)</span><br><span class="line">ax2.set_ylim(<span class="number">-4</span>,<span class="number">4</span>)</span><br><span class="line">ax3.set_ylim(<span class="number">-5</span>,<span class="number">5</span>)</span><br><span class="line">ax4.set_ylim(<span class="number">-6</span>,<span class="number">6</span>)</span><br><span class="line">ax.legend()</span><br><span class="line"><span class="comment">#设置各个轴及其刻度的颜色</span></span><br><span class="line">ax1.axis[<span class="string">'right'</span>].major_ticks.set_color(<span class="string">'red'</span>)</span><br><span class="line">ax2.axis[<span class="string">'right2'</span>].major_ticks.set_color(<span class="string">'green'</span>)</span><br><span class="line">ax3.axis[<span class="string">'right3'</span>].major_ticks.set_color(<span class="string">'blue'</span>)</span><br><span class="line">ax1.axis[<span class="string">'right'</span>].major_ticklabels.set_color(<span class="string">'red'</span>)</span><br><span class="line">ax2.axis[<span class="string">'right2'</span>].major_ticklabels.set_color(<span class="string">'green'</span>)</span><br><span class="line">ax3.axis[<span class="string">'right3'</span>].major_ticklabels.set_color(<span class="string">'blue'</span>)</span><br><span class="line">ax1.axis[<span class="string">'right'</span>].line.set_color(<span class="string">'red'</span>)</span><br><span class="line">ax2.axis[<span class="string">'right2'</span>].line.set_color(<span class="string">'green'</span>)</span><br><span class="line">ax3.axis[<span class="string">'right3'</span>].line.set_color(<span class="string">'blue'</span>)</span><br></pre></td></tr></table></figure><p>输出图形如下:</p><p><img src="/image/zhexian3-1.png" alt="image-20200702161610554"></p><p>测试数据下载地址:<a href="/image/AO.txt">点此下载</a></p>]]></content>
<categories>
<category> Plot </category>
</categories>
</entry>
<entry>
<title>双y轴折线图</title>
<link href="/2020/09/01/zhexian2/"/>
<url>/2020/09/01/zhexian2/</url>
<content type="html"><![CDATA[<p>绘制双y轴折线图的要点在于将y轴的右轴变为一个兄弟轴(twin axis)</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><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> numpy <span class="keyword">as</span> np</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">ao_feb = ao[ao.month==<span class="number">2</span>]</span><br><span class="line"><span class="comment">#创建Figure</span></span><br><span class="line">fig = plt.figure()</span><br><span class="line"><span class="comment">#绘制单y轴折线图</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.plot(np.arange(<span class="number">1950</span>,<span class="number">2020</span>,<span class="number">1</span>),ao_jan.AO,<span class="string">'ko-'</span>,label=<span class="string">'Jan'</span>)</span><br><span class="line">ax1.set_ylabel(<span class="string">'January'</span>,c=<span class="string">'r'</span>)</span><br><span class="line">ax1.set_title(<span class="string">'1950-2019 AO Index'</span>)</span><br><span class="line"><span class="comment">#创建第二根y轴</span></span><br><span class="line">ax2 = ax1.twinx() </span><br><span class="line">ax2.plot(np.arange(<span class="number">1950</span>,<span class="number">2020</span>,<span class="number">1</span>),ao_feb.AO,<span class="string">'rs-'</span>,label=<span class="string">'Feb'</span>)</span><br><span class="line">ax2.set_ylim(<span class="number">-4</span>,<span class="number">4</span>)</span><br><span class="line">ax2.set_ylabel(<span class="string">'February'</span>,c=<span class="string">'k'</span>)</span><br></pre></td></tr></table></figure><p>输出图形如下:</p><p><img src="/image/zhexian2-1.png" alt="image-20200702161610554"></p><p>测试数据下载地址:<a href="/image/AO.txt">点此下载</a></p>]]></content>
<categories>
<category> Plot </category>
</categories>
</entry>
<entry>
<title>基本折线图(单变量,多变量)</title>
<link href="/2020/09/01/zhexian1/"/>
<url>/2020/09/01/zhexian1/</url>
<content type="html"><![CDATA[<p>一、单变量折线图</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><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</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"><span class="comment">#创建Axes</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"><span class="comment">#绘制折线图</span></span><br><span class="line">ax1.plot(np.arange(<span class="number">1950</span>,<span class="number">2020</span>,<span class="number">1</span>),ao_jan.AO, <span class="string">'ko-'</span>)</span><br><span class="line"><span class="comment">#添加图题</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">#添加y=0值水平参考线</span></span><br><span class="line">ax1.axhline(<span class="number">0</span>,ls=<span class="string">':'</span>,c=<span class="string">'r'</span>)</span><br><span class="line"><span class="comment">#添加x=1990垂直参考线</span></span><br><span class="line">ax1.axvline(<span class="number">1990</span>,ls=<span class="string">'--'</span>,c=<span class="string">'g'</span>)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p>输出图形如下:</p><p><img src="/image/zhexian1-1.png" alt="image-20200702161610554"></p><p>其中数据格式如下:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">print(ao)</span><br><span class="line"> year month AO</span><br><span class="line"><span class="number">0</span> <span class="number">1950</span> <span class="number">1</span> <span class="number">-0.060310</span></span><br><span class="line"><span class="number">1</span> <span class="number">1950</span> <span class="number">2</span> <span class="number">0.626810</span></span><br><span class="line"><span class="number">2</span> <span class="number">1950</span> <span class="number">3</span> <span class="number">-0.008128</span></span><br><span class="line"><span class="number">3</span> <span class="number">1950</span> <span class="number">4</span> <span class="number">0.555100</span></span><br><span class="line"><span class="number">4</span> <span class="number">1950</span> <span class="number">5</span> <span class="number">0.071577</span></span><br><span class="line">.. ... ... ...</span><br><span class="line"><span class="number">835</span> <span class="number">2019</span> <span class="number">8</span> <span class="number">-0.721770</span></span><br><span class="line"><span class="number">836</span> <span class="number">2019</span> <span class="number">9</span> <span class="number">0.306200</span></span><br><span class="line"><span class="number">837</span> <span class="number">2019</span> <span class="number">10</span> <span class="number">-0.082195</span></span><br><span class="line"><span class="number">838</span> <span class="number">2019</span> <span class="number">11</span> <span class="number">-1.193400</span></span><br><span class="line"><span class="number">839</span> <span class="number">2019</span> <span class="number">12</span> <span class="number">0.412070</span></span><br><span class="line"></span><br><span class="line">[<span class="number">840</span> rows x <span class="number">3</span> columns]</span><br></pre></td></tr></table></figure><p>二、多变量折线图</p><p>实际上只是在同一个axes下叠加多个axes.plot()图层</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><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="keyword">import</span> numpy <span class="keyword">as</span> np</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">ao_feb = ao[ao.month==<span class="number">2</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.plot(np.arange(<span class="number">1950</span>,<span class="number">2020</span>,<span class="number">1</span>),ao_jan.AO,<span class="string">'ko-'</span>,label=<span class="string">'Jan'</span>)</span><br><span class="line">ax1.plot(np.arange(<span class="number">1950</span>,<span class="number">2020</span>,<span class="number">1</span>),ao_feb.AO,<span class="string">'rs-'</span>,label=<span class="string">'Feb'</span>)</span><br><span class="line">ax1.set_title(<span class="string">'1950-2019 AO Index'</span>)</span><br><span class="line">ax1.legend()</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="/image/zhexian1-2.png" alt="image-20200702161610554"></p><p>测试数据下载地址:<a href="/image/AO.txt">点此下载</a></p>]]></content>
<categories>
<category> Plot </category>
</categories>
</entry>
<entry>
<title>经纬度-时间分布图</title>
<link href="/2020/07/02/lat-time-lev/"/>
<url>/2020/07/02/lat-time-lev/</url>
<content type="html"><![CDATA[<p>气象绘图中,等值线图包含很多种类,其中一种就是以经纬度,和时间或者高度为xy轴的等值线分布图。其与普通等值线图的区别主要体现在xy轴格式不统一上。以纬度-时间分布图为例,分享绘制这类图形的方法:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><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> 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="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="comment">#读取数据</span></span><br><span class="line">f = xr.open_dataset(<span class="string">'./data.nc'</span>)</span><br><span class="line">z = f[<span class="string">'hgt'</span>].loc[<span class="string">'2005-01-01'</span>:<span class="string">'2005-12-01'</span>,<span class="number">500</span>,:,<span class="number">120</span>]</span><br><span class="line">time = z.time</span><br><span class="line">lat = z.lat</span><br><span class="line"><span class="comment">#创建Figure</span></span><br><span class="line">fig = plt.figure(figsize=(<span class="number">16</span>, <span class="number">13</span>))</span><br><span class="line"><span class="comment">#绘制500hPa位势高度场</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"><span class="comment">#绘制等值线</span></span><br><span class="line">q1 = ax1.contour(range(time.shape[<span class="number">0</span>]), lat, z.T)</span><br><span class="line"><span class="comment">#设置y轴为对数轴,并设置相关标签</span></span><br><span class="line">ax1.set_xticks(np.arange(<span class="number">0</span>,<span class="number">12</span>,<span class="number">1</span>))</span><br><span class="line">ax1.set_yticks(np.arange(<span class="number">-90</span>,<span class="number">120</span>,<span class="number">30</span>))</span><br><span class="line">ax1.yaxis.set_major_formatter(cticker.LatitudeFormatter())</span><br><span class="line"><span class="comment">#设置x轴标签</span></span><br><span class="line">ax1.set_xlim(<span class="number">0</span>,<span class="number">11</span>)</span><br><span class="line">ax1.set_xticks(np.arange(<span class="number">0</span>,<span class="number">12</span>,<span class="number">1</span>))</span><br><span class="line">ax1.set_xticklabels(pd.date_range(start=<span class="string">'2005-01'</span>,periods=<span class="number">12</span>,freq=<span class="string">'M'</span>).date )</span><br><span class="line"><span class="comment">#添加图题</span></span><br><span class="line">ax1.set_title(<span class="string">'2005 500hPa Z'</span>,loc=<span class="string">'center'</span>,fontsize=<span class="number">18</span>)</span><br></pre></td></tr></table></figure><p>输出图形如下:</p><p><img src="/image/image-20200702161610554.png" alt="image-20200702161610554"></p><p>其中z数组代表2005年逐月120°E经线上500hPa位势高度场演变(只做示例,不考虑绘图意义)</p>]]></content>
<categories>
<category> Plot </category>
</categories>
</entry>
<entry>
<title>(Random Forest,RF)随机森林模型</title>
<link href="/2020/06/10/randomforest/"/>
<url>/2020/06/10/randomforest/</url>
<content type="html"><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="抱歉, 这个密码看着不太对, 请再试试." data-whm="抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容."> <script id="hbeData" type="hbeData" data-hmacdigest="bb7e1fd36c55faf010b1662ef39ad00206ca7650c4ffef539d822afdf7c96ce0">9ef3cfcf76ea6195548d1a8d168c54c8e021c424d45b8d415d3eb7ddad8f28e36301d3bee5fcf8514f56513c2320b62b2244676801855fd6238b0e0ba1de7f605dd57217c1beee5903ca9ce5e0cda578ee98c388b597a9579c369a43c44dfdfa72ae7809b84d1f22afc6c105ffedd126d61e9c86c615591a9f18db9c22e4130dbf3dc35f0eb07d0810d6c8727b442fb94d67b630e1ec65e6df3b47fa9507fbac8c1558ae2b452188afd18da7451db7451cb45606f3943eac8ef0122fef67153a50f0885387739635572ff7c2cd0867c0636fb4f9352a16e517c5ba7d3da49a6aadbca330ba87a80cb25f6a64e5b74541c3527300d0f90badde9fcd6e702e5adef77c6f7cbeb4ea3358e2eb37e75c005cd05c0157ee7f1963ebd239aae62487d0ef2828c6d51bbcef6f6479ab62b60b6b5968e03777fa90d387001811277a57d1cb11c1d986b65f5389e37e9aa695078ddfb30488543017dca6239889096d64ae2ca2d852cfef40bd65011e3f30e6638366899cacf51e1120efa634dd753726ab63685c1b46e7f98bd532d7f56390fb471034f0de45349be8ac3ac07f6f2cc364e394f182a073b5803407d09a317f2b7280a397e51eb0f492a0096f29925f80c952c4874ea605f69e872a8c5432c43e78b030cf6e5d641594a1008b990296aa225c6725f2ca994ce27d5b6a9789e9f17163668840744bda7d297e48aa70b8e3fd208f83180fb10c2bb3e8389e5dc2587a5a0fc5d83860ec033ff5b86c9e20e2f9c8034cfca96750b35c2e7bfc6caf5b6111e5443eed354673e9a9b7f26a0453896239ef790c1fc04f23dd43c2542f05580ec54f7aa7bacea71ccd8c4946c7e51f35641a6e2f66b2a61ad4eb8c097a062825846ff55c690171a80a4aa6b349a3e9f4c7abd8723281cfdde4468d2b716112f0ebdbe2d2a1d3c4183162b918169d66f9a9b8789091ab463f0e4bce2244239fee3d281c0d116adda0867f9edd9f3324e1d483ba207c853aaa08798d052e8f785125152a06115591fd485101e36db71e491ada9596d5ef336ea5176d332780f824e99853ed5c2cf49caed4faea54a91bfff6db3bf01a31b3635bea0410edfdbf7a45df60fefbd8ae591f9494b3402bd8748e385aad1f74434f7e5eecf2d19ed95b21bd711248f1fe082ba39d67a2cd359622168dea2a629f63ca0b1475bb9723ef2ab97c2e7718ab3dfffd202350d298811047501935cbb46118b84df7e3cacb2b0e118ea90b018cde6f95ac47bb84c35877dfe870546a79d6674ff363ab28b7a6b8d65558bf72888cb9d8d04f030c51a9b67590ce38493a0b4d5df01df78268bba57b9c5cece874bf5ac50751a80ee05df16e7380944e17ecadd9a0fafa416bb18742164a7de1563f009e7228a86d781d0c8b047d264fa2ee1b3c12808b2341b2b1776b44f6934ae2e206a06552d77c003415907d1f66511b85adf7c2feba3c2fd15416220cf96f83e93e2ab3297d823768aa3ab10b676fbad78940058615800f5d47c3913de3a88843cc982eeccab62234fa78859c09ebfa2b99d004b74c3cf7e9ff0cc37c42afde470f923fc4aee198e6b23ecacbc23d18cdf6b57ef021cf4654f7c442f84676ae0a9581a51c19f5646462dcb74223d536b12a96651c4fcbfb1b308da9152ccc719c874082baae5ce9b11e32157042d7f923e63ab1f8329bc1868e3850b0d5e3ddb1c22e311f7e8a995ba2f73444265c605c27265f7b9edee7bf7635b0aa55d6172adf1be2bf79579501edbeb35ea60a60dce90b54b6d37ef5a1d95d4f244f680019d0185e94a127eae0b077b891a7ca75bdf5d055f581615619dc3bcf53f2d9bb1d66284c74ecd3b2960225d95250d598d11e75f92b7b342971a4406147738b20c785236eefcd7b00b03b662d894c4adc659c6e03d4cbab9b42f34eb364c4372ae9413b999b75eadb3cf44745940113f1d83d215a7ccf89ca56400c11d757734a55996c651d1131287803ea2a0f4299b8480552c3407486e79267006c6db6a295831e305900c83ad47534490dcfc13a1f0d9d89d04e4d66b1f3bc7f34693a5b00ebd10ebedd3676dbdba18528a161895caf1e3400fc919d83e7f097e97afd8df78c1418ba7277a78f623ae7d89ebcefd9c8a0542a14b0e9719a0e5d833276dea46357111f9f244e65d4376a0ef0d3b15fd5ff0c5cc0c9371c9cdd7c0a59c97197fd81d018f84f52b986f5dd67178a37dad83b4f2de387bfe98328b2e0bd7aa17a08647298800ab545d46240db00bc165d7d101eb7239bd26a707fb50bbf1d7c231d0ae95e305841736e7e2403b02275608b3e0b660b5661cd67172f5cfbd894d5033ac06ec9ed5fd9de14e66e105a05ee1903e99155d6abcd2ef454617e576f607112f398f414bec7c973e46719697c6cb3cffe179aafce565d4cd6a3989cd68bdabb035544e5e7ec9874432edc054b5d74472ca7f7255a292a4ed02a601091369d9765a6f6598ebfd57887f50d983dc3b52af355ceb24d7d3b1286e2a0c8a03d86a06ec0a6ac9a360c9e267ad0c258d342136823c6cd50f1e597dac1f8d15ef27fd098a2e9c22b49ed5d849ef5a23775b166f8ee77d5587beec53b6837d57915287f7f08f472d1574c2dfbd02212abde73186bead64224fd4b53ce88021bc0ad37fda32a416275beef46421f7d593aefecdead2610fb28e2642c5236422547408977a2652676f199b91b67b85cd094871be120309fc6172ffced8dc9f50dcaf4f41291e647b4228c47b69e75de1e47d0bc9b7244ba690bc3c369fabb36d58ec7b0213bb037264cdbb2471fcc1cb33fa10ebc3c95946dbb4572eefd5a7e60787e77a0a9016fd82225474da2b7865d87642844fed70f416c6974e677165b4f4522f67e8c73564807f9ff774fe30c1c70f4fe66752f1f7990a762de308b61ff0e50f90dea7f71928c6523670279eb287e02637834a9d0046d3ee35e1b65e102105b97cb415d002fae54bde8140cc4926415c67c92a0ee7a6cd64c48fb80968476d0820be3c214fb872106933598af46d5466ca825d112a63de50ebbd8ffcea5d75a750d1ebf6e90eb1314a77c75c9ad965859c7112d5023b905a77a29e5ea532c6c52ff6431e534f856f83eb6f1ebb20fe9339a9390ef8038f124f6db2776cbd76b79d1141b7e5dcc36f114b5d27fff725943e8d18658b72b76d7f20aa562fa91ac752d4c1f64869933e18bf52f7197cb39ac48c0633e0c054708d4b944de9e3c100f3ac6183eb4ac0ec88cdf73f4d18fc38ba6b3ef95c026de527ab5e53b578787f46320529014f979eca3b3213b406ad160261ebe30835a977a9599739e640095442e3f9c5cd75b27d944a528d8f2cd4ea1b159e09eb5b54a79a908f35df027c02a1adde5c153dc5ad983c799a859602a57e49b1a2f6eb76f36a0a6f221c3b6e8901a004b67df42dce261ab6b3755dd18cbc2de71789459b699f06237e92768cd7b8b48d680ec4810c71d320aa1a36905dedd6c3958fa5b65b955e1a55a2443962b528e1862fdf03c250bce36679750c461b8c2cc8d58b3e3198a9aeb449e3d19debf59c6e0d3139aeb36ec3afccecc6bc512520a4668f110264708ce1141d4667982b7f11f7d1d02e6a3665f35e5e583c2b4c27a8b13485aab67023981bdf998a90fe3113284ba032bc62f14aad25b742be52713f7b48b2eecc65a96849680d3daae4b58289322f2b731d26f99eecc1c006d5a8530c17c629eba4d22d237c53661e9728f7b94a60e939cc8ffb88e339fd7b77fffd4a4b311dea75026c166df8292e3195332707618274e1a08275d1e05b1098819e70b1b50b43df5fafbf307e5f08dde946c667f4b567fcb913e47a00ef495a9ade40e5272b426deb3e0710c2df6ce23a6629c6afba64e29e6fc1753d5e4ec7192512eacd993869214a06b22b487e25a238fffcf1a03d1a891cffd09b5f8f537b5e14185e4cfaafb5e11844c96875851e5e5f4f1dade9cea884db878ba6d0044c2bfc5cd2f99cb43e9955c84441473a8bf2888023127faf814686d0ea824b17beba060f240e3142fd0e40ce93f196ecacc689ed0df32acf7eb5a00c7849ff25b20185ace02954430fa5ecc16129c5676446d0adf41081d049357fd379fa133f5b199318c8f764cd35f1cc81ac97d739c1026e48892ef2e005ece4deb180ec81cec1f146adc9fff8b88a9d8a0965307df16305dc117e153ecd076236561e8ee8746232172129824cb89b7eabc94623e14bd1661fa4bee99820b32a529de2c49b390db3861a7b2a3207893b95c8749bce84564bd28eb2bb790ebb4456f1e9a3a8dcfc7e795e3aafb0f4b1904b4577f82ac3ba33b6310e9873e31a06c1c685036f1c9a88696d47ef1358ae354dcfc109181cd93c5f592df81814b9a8aa03e8b7c9bbd4d57a4d3d4c9fa388f75d18d29e3a21c4dc7ded2ef1dd4da4238e3b6d20b1529aa1767ce07c74db5d7423f7b45f2e30d57f38af0b31033e4454eb8f7b5a85c20b2131f7fee6411365af8c7509a699d0db2656b02e2b3cc5aa46a892cbfe40622b48ce7a792cb366a187616f8acbf3c239cb17db8e2b1d9cce9968f54ebb42d19762d35c18aa8eeb9827d45411f0276793af6a43dd0b1a2db5a51f3f5acc7bf4761ad9936e52285204f3240e602ddc669e2753e0b724ba8074bd3b036b8aeadb294c3288a45e64308cb5506d9d9c6f118755ea64ab2d5f47225a32394a8cfc44763cbb5b49c56fffc9485274015f83a702b279c08c14280c470ce91f016d51b52f0d3e21f31db6cbee8eb2d7fca9b9965e3314aa9b953276b9d62335d3a8df8e8ad1f6e420501036ef2ef88e57945473ded4f5990cc374b993036624e39cdf250c78acab84abf37029e79ae09a21295ed79eefbdfa0c8a2bbd3fbea1f8edfee944d23679739c94c976780f6fc9cc6c3f1eb2ed64ac9be7e88f8d26ac136b28389598c76a33fb25112e2da5f2f11f823b28b0aa40963233da0ec06ea3116df048f120fa27c2f64eb55fe3d1da489b5efc82a5983677b6c25ec2ba1658c926fe8fa4239a9978e14b9340ef9ade5866789df887e7cc788282ab33b70c882a652f1161a02d5b8d046994b7af1428d817947fcaa105646216100f5bdc28b5efb1d0e19f4bc1a9daa1bec4eb8cb9d25563a1b009b6261c3fa0e5020b3990f795f495cadc30a9d96b5efb51b4f29d4483719db811dcc7bbd044f970ac14d99c8593dffcf390d67b94ef5f94ca0682ead93264b6e907797f925118ba008a7fcf2e8ec6bbed230712da04355d221493cbc6859f4ca91803d9697e9073dccd34b311904e7ede4eaf73256b19879b0db0131e964e2b07339d038542bcf37209e33f8522605c5c13aa0e2982a2d90a9aa20358e5e00ba917869a8273220655435a752d226d3b25a2393eed644ca9fea4e0d819604d67fa3fc5ad85217f4a96f5921b7c5e8bdc99cb6a08d7ff6522f26e04a3a13daa7d21acef269709a2382f8b724d50ecb1866db6d76d5f06f45c807c9b70facc56015957986ad05220c13fff3b61a71fcaf9d7dac532451622c4066e9a4b64bcc10e8fccf2c9cbe108c53cafa7d418c00658f2718b411782d243e2b10ba008f3a4263f1884d81a2ed1ec00efef722517acb95e49ece2b4d4490890355deb531074cc03c37f1f6e5375f5bcaaf9e3f59a395de3f8ca33426a9d4f6a6d2d40fccf62049b3751b672412a39aab2f79dc559a7110a48598934af2f8ca9b71e3fc76dd889a78f850f4ce8b873d1304efd0eae76a770ba5a99326706a8f525851eb02a492aee86015293f6e502586fe46889f4e93e9233303130926477790e558c70a39633eebe85a6da2c51e88be3837e22e2c37396a11e9c62ca2736a341650ee8dd99fea6a5ae8eeabc80a7cf4a0de0166430742c11fced5ab2203fddd09e9053fded9fabf691397dda4cfbe827e1a76c466261f1a770517e662494d29a76da619516a737064238e9d38e2065733bcf1959cff0e3aa9899c7f0b9758067926845584cb79ada86929095422fde76bf4919a868d1e9cc7a0b7b339d4566c0c06d96277657faae66b1ffe66c65f1f6e062148b04858652a1b7cc39f790af0355fe82f791d85bafb42f590b0b3f7dc2bf9a109481d76675be489391e54487bb8750a47e729bdc7a48430b000709a57c100cf6f4dc31bfb1d0b01d9ffdd27625226c3933baa7eeaa3f4b8be9b439b35592a908eeafcc97e2cb89a6b9d45804e0003f6c23aa3b5d20187e2782745c682167017f40ac7e2adccd59d61a39fad44113dbbd15f96cac2733f0dbb8bf5f57188728b217675ec7a431dda6e2e3065791c2c927c48426b4d4ac8a2e14ff139728eab791751bfde6c20724f0e270dcc67c0132334d9cbd110819d3381df6c29af3009db53354577f4b77fcadc70fcca748a3f9cb70de8ef6e9348d2168930074e704f02c0738feedab9ef08b4dbe1141030518cf2b50a81882eb12eb3f67d073b819a12eed90f1c4533c1c01a107314ab17525af12efc9b21595b262821a8cb381268cdcdf838fdd286bc63ad5ea0cefbf2c3ba70c1521ca06f649527c59efa60013d018664d91567baceea9edb8a7794ab6d50e6fbf4851c178f3f7c6f935ad51880a9c2070b4f387fbab5936a954303d47eb77a9c5e573aeb0705a87e4c4770d174329a642339270c16601f07a76302002c53c9f8ecf49966e7f9e6c16c44fbf7e0023dcb3b56ad6e8c576b85e20265c85d657b36a19347600f6aa91142fd489043bf2dd5b508feb74864b0b1914f1c29a5161913dbfbc7b811aefa71efb12351563f9637e3f9c9fbf38d31f222bad957598a5b7b49611e8cd4304a2923c36c07a8b92107bd13a0c9df6c4a9370792fdbb003dc0939176c52ee6bd0e0d28a3d8a22126bd9d977b50f39070bfa1548e9eb4c802950553e56030371bebf402f9e94b09385a8d2bd9e38a2fb31c48c60c529675596f234b866e5b30b99b9d5025a341fba4c3805771d33e1fbc6218d9f80f25e8b70163139e9c577a4841638720ec358d1f857e585d7d9f4233b54e88915ca617333aa17e91eddeac7b7bb05c23f5f236ec2e8e3b2ec0a44838e1ea6bcebb06688cd4346c387f7d76b78b697a6a6a63676ffc8b22f8d6d990391c133cdfd943d9ae0ae6eebc3a032ae3a306af8dde08bad2f839919335b966e52fa787e472582008defa7e94299ce321802bf52059530b384bde6b44cd346b7aa9277a463a48e7de53797c4089f021a0e4e0b1125e4e9a1a4b68375825ac85a47ad2961c82b87fae31adaa8250f67f63c3f0f90c6f95f0cb0f59ff90418f8e385bdf3ab581b777cb54b61b6a4dff5eccca765990791222f5c1521fedf5e60d86a2ed910bdc5c0d19f28354a344bfed554320d9e9bc9d499359d00a094530d794bcd5621439f8978a8debf1bef93c373e59d61cf21a8cc4bf2b07b5bfc77878e6b077012d2f8e7f2e3953348b5f4c95c880bda4b5bb2a23aa69b0084487934a379f93db8d5959a77fd6df7f81bc9468d1f4dc77211d56a5169dbe9dc108dee6766dd3baa854d19213fa272980901fcfd39243ddfff6b07ff45ce78f13b8ff6404d45f64a9afbeff6830a4ab6db3055d2d069f33ed6b14ec9c5f45ecf72d5b95997bc2e6dd4059809ee49951732c9d5fac234049d3e3e08e58972a1e9eb53bbe78c04a056a930f984b7842bb1834b6772e0ff672ffbb7f7d70e6d5ff18888f1fd59c972e12305a6b25c6567a845ab267c9a9ae3cd8355aee57a960dc92f1137dedad9c5b876c33d6f6dcf194c9fc7b83114105973ce871316978765c781a743a000a86bef0675c2cc81ec2551275731901ab7f23803ee9487ceafa68c2fb11459623a80faaff0049a63ba06b6128c2793dee03f90f6d52708568e599f7d5794c1aa1b9f3d1ecdcfacaaf8e10fcf5345de87fd57720e3c650619ed437b43638c46fd75488f3e0f1712b7f2cf83ba9c520b636bbf1f9388f7f4a7f9919acf47009d5322708ff94f6e1df844795290b37fa0e00f66943cb256fe9e5179d880dc05eef7f3a4b9397ddc011cbee4a6963e0b7bbc402c7734b0c1dda5d472e59b02cee948a234b0bd0824542f05a9d955fd7ca8860d420d5d7edf81f7fe7403f2b778e4d9aee1b6aeb4cf2b8a23d7520e68ead39eb56e44e59818534af7845bcc9866c3f50b411969670d0c6a61fcc25f70d1198fffe4763d4a64b5f967c2f6d8760ff372d909b6f7cfb0a85792a44816794c3b2bc40c74440caec19658b0c67fe021fb636de6daf24235b3d81a6109d413d19acca3035ad2e86280bfbddafeb041ac1ed5e50988b1bd8c0622e4afc94eb499f2e841527d5821e10f4ea5a2f3761c2272a7002ebf5c71c865eb231c1ca1408b82eede8ac5cf75dea99785dad6c97359484ceff4a01c5a8a90e79bd552d9e65d1003dc568ddce39dacdc3c18cd9765f89bbfabf9d699e0c6a4a541fecb184b9d57a385f7d90bd31b126ef14fbf9b6606a9fee697ea6b6414045aa17f98b0fb11b55b3202da493fcc21d49b220e425bd00e3b787d540fc6bb05b82606ba1579599bf2279559b6bb73edab5782eeb13aea1e65c2d8c2fc684e1ba5400bc5d6a4e7622ec815640c37b8f9be1a20fb54ddbdb58158c0a76a7809bc520471c3d71bd4db180e5eb9e7d262391a28e2bd9536f0a9f5f5bf56d815f5edfd330b64a625f047905398cc8e1f991e7e2b7370f1d513638ad3c1b77554d19d5340f42c9ab1a26bd28b5def91a8f8b6d1125ea39c442c7ec6b272f62922505193a383913847c9dd767bc25391da7e86e5b78a6545d876bfd4522e14f3f360afa7103d23c52131836b207596653466b9024a87f7f477a27bc13a22e470a2811195a476a9a3f9d54c2e97d68a5d23d69ecabea5214cb7071fb8d0e46b95db20f65120c0fd3e77953f8a73848aac24416d836b8702aba9d9c6536b4bd7248a5c9e3c700ca3b4f41a089238decd6232ce2e24d6f49198962d2ccfd44e01afd77d413515e816113eeede8ba994ec5325d3b46b7e9096ba3cb03712ed23bea7b960740b71b9730b900833756b1b1603dcafb1f798b0d355066450b515ea8f16f21a518afe4023ac34cb26338e1a7237452da891e3ff403878320ac55418241a1a8ef7d112496e83155bab4bec2dc6a966277c35d3a34a150c25ce1a86ebc48d55ab36856eb5dc66611c970367b8e9189332c01e1b6fa479162582b88de8e60ecea1e9e32e4e86f8dffdcf46c88814ac956d66bf140a72832206ba0f0b8027920653c17084e0092c28809a3cbcb98066ab7d114785c1d92bd382dbf58eaed5ccf811ecdbdc6c34351da93a2dd579170494323fc8424da452ffbd8d1c5342628c6243914c899944066b653ea6988a956e4b52d97a951300827768ffbd5ec2680e16bb2cf5492f82c6615d22dddb567071a0d85bda62f603f34644f4d0a304cf477f4a2744b292311bd82f18fe37e3fdb66df813bb00ba7a24c69adae330a27919cbdace8477304dd694352502741d56330f2fd9858e82f936368f963c17c10bcee7bb60453b36f7b6ab068ba8fb5d6d7812529dad40ced2c2aeb4eb87d5da59c91aa14a0db5d31c2261d397f70aea949e60e68f070de11f5dd820ddbd74d53c7bbeaccca2583a3e780769337d9cb9c6d0363c6c7ca28c177ab6b7e3f5213d518758dc63a81ca0bee0aad1ad55112b8daa6e5173a0c7f39607f71f0d1af1c5305f456f6dba3ea86bd8c4469e1d1a039d40edadb5cba0a1d38348e522bf0679bc3427cb86f370384c0763a31cf51c4d4fa720a60124afc3b1c5afc6f47e5e1de917085406f647932d0d3f28c3c3a0e51593a8e3c97989946d5961bd4b29179f72b8e367d86de843018af8b8625c787e96fe54f6eba059e4b0db96c7a24af0e816a8f1fd2cc838cbf36c051587102ce40b5f3f7017b90de895dd372a30dae9ea2896b93736f5e5823da3817ab709fb0bd1a7040905b5fb36ab5786801af382143971e3c27842092dc5b79af8195c083839540e0c7e7f97f6c33776f650b0e22dcc8288adcc87e983738b05065ee350c645440d0e3cfb16ee682b129058d96dc850940e13bb7eba56b90196bfa4fab369f3ddd7432e6c797aa8b4a282696fac69326ce01ada99a0e1009566d2742e0a9b9e31a589561e8d4fbb2684cd7480d21a01a7d6bb8b8ea5f9bd73e2f43f3e571d373238af293743ed028cdccb4064d61ddd36e89c578ac08ef1fca72696dd57bf10ae96c04e6505fd2f2a4cda2d2bd1880931e28d917d131aba886ae4927d9c8eff3904dea6b01a043e96e55e32a6b9f7cfc5862e3e8d348c353a2a84a4053bcdcedce2fb313d2c627206f88fb3ab46bca2da09325db2aaf744b772887ae518d685215165331699faaef0fd1de5dacfbbb4ed710751a84a1910c19f37916c3064a349724ea60fd9a4308476709175c40d90d9ecdf90766fbef184726fe4103499029547f4dadab0b454eec684679b9f0bab8d9abb9dc813b27aa5a702b3293d2876e1b2a951932f3d41fadae8321ae3887801a999c246c7732bcd9dbf25193e68a3956db90771f6d1d8f9ec0e4ca2abf76550735e4ed95c8aa2588cca560d2f453d4bf1e14fe44ba536e0cf720bea461d5d015d52b9d46e4121f6266fb57db24f3794f6939a53a2927ba6e9d5865aaeccf6c899800be9d7144835061c3cf660d156c7967fe6d9d0790fb47b0bd9eb897e0037a57a717b9c68d25930a989e8f78423d281984372bf7c771fb6ddad75b0499d0e418667b3a2ed9f4cc3f4d228bdc1643afdbd8de9adeb23ba7e11fd2453d52206ce131b1e10aca73e912e0231aef742ff21c0e9390203ac84fb306606c945132e815c1a7c72d28b7fa61985f76da1bc43ffeeccf1aceae5b8a8540a6e456ce742a12ba5ddebde36e8218b968a34fb668237736146b6d51c92043169ab00e6ab785f2ff425887ffed64e36cea6e6b8cf6c120652d02a3de2a2ba236df6914611e910677bac21df044518518077a8884ca279a792be745b40df39d070d412e99c87a5cee43b5dfe6300900cc04f91da7358cca38d0b3d37abb3cfba87a1014032d200c0aad5330757f1299cc0e4633fd43ce529889ee4bdaf3e73a06e4ca50480f0451b61f992320b0390f91eb52a50ae3912cd8f89d48d619dbd76a13c993a801d8efbcea69fb93cd151de3235e8c83ab1c414585eda0e2ebf2f4e4e1e7c8b74adc8a1a64cf05eeb388921eab97b40b1aeb1b37d6555f6aa065d8c0f9eaff4549a84a4180d801dec72f6503412789c59bcab3c10a4c861507caa29279c3ed365bc667f947395fc2a9070b877ec53a73fe4f6079e69a27f79e4e2e295cbedc9e04ce3c7eb02a24dc957078189e1c0dd153e99a39a147f69e03701b5a997fa9b079abfe34714ac0aa1eee93113e18387ee1a0b62a59a1a434d2db3742d8efc8e95f18dd93188e209897d96f5498d35acd87e8d41946b2e90ffd70f8eeb77db37fb5440162584baedfd393568090a416223e08808c62a7888668d337ed68223d45b4981010b01bf46b3bb9c75167d0ba3cb6e0b9667f5829f8d08de812b39c88f2f250c84d1da883582fda9e159741442db170d5e24dc4dd1f6f567217981ca36d60bf28d3cfaa2bbbe0e1db14e9ac00f540270d50ecbaa0ab43fc6cd3f43c1635e2b939794d349e76bf0b7ef4026b368da0589eab5ad2653ad49023b8224611ba812f9bbd8df9086200b08039d9e914e8587b5092e780e8564f6a6b1bd862a9ec7b7b41aa8961c7150446fa6c96f391fb8dc9e234be5fcc7fdcdab7b0def1ee8d13fed32bc1bc64fff2ba35930d7b533c81fb9d04e6a4aa2a386b37c3c1422a5258c8b8716451482c602f3dcd1eb05718606f27e1263b13ccbcd142146a0e355ff737c9f046fbcad5f192d7c9b1511e6fa40f0d28bc551bf8426986993c6a5ab96b7427f0310c3aafd5b5bbbae0e8d818f842a418a54e3f7282bf9c5368d8069148f17282b4111956523608d4efd3dbc8e3cee6b91d85ff9dbf671e63bcd2c7e769a93b740238d0a050444bb0c75a7dd7c4378bb685ffa76ef4677a591d171eca08e6f2a4a72701fadb996f3fec1b996ea8c71e9f7f7bd40135ec761e386bf096293bc54255fd877804f6bbb6d280df0f50b065bf8420f05848181fb3711212104f48870caaf053ef4207ab1bccafcddd396c46c271cf07c708e1c75acb23808b738fd2be857a925a7595a35c6286b18f59ecf0367c8979f2f0898deef5a179baf02593da3d468b2125abe279fc73b8a1077476972ea07fd2f052ee2663ccbf17aeb0f0deb43500c6293be7e8f1defdc2c58803a0ebc87a503775d907c5852f063af91fdd2495339b5c97baf0c67b71f284ad543919826a1b650fcef0748b9390399f4f6cb6d5461ef1086d09227ae9cb64274e163fec5715fd68cd4f794b6c4490a925321e31b8ec8a3654ec943a5475c4c4ad6fa0309785b8f1b17dbf42f6c411fb2632d54a3f06e7dea631b8125a6d16c1e07cda8e5623156b1a8b77c40072d9a969afa13aad016d45afd78a803b058944cc78d2b43bb73b0d9f087dc2064602f4c9d1d5d1c09d23c9639beaeed75231483e803a73de041665e803bf16ac54eef6522ee76e54507f3fe01e4a7c53b4b84b0ff22903a03381fb1362b12113cea5cbb9d623ccdff321f8ee295069e35696325e391864a5e23a51e219b7c297dbb14263e4e77f110716831f2db438dd019669477cd19078740f4891382f4933c4db972b601aa329df34af213c01358a3af002ff67c8a38f97ad9e6f11b4de6ca0335571367a4131dfc8a115db8e1a399acb83ec9a7c0c2765fed008584531f8e4223de69b88dab47ca174dd065f22fcea9a01519b45132ff2e43576f721cc308766b5cd438ed8a5feeb4f705ae874f36318dfb23dccd18dbd152a21ecf79fe26634242d64e764cb0665eb7f8a93ac8e877e04853d2f3e5740854d8fff9be33c2da277be5f38603dbb7181031079287eada78b5d72e4f49c24328d5e85161b816c303cea436bccaecfd04cd4f60258ff7985a353bed0e159c13933a27411f31f7cf61b7fdb8b4ea4c220e2f7d4c366aae9043c608cb7018961f71f99e2298bd676cceb06a1482d167fb45f43cd79c6a59e0abfbb827b410719cd980dae8fe2145132d27bcc8b653e038c169b2df993de2e33edd1a463658b5ef73b67a3e36b5dcf0cb716c46c812735f3114eb4ba4a4f2db66a3791a73158afae72ba98519722da93a425524bc4e613174e29b11a67362e596fdcceea8c58fa173c6d345ac345bf62a4a545af448be828a85a182762b44b6e47727122525c21c1392a6f930e1986aa1a5e41fcfc58c419166c4d2d0646bf4a20347ce5beb2bd4a5c1f4b25191021c89cb433a326978967c800c2965c2a3ae4cbc0b17b7f9629c8838b5a55e8bdaad87addc3777d9472b6305f1f09bc4dc62a503e7afd8bdd7b65903547ef2965be310a52b8f470d2717833b68b7542c29156dd564acb4359f26fd82c6aad231fc565c29837351ee1c90f74c257a910d5f802fe9ad87dc6053b26aa249c5dae50635f07f2f7ad21b7778be9617273de6ae64b647bfc6e7dea5d7b3ec70cf1de5b4470404838d8b6874500bbf0f438df303d279c083b46908a7131e7f55cfac9187cb8c36fb9011cae3100e43f7a34c5c8d18fe8d82577ffc7fe79cd7e5c1f5d81390d1facac32c9a753b008b77412deb9305acd114f47ca198230d358c2443e2f7afde6cdfad87479310921da1ef13cf494421dae7defc8fc4ca3f9ff991bd8143ea7280bf7c8a7b051a4eec091f2622eb90913c2554c0036da5931c99c7344128b092726c44276efbed271cdf7f8cb77f2ccf0f8cd6ce4cb5897cfffb0522a5c04f41737cc76f21befa6b28250bc197de61fbc919c4972e02b30230b7ee42159b6d62e899f192af59d9bcc1e9a1b6edca4e23374cd249d0e547d538031d775804685eebec89bf3a04cdeb88c2745f5a4620cb98b3067315649998538742b8241fc48645390389218594db0492b0e21b90e8ee4428822ffffbfa6a6dde4cc59b8222da24ac460f3402adc7ee0e9b46014cea7b532e5fee8eb4497d9e89eb9c99f97e70212506591f85affe197579b7097fb2b18325dab8c0a58f9eeefaa6507e5c77a7f5b7ee9b42dfc6f513f63643e6bdee4c83b660d881cf6996b566bde42496b9c89d6d6307f41ca0bdd02f442042395fbf796fcff8b5eb4aee25b50a730d87112d2215e26796d316dcc9fe69324f16ab55dc1c0a4936d99169eef35cb88489d519833d0d06381dc3b5db5deca0109511585a325725a47cddd2371d2fe2c689ba1d4e054227c02db622851728f7dd7601a25e9ba628fa6acabe535b38c60697cb035dccc9fb80bf3d98ef3cd3a24c798d51d7395be47109f0c7e28a68e62f5882c8d37546044a1720ee56e193ef832b6de8daf1c254fa7d3088a892af8f8de41ce9258f6da0fdd71293265969163346607db73da76841df8a2bf3c6b2d033b4c983940c3e58fb66149fa5afd118c8d80094af824d53d7f59339d2f7186b51a0a9d66b62c09793db857fd080e28d828f3cf2b578edbc98040b9f9a680bb60323eb73a72ef1139c8309ba5106ec4479390621ba90a5949731f798678fd866ea29845a474c602587e46446497580592fce6fced17cb11bba7467cfa7fe540967fbefbb04c8b1ec07dc908f2d2d9a80344bc583ab0118b6617945523fc73ae26ac857eb3066281d1c8514628460d554bf8f36bfc9f5d8cbadc7bad53af2a4ddc8e3f27842d7ee533a7ed2711ec58b550fa1f70723d5d8201c7ddf1d55e0e96e4d57e071be261ecbfe7353b88b675ecd52baed71e725953236c2e529135cea150b29f9b1071f856ec007d103dce8925396d6c2fb2d46d42ee698d35ecd42df47d903ed5fb49b4b6572dcdb44835552038d0f80c028e644ae27b3ececbc9bbab1c62ae7c992adb380d824b1751dee6a85844333930df5c51e2431222b795cfd1aba7c1bc925138644848911da7aed1868d483f454823983df2bce50fd8a72d1a9afb76b6fc60f9b9b7a92c1666b300848bd51742f1ef81623f1a8ebef74d5169e9a3e1bd4275d3b2bd01885ff175a349068e05aac018398b564a2672a725aba74ae119678d0fc6fd5805f880c1ef6ecd1bed1e7621d31a96c0381bf4b34e758a3fa18c9d9436912a358c37f901c16516fd1bc3c60eb12a8134e84ae0842960d2873ca651eccd665b89bafbd769f6f60f41869be6b0ba173ee74ec129344adbd283968718e12757fe46c7aa8c2ae91db6933fc47854022412d6a76750f5f16639a3bfb3c43c7220aa1093ed0ae24765d662587579f45ba9dde2043861ebd2d48952b02976014cd799f8e9f8a2ab5da98e01188f385352eb339922343674e8933ab1cdce8597c04bc483f4ff45d6456a9790dae146e599a634daf4564fc82481ead8df5ff9e6dc8c7925afa47c6d11a10176406c78a05a9851d399d74e2e07cdf11ee20f657339c4fb8d7b3df79425dcc7a030fbe824cb4a29501358f845c1dd738031ce047a1f85ee106018c963ec38c7d91a33063403940df2d170c3d7a088c0be4647c82e0c7b0a74760cf901321e619a054781cd0b0112a5e14ca597d8bb203d841905a58400f9cf49fac5d1f362e5130c76a96883f5138f5604ceedca2d08b9e5ca681f713c05cc581038aa713ac77d2cc5c2e970bffaf82e3f600d00eea3cf4c1731e243b4d6d8209d21b27a7321dc0f4d15f4d24f656facbe66a6b87a0c50f77a01b89c37ace2cf8905510e5f5d0580ff435a00859fbc444d6500e82073753723d23f25915dd1ba0b76e262f25c8c92b0204472eca4481d763caa14a796cf94d60894a1210dcdf56f930f1d045c1c3437f785fa9d35255ceda5f09a08fe6d375d3058fb1d7b0216fa85e218a453fea4997ce4e91437a659c8e9178794945c1d6641b3505a84fe3dda7a59756ddc3958238ea2459890d8ea726c65c6ccdff9ca4890705725c66c14b20d888db5e4706ff7888df0ae9d6172c193b9369c7c33280540cf61998ee0e5d999ad1db33d10fbe93fe68a73d67cabfc191276e01ef99a87aa1d59c88c26ea629ea4a399696a0beccea382f097b740eae580f2d50b1829f82a0e7e03c125610b1bcc6defae9d9438f6598930028a9b0b089a4c5c3a1efc07f045a7c76b304b2cc74d3a404ba1323a61caad8414f62fbbba512e39d55cad0d2339f4525a38bc0a65b489c3cbdddb4e811f25ca60a2c2d9bf99c70162a4c0bbd8a13679ee3d12dcf0dc6615eabdad7ac34cb5e336507c44c5271232a1b1763e330c4de92cf9893c723675bc617624fd63ec024f49cdba134a9a94aa83016946c2f56ccfe79d271737e91c8f798e512d5f2caae8f9f7b0cf641939d6be76e9fa97e3648ab482768fb53524806cf0bdd2b06b29bae99a2f3ba11c8f721706196668f9dc953aa352dd3512117396fabcffe24c95620d173122fa3ef81b231cbd1e1c724e78390b6c258962b1df7066e5b5d11c1cb8ac823703c27e1c6542615b3bffbc47e5437ca037c3e3d5beb2f84b93006517cb3ad96b7e4897c1827ab1b64f4d00b2874314ea88a7719bb7386518533bca2afa5a53e0263888c20ee59dd65862f9d587e584d2aa0c59e0b8dacb2dcab02b3e42a0499ace7465d634bd3e58c0769c025df70c9aaf9f622c6d2045380f783b5bd87ec59d6822ff388a766c388d36b1a3549ded18826f8f4ee5b3caf97f14369841058f9aa50e8f702f14a894c9b608ace272ae1a8dffdc0b6c646eb2dc3498287436bc7a72da5bc2c177a7c72258b9be3028a3950d28152402524f6fab1377c064f68f0f6875eb7a148f34ba8fa39db8c1b5a6b7b9083136916c218e06fe38dc45813fdb5d32d46bf063dac7b4b07a07f78c7531120b5a7b04594eaea378fc3bb2f67e217bec4e5bf7297d300b8e3a76cc63918663cf22c2699f29ff7ad9cdd5198579015e27932e88871286a98ce61f6b16a3c0666f002220b5ba0840a383481d265a3e42e05671a655c843d38479448ad323899d78edbd17f9f41e87ddc4458825b664419faa79f92eae2f80385a92bf694037656d69ea94579431c77d5578b8bb41d27da5ac59f60cb029024c9d0dbbef65fff1b7e20d37447a8cc8d7e11d46643994e049a61d905ff145137b7f8980a51eeafcb50aede4978a5b5eb2dd918c61c390932ba93fa753f6bd09d19d7d6afa5f88aee3441ca6195e1e79ff6bc1bdde7af57abcac69c563c0ed8574bd7dc505902b7aa0a662567b764631ea3a4e037786f40c4a14bd5cbb410106ebf50c9d7f5b64963db3a4d13b7588f589fea8df2fd9745a0b554c53f9b958914cbd83e3afe9b2d370462bf6f07d6eedecd4f9cd38e354783cdad7bd12b0f50c7043a71ad5f8fdda1fc102b4ffadd5ff65d3c3b233c268cf4258b4f29d2fc4e84cb153ce6cb6cad2f215a0bbc7dfc426abd2fd06e7f0385620f58c36d2b0e52b052ba27bcc80537852d2f4fb795e25c4453a70e65d538b0087c6bb65d5ae1f0681fdccf5de3f79ed10647b1f6d5f1a6c8e77c885dd76b1d03cc65e27f298e51baeb112383f4d2995e126a2a932b24fd789fb411a5a480595a0074206daaa0e283d8f6f4331a8a8ff5f4c58c99a534f609022388fde539549ea4a2d9cec0743ca999ea5e18e9e2af73502420c77561526c688a6044844da42c2719cd29c51a1cef56f643fa1b2bd9f9996c03c55d85ecd522308315d26b2c95809890b5f9488d2ef8057e33cc3760c0a321952d2833963ef9988a6e5a1142715d2907059f2b1aeef68a44dfec3c377d64f29c55c36f300ebef00b66a02e74ec035b910f1caa3eda8a1d11aecfa27a983ca14917bee07cca6cd9fab3f226a6df1ceb43651a3b3d11346575dd4108265eb9adbe72612b9ffdcd3a76e9406d9284f18ad4aa2d5760a96e0f7c900f8c6b92a3ddff3db33b3bf275a404a55af5ff191f5a58d819b28d0246d12634143d567d6dcde407f41b249e6950d190e82ecad7c5dd776a46e6509d9c068fb0636a5be0d397e5e49241b5bf5deef0bd0fe5eb611682163a9abc5d60fada37090390a341818dd5dd19aac5a5e9c86699037ec02a0520dab14933f59dc8944ef4559bab1df63d9477136b2ebcef56e9680b3fa7fe46ed03edc82ae5b1fd1ffaf5d73a9b3ac24d7ceecc37e0546fca1b200939545c092bb770096a237279e73c5fab57595450df0c40a12243b883bf9dc7c89251d33d736b354bc13b7108244efa048ca0ce9dfa23df7f266504958f852df88f590dbc28341ebbfe65f91bde839fd6cb3f2e8eff1819f3d018ae6d41165069dc534b3adf473c12957a3a7a3cbe69d25af28e4eb074fe7df04fd3dc11c15b5e511bc497d51fa16f904f11f3cd50a51ac8a2043b311ea86b6ac0c36d4b52164cde4076f424bf015918f8aa5061d916cbc3444f7ff161b716ba4923d37615a44b4a610595f9b867524082433b8967677b1a0a109accbefaac818720c5b09b3d98ffb0eca2f6d68582a05235d3f696a21dcf68bf20a14cf2fa4a9ba9db8588aa840b1e49bb0e872ad182509eaae7b739b64e9d5446cc7d7a3b904d9d0d97eff2c5858866f47efef1e443e99557d88098fd7e0a7ef519ec66b05cd5a90a5888e6263df6b857fbdb28971449491922e7eb757104ddb82b5e621c7c91c59d0512633d51f6b39a74e332ca47b8ab6ee25610a7455c5dfd611932dfe179b6a2ebbc6d0e5aa3891b1115ddf92584096215acb91ec27cdc5ed39e3c4c2faaa3ea8da2661e2e9a9c53c37496237ffb6f733acd2a0943039e947fde654d01fedf5351928ff95a59450ba34cd209c3380f1701abd8287e388ba57d069bdc59d8ae4592e40d65fa38cdd3e9c0865251c9ee389e9630c69d08a7fa1fa4b5e403ec4451f9fe021d0d7aac7565a4cbc08b03e5a03e1ef146d164006b4e8950a046080618fc4014d5a9d3705e7c9c87260e0247bb0d0aba9b75821aff428abf65ca3b2440209602bffef2a0b053fedc928d07a960486769846a2996edd0cb8b8c034a9aee5dd713a005b8a3722783632abd32584c0a84cee74efa106c3533a4a777ad4ab55ca82b44b1dc887fdaddec75476c04783da5b477fda64c33b851ee90ef55f605310067eb73c57fa2f8283d64d3e6a111eb23ade577263874c0c028fd6ec634d8bf8d4c4ae3505312e2cf7f50c2faaedab45ce5314b1f7139463b3f45f7315e75c33ac02ade1a6986164e39f03cfc3c35a150c2ea9926e775765ee18a1bf971a57438fc7ee683e60ec997ce04951bec174e48d8f368fd5a1e56c7665a6b7784ca9ee11b09c2b8b9eb3b7166efe7085e5f018cb69faba8c0cffe4fc6b3ad1e188f81cced8011c22931a6260121aab3154c4454e471e2d0c2ebab77896d7f2c4a816eb17b96f3222318b8ecef660918f9738cad6fa4bd81428c1525848be4cc4f1d989a207330ab56b8b2b91e391b9228f62a735a6d3d56556a799d52a03f0a2270c7f158f9c7871da9c68a</script> <div class="hbe hbe-content"> <div class="hbe hbe-input hbe-input-default"> <input class="hbe hbe-input-field hbe-input-field-default" type="password" id="hbePass"> <label class="hbe hbe-input-label hbe-input-label-default" for="hbePass"> <span class="hbe hbe-input-label-content hbe-input-label-content-default">您好, 这里需要密码.</span> </label> </div> </div></div><script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
<categories>
<category> Private </category>
</categories>
</entry>
<entry>
<title>等高线图、填色图</title>
<link href="/2020/06/10/ContourDiagram/"/>
<url>/2020/06/10/ContourDiagram/</url>
<content type="html"><![CDATA[]]></content>
<categories>
<category> Plot </category>
</categories>
</entry>
<entry>
<title>CDO简介及常用语法</title>
<link href="/2020/06/07/cdo/"/>
<url>/2020/06/07/cdo/</url>
<content type="html"><![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="gutter"><pre><span class="line">1</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br></pre></td><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>Python绘图如何自定义或使用NCL中的colormap</title>
<link href="/2020/06/06/color/"/>
<url>/2020/06/06/color/</url>
<content type="html"><![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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><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><img src="/image/colormap1.png"/><p>使用调色盘软件生成的色板也是同样的思路,将生成的txt内的rgb信息读取映射,就可以使用了。</p><h3 id="四、设定色板颜色,进行插值映射"><a href="#四、设定色板颜色,进行插值映射" class="headerlink" title="四、设定色板颜色,进行插值映射"></a>四、设定色板颜色,进行插值映射</h3><p>最后再介绍一种创建色板的方式,那就是挑选几种自己需要的颜色排列起来,然后进行插值,形成颜色之间的渐变,最后映射为色板。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><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.colors <span class="keyword">as</span> colors</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">colorslist = [<span class="string">'black'</span>,<span class="string">'red'</span>,<span class="string">'orange'</span>,<span class="string">'blue'</span>]</span><br><span class="line"><span class="comment">#将四种色插值为具有300个渐变色的色板</span></span><br><span class="line">colormap = colors.LinearSegmentedColormap.from_list(<span class="string">'123'</span>,colorslist,N=<span class="number">300</span>)</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">#绘制散点图,使用刚刚自定义的123色板</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><img src="/image/colormap2.png"/>]]></content>
<categories>
<category> Paper </category>
</categories>
<tags>
<tag> Python </tag>
<tag> Plot </tag>
</tags>
</entry>
<entry>
<title>经验正交函数分解(EOF)</title>
<link href="/2020/06/01/f1-5-1-1/"/>
<url>/2020/06/01/f1-5-1-1/</url>
<content type="html"><![CDATA[<p>EOF分析在气象分析中十分常见,幸运的是有前辈已经利用Python实现了EOF分析并且发布在<a href="https://github.com/ajdawson/eofs" target="_blank" rel="noopener">github</a>。</p><p>本文将直接介绍该库的安装及使用,关于EOF的原理不做介绍。</p><h4 id="一、安装"><a href="#一、安装" class="headerlink" title="一、安装"></a>一、安装</h4><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">conda install -c conda-forge eofs</span><br></pre></td></tr></table></figure><h4 id="二、使用介绍"><a href="#二、使用介绍" class="headerlink" title="二、使用介绍"></a>二、使用介绍</h4><p>首先import</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> eofs.standard <span class="keyword">import</span> Eof</span><br></pre></td></tr></table></figure><p>该库有几个基本函数是必须掌握的,我们一一介绍。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">solver = Eof(x, weights)</span><br><span class="line">eof = solver.eofsAsCorrelation(neofs=<span class="number">3</span>)</span><br><span class="line">pc = solver.pcs(npcs=<span class="number">3</span>, pcscaling=<span class="number">1</span>)</span><br><span class="line">var = solver.varianceFraction()</span><br></pre></td></tr></table></figure><p>solver = Eof()建立一个EOF分解器,x为要进行分解的变量,weights为权重,通常指纬度权重</p><p>solver.eofsAsCorrelation,solver.pcs,solver.varianceFraction分别取出空间模态,PC和方差。</p><h4 id="三、示例"><a href="#三、示例" class="headerlink" title="三、示例"></a>三、示例</h4><p>我们以中国夏季降水三类雨型的分解为例,展示EOF分析完整的Python实现。</p><p><img src="/image/image-20200601202548617.png" alt="image-20200601202548617"></p><p>数据下载:<a href="/image/pre.nc">1961-2016夏季降水</a> 以及 <a href="/image/shp.rar">边界shp文件</a></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><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="keyword">from</span> cartopy.mpl.gridliner <span class="keyword">import</span> LONGITUDE_FORMATTER, LATITUDE_FORMATTER</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="keyword">import</span> cartopy.io.shapereader <span class="keyword">as</span> shpreader</span><br><span class="line"><span class="keyword">import</span> xarray <span class="keyword">as</span> xr</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="comment">#读取数据</span></span><br><span class="line">f = xr.open_dataset(<span class="string">'./pre.nc'</span>)</span><br><span class="line">pre = np.array(f[<span class="string">'pre'</span>])</span><br><span class="line">lat = f[<span class="string">'lat'</span>]</span><br><span class="line">lon = f[<span class="string">'lon'</span>]</span><br><span class="line"><span class="comment">#计算纬度权重</span></span><br><span class="line">lat = np.array(lat)</span><br><span class="line">coslat = np.cos(np.deg2rad(lat))</span><br><span class="line">wgts = np.sqrt(coslat)[..., np.newaxis]</span><br><span class="line"><span class="comment">#创建EOF分解器</span></span><br><span class="line">solver = Eof(summer_mean_tmp, weights=wgts)</span><br><span class="line"><span class="comment">#获取前三个模态,获取对应的PC序列和解释方差</span></span><br><span class="line">eof = solver.eofsAsCorrelation(neofs=<span class="number">3</span>)</span><br><span class="line">pc = solver.pcs(npcs=<span class="number">3</span>, pcscaling=<span class="number">1</span>)</span><br><span class="line">var = solver.varianceFraction()</span><br></pre></td></tr></table></figure><p>以下是绘图部分,我们先给出其中不重复的部分,文章最末会给出完整代码:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#设置色标颜色,用于绘制PC柱状图</span></span><br><span class="line">color1=[]</span><br><span class="line">color2=[]</span><br><span class="line">color3=[]</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">1961</span>,<span class="number">2017</span>):</span><br><span class="line"> <span class="keyword">if</span> pc[i<span class="number">-1961</span>,<span class="number">0</span>] >=<span class="number">0</span>:</span><br><span class="line"> color1.append(<span class="string">'red'</span>)</span><br><span class="line"> <span class="keyword">elif</span> pc[i<span class="number">-1961</span>,<span class="number">0</span>] <<span class="number">0</span>:</span><br><span class="line"> color1.append(<span class="string">'blue'</span>)</span><br><span class="line"> <span class="keyword">if</span> pc[i<span class="number">-1961</span>,<span class="number">1</span>] >=<span class="number">0</span>:</span><br><span class="line"> color2.append(<span class="string">'red'</span>)</span><br><span class="line"> <span class="keyword">elif</span> pc[i<span class="number">-1961</span>,<span class="number">1</span>] <<span class="number">0</span>:</span><br><span class="line"> color2.append(<span class="string">'blue'</span>)</span><br><span class="line"> <span class="keyword">if</span> pc[i<span class="number">-1961</span>,<span class="number">2</span>] >=<span class="number">0</span>:</span><br><span class="line"> color3.append(<span class="string">'red'</span>)</span><br><span class="line"> <span class="keyword">elif</span> pc[i<span class="number">-1961</span>,<span class="number">2</span>] <<span class="number">0</span>:</span><br><span class="line"> color3.append(<span class="string">'blue'</span>)</span><br><span class="line"><span class="comment">#建立图形以及基本设置</span></span><br><span class="line">fig = plt.figure(figsize=(<span class="number">15</span>,<span class="number">15</span>))</span><br><span class="line">proj = ccrs.PlateCarree(central_longitude=<span class="number">115</span>)</span><br><span class="line">leftlon, rightlon, lowerlat, upperlat = (<span class="number">70</span>,<span class="number">140</span>,<span class="number">15</span>,<span class="number">55</span>)</span><br><span class="line">lon_formatter = cticker.LongitudeFormatter()</span><br><span class="line">lat_formatter = cticker.LatitudeFormatter()</span><br><span class="line"><span class="comment">#绘制第一模态</span></span><br><span class="line">fig_ax1 = fig.add_axes([<span class="number">0.1</span>, <span class="number">0.8</span>, <span class="number">0.5</span>, <span class="number">0.3</span>],projection = proj)</span><br><span class="line">fig_ax1.set_extent([leftlon, rightlon, lowerlat, upperlat], crs=ccrs.PlateCarree())</span><br><span class="line">fig_ax1.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>))</span><br><span class="line">fig_ax1.add_feature(cfeature.LAKES, alpha=<span class="number">0.5</span>)</span><br><span class="line">fig_ax1.set_xticks(np.arange(leftlon,rightlon+<span class="number">10</span>,<span class="number">10</span>), crs=ccrs.PlateCarree())</span><br><span class="line">fig_ax1.set_yticks(np.arange(lowerlat,upperlat+<span class="number">10</span>,<span class="number">10</span>), crs=ccrs.PlateCarree())</span><br><span class="line">fig_ax1.xaxis.set_major_formatter(lon_formatter)</span><br><span class="line">fig_ax1.yaxis.set_major_formatter(lat_formatter)</span><br><span class="line">china = shpreader.Reader(<span class="string">'./bou2_4l.dbf'</span>).geometries()</span><br><span class="line">fig_ax1.add_geometries(china, ccrs.PlateCarree(),facecolor=<span class="string">'none'</span>, edgecolor=<span class="string">'black'</span>,zorder = <span class="number">1</span>)</span><br><span class="line">fig_ax1.set_title(<span class="string">'(a) EOF1'</span>,loc=<span class="string">'left'</span>,fontsize =<span class="number">15</span>)</span><br><span class="line">fig_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>,fontsize =<span class="number">15</span>)</span><br><span class="line">c1=fig_ax1.contourf(pre_lon,pre_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><br><span class="line"><span class="comment">#添加南海</span></span><br><span class="line">fig_ax11 = fig.add_axes([<span class="number">0.525</span>, <span class="number">0.08</span>, <span class="number">0.072</span>, <span class="number">0.15</span>],projection = proj)</span><br><span class="line">fig_ax11.set_extent([<span class="number">105</span>, <span class="number">125</span>, <span class="number">0</span>, <span class="number">25</span>], crs=ccrs.PlateCarree())</span><br><span class="line">fig_ax11.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>))</span><br><span class="line">china = shpreader.Reader(<span class="string">'./bou2_4l.dbf'</span>).geometries()</span><br><span class="line">fig_ax11.add_geometries(china, ccrs.PlateCarree(),facecolor=<span class="string">'none'</span>, edgecolor=<span class="string">'black'</span>,zorder = <span class="number">1</span>)</span><br><span class="line"><span class="comment">#添加色标</span></span><br><span class="line">cbposition=fig.add_axes([<span class="number">0.13</span>, <span class="number">0.04</span>, <span class="number">0.4</span>, <span class="number">0.015</span>])</span><br><span class="line">fig.colorbar(c1,cax=cbposition,orientation=<span class="string">'horizontal'</span>,format=<span class="string">'%.1f'</span>,)</span><br><span class="line"><span class="comment">#绘制PC</span></span><br><span class="line">fig_ax4 = fig.add_axes([<span class="number">0.65</span>, <span class="number">0.808</span>, <span class="number">0.47</span>, <span class="number">0.285</span>])</span><br><span class="line">fig_ax4.set_title(<span class="string">'(b) PC1'</span>,loc=<span class="string">'left'</span>,fontsize = <span class="number">15</span>)</span><br><span class="line">fig_ax4.set_ylim(<span class="number">-2.5</span>,<span class="number">2.5</span>)</span><br><span class="line">fig_ax4.axhline(<span class="number">0</span>,linestyle=<span class="string">"--"</span>)</span><br><span class="line">fig_ax4.bar(np.arange(<span class="number">1961</span>,<span class="number">2017</span>,<span class="number">1</span>),pc[:,<span class="number">0</span>],color=color1)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p>下面给出完整脚本的代码。看上去很长,但实际上大部分都是重复的:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br></pre></td><td class="code"><pre><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="keyword">from</span> cartopy.mpl.gridliner <span class="keyword">import</span> LONGITUDE_FORMATTER, LATITUDE_FORMATTER</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="keyword">import</span> cartopy.io.shapereader <span class="keyword">as</span> shpreader</span><br><span class="line"><span class="keyword">import</span> xarray <span class="keyword">as</span> xr</span><br><span class="line"><span class="keyword">from</span> eofs.standard <span class="keyword">import</span> Eof</span><br><span class="line">f = xr.open_dataset(<span class="string">'./pre.nc'</span>)</span><br><span class="line">pre = np.array(f[<span class="string">'pre'</span>])</span><br><span class="line">lat = f[<span class="string">'lat'</span>]</span><br><span class="line">lon = f[<span class="string">'lon'</span>]</span><br><span class="line">lat = np.array(lat)</span><br><span class="line">coslat = np.cos(np.deg2rad(lat))</span><br><span class="line">wgts = np.sqrt(coslat)[..., np.newaxis]</span><br><span class="line">solver = Eof(pre, weights=wgts)</span><br><span class="line">eof = solver.eofsAsCorrelation(neofs=<span class="number">3</span>)</span><br><span class="line">pc = solver.pcs(npcs=<span class="number">3</span>, pcscaling=<span class="number">1</span>)</span><br><span class="line">var = solver.varianceFraction()</span><br><span class="line">color1=[]</span><br><span class="line">color2=[]</span><br><span class="line">color3=[]</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">1961</span>,<span class="number">2017</span>):</span><br><span class="line"> <span class="keyword">if</span> pc[i<span class="number">-1961</span>,<span class="number">0</span>] >=<span class="number">0</span>:</span><br><span class="line"> color1.append(<span class="string">'red'</span>)</span><br><span class="line"> <span class="keyword">elif</span> pc[i<span class="number">-1961</span>,<span class="number">0</span>] <<span class="number">0</span>:</span><br><span class="line"> color1.append(<span class="string">'blue'</span>)</span><br><span class="line"> <span class="keyword">if</span> pc[i<span class="number">-1961</span>,<span class="number">1</span>] >=<span class="number">0</span>:</span><br><span class="line"> color2.append(<span class="string">'red'</span>)</span><br><span class="line"> <span class="keyword">elif</span> pc[i<span class="number">-1961</span>,<span class="number">1</span>] <<span class="number">0</span>:</span><br><span class="line"> color2.append(<span class="string">'blue'</span>)</span><br><span class="line"> <span class="keyword">if</span> pc[i<span class="number">-1961</span>,<span class="number">2</span>] >=<span class="number">0</span>:</span><br><span class="line"> color3.append(<span class="string">'red'</span>)</span><br><span class="line"> <span class="keyword">elif</span> pc[i<span class="number">-1961</span>,<span class="number">2</span>] <<span class="number">0</span>:</span><br><span class="line"> color3.append(<span class="string">'blue'</span>)</span><br><span class="line">fig = plt.figure(figsize=(<span class="number">15</span>,<span class="number">15</span>))</span><br><span class="line">proj = ccrs.PlateCarree(central_longitude=<span class="number">115</span>)</span><br><span class="line">leftlon, rightlon, lowerlat, upperlat = (<span class="number">70</span>,<span class="number">140</span>,<span class="number">15</span>,<span class="number">55</span>)</span><br><span class="line">lon_formatter = cticker.LongitudeFormatter()</span><br><span class="line">lat_formatter = cticker.LatitudeFormatter()</span><br><span class="line"></span><br><span class="line">fig_ax1 = fig.add_axes([<span class="number">0.1</span>, <span class="number">0.8</span>, <span class="number">0.5</span>, <span class="number">0.3</span>],projection = proj)</span><br><span class="line">fig_ax1.set_extent([leftlon, rightlon, lowerlat, upperlat], crs=ccrs.PlateCarree())</span><br><span class="line">fig_ax1.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>))</span><br><span class="line">fig_ax1.add_feature(cfeature.LAKES, alpha=<span class="number">0.5</span>)</span><br><span class="line">fig_ax1.set_xticks(np.arange(leftlon,rightlon+<span class="number">10</span>,<span class="number">10</span>), crs=ccrs.PlateCarree())</span><br><span class="line">fig_ax1.set_yticks(np.arange(lowerlat,upperlat+<span class="number">10</span>,<span class="number">10</span>), crs=ccrs.PlateCarree())</span><br><span class="line">fig_ax1.xaxis.set_major_formatter(lon_formatter)</span><br><span class="line">fig_ax1.yaxis.set_major_formatter(lat_formatter)</span><br><span class="line">china = shpreader.Reader(<span class="string">'./bou2_4l.dbf'</span>).geometries()</span><br><span class="line">fig_ax1.add_geometries(china, ccrs.PlateCarree(),facecolor=<span class="string">'none'</span>, edgecolor=<span class="string">'black'</span>,zorder = <span class="number">1</span>)</span><br><span class="line">fig_ax1.set_title(<span class="string">'(a) EOF1'</span>,loc=<span class="string">'left'</span>,fontsize =<span class="number">15</span>)</span><br><span class="line">fig_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>,fontsize =<span class="number">15</span>)</span><br><span class="line">c1=fig_ax1.contourf(pre_lon,pre_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><br><span class="line"></span><br><span class="line">fig_ax2 = fig.add_axes([<span class="number">0.1</span>, <span class="number">0.45</span>, <span class="number">0.5</span>, <span class="number">0.3</span>],projection = proj)</span><br><span class="line">fig_ax2.set_extent([leftlon, rightlon, lowerlat, upperlat], crs=ccrs.PlateCarree())</span><br><span class="line">fig_ax2.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>))</span><br><span class="line">fig_ax2.add_feature(cfeature.LAKES, alpha=<span class="number">0.5</span>)</span><br><span class="line">fig_ax2.set_xticks(np.arange(leftlon,rightlon+<span class="number">10</span>,<span class="number">10</span>), crs=ccrs.PlateCarree())</span><br><span class="line">fig_ax2.set_yticks(np.arange(lowerlat,upperlat+<span class="number">10</span>,<span class="number">10</span>), crs=ccrs.PlateCarree())</span><br><span class="line">fig_ax2.xaxis.set_major_formatter(lon_formatter)</span><br><span class="line">fig_ax2.yaxis.set_major_formatter(lat_formatter)</span><br><span class="line">china = shpreader.Reader(<span class="string">'./bou2_4l.dbf'</span>).geometries()</span><br><span class="line">fig_ax2.add_geometries(china, ccrs.PlateCarree(),facecolor=<span class="string">'none'</span>, edgecolor=<span class="string">'black'</span>,zorder = <span class="number">1</span>)</span><br><span class="line">fig_ax2.set_title(<span class="string">'(c) EOF2'</span>,loc=<span class="string">'left'</span>,fontsize =<span class="number">15</span>)</span><br><span class="line">fig_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>,fontsize =<span class="number">15</span>)</span><br><span class="line">c2=fig_ax2.contourf(pre_lon,pre_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><br><span class="line">fig_ax3 = fig.add_axes([<span class="number">0.1</span>, <span class="number">0.1</span>, <span class="number">0.5</span>, <span class="number">0.3</span>],projection = proj)</span><br><span class="line">fig_ax3.set_extent([leftlon, rightlon, lowerlat, upperlat], crs=ccrs.PlateCarree())</span><br><span class="line">fig_ax3.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>))</span><br><span class="line">fig_ax3.add_feature(cfeature.LAKES, alpha=<span class="number">0.5</span>)</span><br><span class="line">fig_ax3.set_xticks(np.arange(leftlon,rightlon+<span class="number">10</span>,<span class="number">10</span>), crs=ccrs.PlateCarree())</span><br><span class="line">fig_ax3.set_yticks(np.arange(lowerlat,upperlat+<span class="number">10</span>,<span class="number">10</span>), crs=ccrs.PlateCarree())</span><br><span class="line">fig_ax3.xaxis.set_major_formatter(lon_formatter)</span><br><span class="line">fig_ax3.yaxis.set_major_formatter(lat_formatter)</span><br><span class="line">china = shpreader.Reader(<span class="string">'./bou2_4l.dbf'</span>).geometries()</span><br><span class="line">fig_ax3.add_geometries(china, ccrs.PlateCarree(),facecolor=<span class="string">'none'</span>, edgecolor=<span class="string">'black'</span>,zorder = <span class="number">1</span>)</span><br><span class="line">fig_ax3.set_title(<span class="string">'(e) EOF3'</span>,loc=<span class="string">'left'</span>,fontsize =<span class="number">15</span>)</span><br><span class="line">fig_ax3.set_title( <span class="string">'%.2f%%'</span> % (var[<span class="number">2</span>]*<span class="number">100</span>),loc=<span class="string">'right'</span>,fontsize =<span class="number">15</span>)</span><br><span class="line">c3=fig_ax3.contourf(pre_lon,pre_lat, eof[<span class="number">2</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><br><span class="line">fig_ax11 = fig.add_axes([<span class="number">0.525</span>, <span class="number">0.08</span>, <span class="number">0.072</span>, <span class="number">0.15</span>],projection = proj)</span><br><span class="line">fig_ax11.set_extent([<span class="number">105</span>, <span class="number">125</span>, <span class="number">0</span>, <span class="number">25</span>], crs=ccrs.PlateCarree())</span><br><span class="line">fig_ax11.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>))</span><br><span class="line">china = shpreader.Reader(<span class="string">'./bou2_4l.dbf'</span>).geometries()</span><br><span class="line">fig_ax11.add_geometries(china, ccrs.PlateCarree(),facecolor=<span class="string">'none'</span>, edgecolor=<span class="string">'black'</span>,zorder = <span class="number">1</span>)</span><br><span class="line"></span><br><span class="line">fig_ax22 = fig.add_axes([<span class="number">0.525</span>, <span class="number">0.43</span>, <span class="number">0.072</span>, <span class="number">0.15</span>],projection = proj)</span><br><span class="line">fig_ax22.set_extent([<span class="number">105</span>, <span class="number">125</span>, <span class="number">0</span>, <span class="number">25</span>], crs=ccrs.PlateCarree())</span><br><span class="line">fig_ax22.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>))</span><br><span class="line">china = shpreader.Reader(<span class="string">'./bou2_4l.dbf'</span>).geometries()</span><br><span class="line">fig_ax22.add_geometries(china, ccrs.PlateCarree(),facecolor=<span class="string">'none'</span>, edgecolor=<span class="string">'black'</span>,zorder = <span class="number">1</span>)</span><br><span class="line"></span><br><span class="line">fig_ax33 = fig.add_axes([<span class="number">0.525</span>, <span class="number">0.78</span>, <span class="number">0.072</span>, <span class="number">0.15</span>],projection = proj)</span><br><span class="line">fig_ax33.set_extent([<span class="number">105</span>, <span class="number">125</span>, <span class="number">0</span>, <span class="number">25</span>], crs=ccrs.PlateCarree())</span><br><span class="line">fig_ax33.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>))</span><br><span class="line">china = shpreader.Reader(<span class="string">'./bou2_4l.dbf'</span>).geometries()</span><br><span class="line">fig_ax33.add_geometries(china, ccrs.PlateCarree(),facecolor=<span class="string">'none'</span>, edgecolor=<span class="string">'black'</span>,zorder = <span class="number">1</span>)</span><br><span class="line"></span><br><span class="line">cbposition=fig.add_axes([<span class="number">0.13</span>, <span class="number">0.04</span>, <span class="number">0.4</span>, <span class="number">0.015</span>])</span><br><span class="line">fig.colorbar(c1,cax=cbposition,orientation=<span class="string">'horizontal'</span>,format=<span class="string">'%.1f'</span>,)</span><br><span class="line"></span><br><span class="line">fig_ax4 = fig.add_axes([<span class="number">0.65</span>, <span class="number">0.808</span>, <span class="number">0.47</span>, <span class="number">0.285</span>])</span><br><span class="line">fig_ax4.set_title(<span class="string">'(b) PC1'</span>,loc=<span class="string">'left'</span>,fontsize = <span class="number">15</span>)</span><br><span class="line">fig_ax4.set_ylim(<span class="number">-2.5</span>,<span class="number">2.5</span>)</span><br><span class="line">fig_ax4.axhline(<span class="number">0</span>,linestyle=<span class="string">"--"</span>)</span><br><span class="line">fig_ax4.bar(np.arange(<span class="number">1961</span>,<span class="number">2017</span>,<span class="number">1</span>),pc[:,<span class="number">0</span>],color=color1)</span><br><span class="line"></span><br><span class="line">fig_ax5 = fig.add_axes([<span class="number">0.65</span>, <span class="number">0.458</span>, <span class="number">0.47</span>, <span class="number">0.285</span>])</span><br><span class="line">fig_ax5.set_title(<span class="string">'(d) PC2'</span>,loc=<span class="string">'left'</span>,fontsize = <span class="number">15</span>)</span><br><span class="line">fig_ax5.set_ylim(<span class="number">-2.5</span>,<span class="number">2.5</span>)</span><br><span class="line">fig_ax5.axhline(<span class="number">0</span>,linestyle=<span class="string">"--"</span>)</span><br><span class="line">fig_ax5.bar(np.arange(<span class="number">1961</span>,<span class="number">2017</span>,<span class="number">1</span>),pc[:,<span class="number">1</span>],color=color2)</span><br><span class="line"></span><br><span class="line">fig_ax6 = fig.add_axes([<span class="number">0.65</span>, <span class="number">0.108</span>, <span class="number">0.47</span>, <span class="number">0.285</span>])</span><br><span class="line">fig_ax6.set_title(<span class="string">'(f) PC3'</span>,loc=<span class="string">'left'</span>,fontsize = <span class="number">15</span>)</span><br><span class="line">fig_ax6.set_ylim(<span class="number">-2.5</span>,<span class="number">2.5</span>)</span><br><span class="line">fig_ax6.axhline(<span class="number">0</span>,linestyle=<span class="string">"--"</span>)</span><br><span class="line">fig_ax6.bar(np.arange(<span class="number">1961</span>,<span class="number">2017</span>,<span class="number">1</span>),pc[:,<span class="number">2</span>],color=color3)</span><br><span class="line"></span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> Function </category>
</categories>
</entry>
<entry>
<title>利用Cartopy绘制带有地图投影的图形</title>
<link href="/2020/06/01/geoplot/"/>
<url>/2020/06/01/geoplot/</url>
<content type="html"><![CDATA[<p>从NCL转向python绘图后,最迷茫的一点恐怕就是地理绘图了,网络上流传了大量的python绘图教程,但是很少是关于地理方面的,包括各类投影坐标系,地理地形,界线shp的绘制等等。这篇文章以Cartopy为主,介绍如何通过Matplotlib结合Cartopy来灵活的绘制带有地图投影的图像。</p><a id="more"></a><p>本部分需要使用Cartopy库,通过:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">conda install -c conda-forge cartopy</span><br><span class="line"><span class="meta">#</span><span class="bash">or</span></span><br><span class="line">pip install cartopy</span><br></pre></td></tr></table></figure><p>安装。</p><h3 id="一、Cartopy投影坐标系"><a href="#一、Cartopy投影坐标系" class="headerlink" title="一、Cartopy投影坐标系"></a>一、Cartopy投影坐标系</h3><p>在绘图前首先要选择适合的投影方式,目前cartopy提供了超过三十种的投影方式,其中也包含我们所熟悉的极地投影,墨卡托投影,兰伯特投影等等。下面,将介绍几种常用的投影方式的设置及使用。</p><h4 id="1、-PlateCarree-无坐标转换"><a href="#1、-PlateCarree-无坐标转换" class="headerlink" title="1、 PlateCarree (无坐标转换)"></a>1、 PlateCarree (无坐标转换)</h4><p>PlateCarree是一种基础的投影方式,其计算方法是将经纬度网格设置成等距网格,实际上数据并没有进行坐标转换。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cartopy.crs.PlateCarree(central_longitude=<span class="number">0.0</span>)</span><br></pre></td></tr></table></figure><p>参数: central_longitude : GeoAxes中心的经度,默认为0°</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><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">fig = plt.figure(figsize=[<span class="number">10</span>, <span class="number">5</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">ax2 = fig.add_subplot(<span class="number">1</span>, <span class="number">2</span>, <span class="number">2</span>, projection=ccrs.PlateCarree(central_longitude = <span class="number">120</span>))</span><br><span class="line">ax1.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>)) </span><br><span class="line">ax2.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>)) </span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="/image/image-20200601184415711.png" alt="image-20200601184415711"></p><h4 id="2、圆锥兰伯特投影-LambertConformal"><a href="#2、圆锥兰伯特投影-LambertConformal" class="headerlink" title="2、圆锥兰伯特投影 LambertConformal"></a>2、圆锥兰伯特投影 LambertConformal</h4><p>LambertConformal(正形兰伯特投影),也就是常说的正轴圆锥投影。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cartopy.crs.LambertConformal(central_longitude=<span class="number">-96.0</span>, central_latitude=<span class="number">39.0</span>, false_easting=<span class="number">0.0</span>, false_northing=<span class="number">0.0</span>, secant_latitudes=<span class="literal">None</span>, standard_parallels=<span class="literal">None</span>, cutoff=<span class="number">-30</span>)</span><br></pre></td></tr></table></figure><p>参数: central_longitude : GeoAxes中心的经度,默认为96°W</p><p>central_latitude :GeoAxes中心的纬度,默认为39°N</p><p>false_easting : 东伪偏移,默认为0m</p><p>false_northing :北伪偏移,默认为0m</p><p>standard_parallels : 标准平行纬度,默认为(33,45)</p><p>cutoff : 截止纬度,即最南边界纬度,默认为30°S</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><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">fig = plt.figure(figsize=[<span class="number">10</span>, <span class="number">5</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.LambertConformal())</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.LambertConformal(cutoff=<span class="number">0</span>))</span><br><span class="line">ax1.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>)) </span><br><span class="line">ax2.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>)) </span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="/image/image-20200601184531410.png" alt="image-20200601184531410"></p><h4 id="3、墨卡托投影-Mercator"><a href="#3、墨卡托投影-Mercator" class="headerlink" title="3、墨卡托投影 Mercator"></a>3、墨卡托投影 Mercator</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cartopy.crs.Mercator(central_longitude=<span class="number">0.0</span>, min_latitude=<span class="number">-80.0</span>, max_latitude=<span class="number">84.0</span>, latitude_true_scale=<span class="literal">None</span>, false_easting=<span class="number">0.0</span>, false_northing=<span class="number">0.0</span>)</span><br></pre></td></tr></table></figure><p>参数:</p><p>central_longitude : GeoAxes中心的经度,默认为0°</p><p>min_latitude :GeoAxes最南纬度,默认为80°S</p><p>max_latitude :GeoAxes最北纬度,默认为84°N</p><p>latitude_true_scale :比例尺为1的纬度,默认为赤道</p><p>false_easting : 东伪偏移,默认为0m</p><p>false_northing :北伪偏移,默认为0m</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><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">fig = plt.figure(figsize=[<span class="number">10</span>, <span class="number">5</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.Mercator())</span><br><span class="line">ax1.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>)) </span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="/image/image-20200601184730865.png" alt="image-20200601184730865"></p><h4 id="4、极地投影"><a href="#4、极地投影" class="headerlink" title="4、极地投影"></a>4、极地投影</h4><p>NorthPolarStereo(北半球极射赤面投影)和SouthPolarStereo(南半球极射赤面投影)</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cartopy.crs.NorthPolarStereo(central_longitude=<span class="number">0.0</span>, true_scale_latitude=<span class="literal">None</span>)</span><br><span class="line">cartopy.crs.SouthPolarStereo(central_longitude=<span class="number">0.0</span>, true_scale_latitude=<span class="literal">None</span>)</span><br></pre></td></tr></table></figure><p>参数:</p><p>central_longitude : GeoAxes中心的经度,默认为0°</p><p>true_scale_latitude :比例尺为1的纬度。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><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">fig = plt.figure(figsize=[<span class="number">10</span>, <span class="number">5</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.NorthPolarStereo())</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.SouthPolarStereo())</span><br><span class="line">ax1.gridlines()</span><br><span class="line">ax2.gridlines()</span><br><span class="line">ax1.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>)) </span><br><span class="line">ax2.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>)) </span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="/image/image-20200601184823459.png" alt="image-20200601184823459"></p><h3 id="二、GeoAxes绘制"><a href="#二、GeoAxes绘制" class="headerlink" title="二、GeoAxes绘制"></a>二、GeoAxes绘制</h3><p>上篇文章讲到Axes的构成,GeoAxes简单讲就是在Axes的基础上添加了地理要素(地图投影)。那么绘制GeoAxes有哪些不同呢?</p><p>我们以一个500hPa高度场的绘制为例。应大家要求,这次我裁剪了数据,控制了数据的大小,以方便大家下载。</p><p>数据下载地址:<a href="https://pan.baidu.com/s/1JPoOO4y-F7JKXzONrDw6CA" target="_blank" rel="noopener">1980060106.nc(71M)</a></p><p>神秘代码:k1qd</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><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="keyword">import</span> xarray <span class="keyword">as</span> xr</span><br><span class="line"><span class="comment">###数据读取###</span></span><br><span class="line">f = xr.open_dataset(<span class="string">'./data/1980060106.nc'</span>)</span><br><span class="line">z = f[<span class="string">'z'</span>].loc[:,<span class="number">500</span>,:,:][<span class="number">0</span>,:,:]/<span class="number">98</span></span><br><span class="line">lat = z[<span class="string">'latitude'</span>]</span><br><span class="line">lon = z[<span class="string">'longitude'</span>]</span><br><span class="line"><span class="comment">###建立Figure###</span></span><br><span class="line">fig = plt.figure(figsize=(<span class="number">12</span>,<span class="number">8</span>))</span><br><span class="line"><span class="comment">###指定投影为中心经度为90°的PlateCarree###</span></span><br><span class="line">ax = fig.add_subplot(<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,projection = ccrs.PlateCarree(central_longitude=<span class="number">90</span>)) </span><br><span class="line"><span class="comment">###设置GeoAxes范围###</span></span><br><span class="line">ax.set_extent([<span class="number">0</span>,<span class="number">180</span>,<span class="number">0</span>,<span class="number">90</span>], crs=ccrs.PlateCarree())</span><br><span class="line"><span class="comment">###添加海岸线###</span></span><br><span class="line">ax.add_feature(cfeature.COASTLINE.with_scale(<span class="string">'50m'</span>)) </span><br><span class="line"><span class="comment">###设置坐标及刻度###</span></span><br><span class="line">ax.set_xticks(np.arange(<span class="number">0</span>,<span class="number">180</span>+<span class="number">30</span>,<span class="number">30</span>), crs=ccrs.PlateCarree())</span><br><span class="line">ax.set_yticks(np.arange(<span class="number">0</span>,<span class="number">90</span>+<span class="number">30</span>,<span class="number">30</span>), 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">ax.xaxis.set_major_formatter(lon_formatter)</span><br><span class="line">ax.yaxis.set_major_formatter(lat_formatter)</span><br><span class="line"><span class="comment">###图题###</span></span><br><span class="line">ax.set_title(<span class="string">'500hPa Z'</span>,loc=<span class="string">'center'</span>,fontsize=<span class="number">18</span>)</span><br><span class="line">ax.set_title(<span class="string">'unit: dagpm'</span>,loc=<span class="string">'right'</span>,fontsize=<span class="number">18</span>)</span><br><span class="line"><span class="comment">###绘制等高线,指定坐标转换方式###</span></span><br><span class="line">c = ax.contour(lon,lat, z, zorder=<span class="number">0</span>,transform=ccrs.PlateCarree())</span><br><span class="line"><span class="comment">###添加等高线标签###</span></span><br><span class="line">ax.clabel(c, fontsize=<span class="number">9</span>, inline=<span class="number">1</span>,fmt=<span class="string">'%d'</span>)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="/image/image-20200601185834300.png" alt="image-20200601185834300"></p><p>这里对脚本中一些函数进行额外解释:</p><ol><li>在进行建立Axes时,要指明目标投影,使之成为GeoAxes</li><li>设置GeoAxes范围时,输入范围的左右下上边界经纬度</li><li>绘制等高线,指定坐标转换方式,此示例是以最为常用的PlateCarree形式展示</li></ol><p>大家可以使用上边介绍的其它投影格式进行替换,绘图时必须要弄清楚什么地方应该设置为数据的投影方式,什么地方设置为目标的投影方式。</p>]]></content>
<categories>
<category> Paper </category>
</categories>
<tags>
<tag> Python </tag>
<tag> Matplotlib </tag>
<tag> Cartopy </tag>
</tags>
</entry>
<entry>
<title>一张图看懂matplotlib的绘图结构</title>
<link href="/2020/05/28/%E4%B8%80%E5%BC%A0%E5%9B%BE%E5%BC%84%E6%87%82matplotlib/"/>
<url>/2020/05/28/%E4%B8%80%E5%BC%A0%E5%9B%BE%E5%BC%84%E6%87%82matplotlib/</url>
<content type="html"><![CDATA[<p>介绍matplotlib绘图基础结构,绘图基础流程,以及绘图通用属性设置。</p><a id="more"></a><p>刚开始接触python matplotlib绘图的朋友可能对figure,axes,axis等等名词感到迷糊,到底什么对应什么,弄不清怎么才能绘制出自己满意的图形结构,那么借用官方提供的一张图,可以清晰的展现一个完整的图片的层次结构。</p><p>首先声明,本文是为了助于大家理解绘图的结构,所以会用一些粗浅的比喻,尽量避免让人迷惑的专业词汇。所以这篇文章会非常的:unprofessional。</p><h4 id="一、-Figure结构"><a href="#一、-Figure结构" class="headerlink" title="一、 Figure结构"></a>一、 Figure结构</h4><p><img src="/image/image-20200528144651404.png" alt="image-20200528144651404"></p><ol><li>首先找到位于左下角的“Figure”,这一整张图形,就是一个Figure,Figure包含了全部,可以想象成你画画的桌子</li><li>“Figure”右边不远,有一个Axes,每一个Axes都是一张用来画画的纸,这些纸可以铺在桌子上的任何位置,也可以叠起来,一张压着一张,随你怎么摆放</li><li>除此之外,这张图圈起来的其他所有属性,都是建立在Axes之上的,也就是在画纸上进行的。</li></ol><p>那么在理解了绘制一个Figure的要素之后,就可以顺着这个流程来绘图了。</p><h4 id="二、绘图流程"><a href="#二、绘图流程" class="headerlink" title="二、绘图流程"></a>二、绘图流程</h4><ol><li><p>建立Figure</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line">fig = plt.figure(figsize=(<span class="number">12</span>,<span class="number">8</span>))<span class="comment">#12,8为图片长宽</span></span><br></pre></td></tr></table></figure></li><li><p>建立Axes</p><p>2.1 这一步有很多方法,比如最常见的,通常也是比较便捷的,像制定表格一样,指明摆放几行几列(顺序为从上到下从左到右)的画纸:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">ax1 = fig.add_subplot(<span class="number">221</span>)<span class="comment">#2行2列第一个位置</span></span><br><span class="line">ax2 = fig.add_subplot(<span class="number">222</span>)<span class="comment">#2行2列第一个位置</span></span><br><span class="line">ax3 = fig.add_subplot(<span class="number">223</span>)<span class="comment">#2行2列第一个位置</span></span><br><span class="line">ax4 = fig.add_subplot(<span class="number">224</span>)<span class="comment">#2行2列第4个位置</span></span><br></pre></td></tr></table></figure><p>2.2 第二种方法更加灵活自由,但是需要自己指定精确的坐标位置(这是我最喜欢的一种方法,虽然比较麻烦,但是灵活呀)</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ax = fig.add_axes([<span class="number">0.1</span>, <span class="number">0.2</span>, <span class="number">0.3</span>, <span class="number">0.4</span>])<span class="comment">#在figure中x=0.1,y=0.2的位置,建立一个长0.3宽0.4的Axes</span></span><br></pre></td></tr></table></figure></li><li><p>调用相应的绘图函数绘制图层,比如折线图里的折线,散点图里的散点,填色图里的色斑等等,这部分不在这里细讲</p></li><li><p>设置Axes属性,图题,坐标标签,图例,等等</p></li></ol><h4 id="三、通用属性设置"><a href="#三、通用属性设置" class="headerlink" title="三、通用属性设置"></a>三、通用属性设置</h4><p>通用属性,指的是绘图对象均可设置的属性,比如说透明度alpha,标签可以设置透明度,折线可以设置透明度,图例也可以设置透明度,这就属于通用属性,通用指的是对Artist的通用,总之,你在Axes上看到的一切,都姑且可以当做Artist来对待。</p><table><thead><tr><th align="center">Artist通用属性</th><th align="center">作用</th></tr></thead><tbody><tr><td align="center">alpha</td><td align="center">透明度,0为透明,1为不透明</td></tr><tr><td align="center">clip_box</td><td align="center">裁剪框</td></tr><tr><td align="center">clip_on</td><td align="center">是否裁剪</td></tr><tr><td align="center">clip_path</td><td align="center">裁剪路径</td></tr><tr><td align="center">label</td><td align="center">文本标签</td></tr><tr><td align="center">transform</td><td align="center">坐标转换(绘制带地图投影的图形需要)</td></tr><tr><td align="center">visible</td><td align="center">是否可见/隐藏(通常用于隐藏Spines,也就是隐藏掉边框)</td></tr><tr><td align="center">zorder</td><td align="center">绘图顺序(用于设置多图层的绘图顺序,比如先填色,再打点,再加图例)</td></tr></tbody></table><p>最常用的alpha,label,transform,visible,zorder。</p><h4 id="四、图像核心要素设置"><a href="#四、图像核心要素设置" class="headerlink" title="四、图像核心要素设置"></a>四、图像核心要素设置</h4><h5 id="4-1-与坐标轴有关的设置"><a href="#4-1-与坐标轴有关的设置" class="headerlink" title="4.1 与坐标轴有关的设置"></a>4.1 与坐标轴有关的设置</h5><ol><li><p>设置x,y轴范围</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ax1.set_xlim(x1, x2)</span><br><span class="line">ax1.set_ylim(y1, y2)</span><br></pre></td></tr></table></figure></li><li><p>设置刻度及标签</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#将x轴1,2,3,4对应位置标签改为a,b,c,d。y轴同理,x->y即可</span></span><br><span class="line">ax1.set_xticks([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>])</span><br><span class="line">ax1.set_xticklabels([<span class="string">'a'</span>,<span class="string">'b'</span>,<span class="string">'c'</span>,<span class="string">'d'</span>])</span><br></pre></td></tr></table></figure></li></ol><ol start="3"><li><p>设置坐标轴不显示,这里就展示到了刚刚通用属性的用法</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ax.spines[<span class="string">'top'</span>].set_visible(<span class="literal">False</span>)</span><br><span class="line">ax.spines[<span class="string">'right'</span>].set_visible(<span class="literal">False</span>)</span><br></pre></td></tr></table></figure><img src="/image/image-20200528153307572.png" alt="image-20200528153307572" style="zoom:50%;" /><p>4.设置坐标轴名称</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ax.set_xlabel(<span class="string">'x axis'</span>)</span><br><span class="line">ax.set_ylabel(<span class="string">'y axis'</span>)</span><br></pre></td></tr></table></figure></li></ol><h5 id="4-2-常用属性设置-颜色,线性,标记符号"><a href="#4-2-常用属性设置-颜色,线性,标记符号" class="headerlink" title="4.2 常用属性设置(颜色,线性,标记符号)"></a>4.2 常用属性设置(颜色,线性,标记符号)</h5><table><thead><tr><th>颜色</th><th>代码</th><th>线型</th><th>代码</th><th>标记</th><th>代码</th></tr></thead><tbody><tr><td>蓝</td><td>‘b’</td><td>实线</td><td>‘-’</td><td>点</td><td>‘.’</td></tr><tr><td>绿</td><td>‘g’</td><td>虚线</td><td>‘–’</td><td>x</td><td>‘x’</td></tr><tr><td>红</td><td>‘r’</td><td>虚点</td><td>‘-.’</td><td>圆圈</td><td>‘o’</td></tr><tr><td>青</td><td>‘c’</td><td>点线</td><td>‘:’</td><td>三角</td><td>‘v’</td></tr><tr><td>紫</td><td>‘p’</td><td></td><td></td><td>方块</td><td>‘s’</td></tr><tr><td>黄</td><td>‘y’</td><td></td><td></td><td>星</td><td>‘*’</td></tr><tr><td>黑</td><td>‘k’</td><td></td><td></td><td>加号</td><td>‘+’</td></tr><tr><td>白</td><td>‘w’</td><td></td><td></td><td>菱形</td><td>‘D’</td></tr></tbody></table><p>使用很简单,以最基础的plot函数为例:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ax.plot(x,y, color=<span class="string">'k'</span>, linestyle=<span class="string">'-'</span>, alpha=<span class="number">0.3</span>)</span><br></pre></td></tr></table></figure><p>甚至可以将color=’k’, linestyle=’-‘缩写为’-k’</p><h5 id="4-3-标题"><a href="#4-3-标题" class="headerlink" title="4.3 标题"></a>4.3 标题</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ax.set_title(<span class="string">'abc'</span>)</span><br></pre></td></tr></table></figure><p>标题的设置同样也可以添加一些参数:</p><p>loc: {‘center’, ‘left’, ‘right’},设置标题显示的位置</p><p>pad: 设置标题距离图像上边缘距离</p><p>fontsize: 设置字体大小</p><p>color: 设置字体颜色</p><h4 id="五、示例"><a href="#五、示例" class="headerlink" title="五、示例"></a>五、示例</h4><p>这边给一个完整的示例,将上面的要素尽量融合(由<a href="https://matplotlib.org/gallery/lines_bars_and_markers/fill_between_demo.html#sphx-glr-gallery-lines-bars-and-markers-fill-between-demo-py" target="_blank" rel="noopener">matplotlib官方例子</a>改编)。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#生成绘图数据部分,跳过即可</span></span><br><span class="line">N = <span class="number">21</span></span><br><span class="line">x = np.linspace(<span class="number">0</span>, <span class="number">10</span>, <span class="number">11</span>)</span><br><span class="line">y = [<span class="number">3.9</span>, <span class="number">4.4</span>, <span class="number">10.8</span>, <span class="number">10.3</span>, <span class="number">11.2</span>, <span class="number">13.1</span>, <span class="number">14.1</span>, <span class="number">9.9</span>, <span class="number">13.9</span>, <span class="number">15.1</span>, <span class="number">12.5</span>]</span><br><span class="line">a, b = np.polyfit(x, y, deg=<span class="number">1</span>)</span><br><span class="line">y_est = a * x + b</span><br><span class="line">y_err = x.std() * np.sqrt(<span class="number">1</span>/len(x) +</span><br><span class="line"> (x - x.mean())**<span class="number">2</span> / np.sum((x - x.mean())**<span class="number">2</span>))</span><br><span class="line"><span class="comment">#绘图开始</span></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_subplot(<span class="number">111</span>)</span><br><span class="line">ax.plot(x, y_est, <span class="string">'-'</span>)</span><br><span class="line">ax.fill_between(x, y_est - y_err, y_est + y_err, alpha=<span class="number">0.2</span>)</span><br><span class="line">ax.plot(x, y, <span class="string">'o'</span>, color=<span class="string">'r'</span>)</span><br><span class="line"><span class="comment">#添加属性</span></span><br><span class="line">ax.set_xlabel(<span class="string">'x axis'</span>,fontsize =<span class="number">16</span>)</span><br><span class="line">ax.set_ylabel(<span class="string">'y axis'</span>,fontsize =<span class="number">16</span>)</span><br><span class="line">ax.set_title(<span class="string">'example'</span>,loc=<span class="string">'left'</span>)</span><br><span class="line">ax.spines[<span class="string">'top'</span>].set_visible(<span class="literal">False</span>)</span><br><span class="line">ax.spines[<span class="string">'right'</span>].set_visible(<span class="literal">False</span>)</span><br><span class="line">ax.set_xlim(<span class="number">0</span>,<span class="number">20</span>)</span><br><span class="line">ax.set_yticks([<span class="number">0</span>,<span class="number">5</span>,<span class="number">10</span>])</span><br><span class="line">ax.set_yticklabels([<span class="string">'zero'</span>,<span class="string">'five'</span>,<span class="string">'ten'</span>])</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><img src="/image/image-20200528160025451.png" alt="image-20200528160025451" style="zoom:67%;" /><p>添加属性部分去掉任何一句话都不影响脚本的正确性,因此大家可以尝试逐句注释,来看看每句话控制着那些要素。</p>]]></content>
<categories>
<category> Paper </category>
</categories>
<tags>
<tag> Python </tag>
<tag> Matplotlib </tag>
</tags>
</entry>
<entry>
<title>功率谱</title>
<link href="/2020/05/27/f1-4-1-1/"/>
<url>/2020/05/27/f1-4-1-1/</url>
<content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><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">from</span> scipy.stats.distributions <span class="keyword">import</span> chi2</span><br><span class="line"><span class="string">'''</span></span><br><span class="line"><span class="string">功率谱分析</span></span><br><span class="line"><span class="string">输入:</span></span><br><span class="line"><span class="string">x:需要分析的时间序列(原始序列,未标准化或距平处理)</span></span><br><span class="line"><span class="string">m:最大滞后相关长度,m取值范围最好在(n/10)~(n/3)之间,n为样本数,可以多次调整m获得最佳效果,通常取m=n/3</span></span><br><span class="line"><span class="string">alpha1:红噪音检验信度</span></span><br><span class="line"><span class="string">alpha2:白噪音检验信度</span></span><br><span class="line"><span class="string">输出:</span></span><br><span class="line"><span class="string">l:功率谱图的X坐标,对应的周期为2m/l,使用时自己调整tick labels</span></span><br><span class="line"><span class="string">Sl:功率谱估计值</span></span><br><span class="line"><span class="string">Sr:红噪音</span></span><br><span class="line"><span class="string">Sw:白噪音</span></span><br><span class="line"><span class="string">r1:落后一个时刻的自相关函数,用于查看使用哪种噪音检验</span></span><br><span class="line"><span class="string">'''</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">specx_anal</span><span class="params">(x,m,alpha1,alpha2)</span>:</span></span><br><span class="line"> n = x.shape[<span class="number">0</span>]</span><br><span class="line"> x = (x - np.mean(x))/np.std(x)</span><br><span class="line"> r1 = np.zeros((n<span class="number">-6</span>))</span><br><span class="line"> r2 = np.zeros((n<span class="number">-7</span>))</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> np.arange(<span class="number">0</span>,n<span class="number">-6</span>):</span><br><span class="line"> r1[i]=np.sum(x[:n-i]*x[i:])/x[:n-i].shape[<span class="number">0</span>]</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> np.arange(<span class="number">1</span>,n<span class="number">-6</span>):</span><br><span class="line"> r2[i<span class="number">-1</span>]=np.sum(x[:n-i]*x[i:])/x[:n-i].shape[<span class="number">0</span>]</span><br><span class="line"> r2 = r2[::<span class="number">-1</span>]</span><br><span class="line"> r = np.hstack((r2,r1))</span><br><span class="line"> l = np.arange(<span class="number">0</span>,m+<span class="number">1</span>,<span class="number">1</span>)</span><br><span class="line"> tao = np.arange(<span class="number">1</span>,m,<span class="number">1</span>)</span><br><span class="line"> Sl = np.zeros((m+<span class="number">1</span>))</span><br><span class="line"> Tl = np.zeros((m+<span class="number">1</span>))</span><br><span class="line"> S0l = np.zeros((m+<span class="number">1</span>))</span><br><span class="line"> a = np.array((r.shape[<span class="number">0</span>]+<span class="number">1</span>)/<span class="number">2</span>).astype(<span class="string">'int32'</span>)</span><br><span class="line"> r = r[a<span class="number">-1</span>:a+m]</span><br><span class="line"> a=r[<span class="number">1</span>:<span class="number">-1</span>]*(<span class="number">1</span>+np.cos(np.pi*tao/m))</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> np.arange(<span class="number">2</span>,m+<span class="number">1</span>,<span class="number">1</span>):</span><br><span class="line"> Sl[i<span class="number">-1</span>]=(r[<span class="number">0</span>]+np.sum(a*np.cos(l[i<span class="number">-1</span>]*np.pi*tao/m)))/m </span><br><span class="line"> Sl[<span class="number">0</span>]=(r[<span class="number">0</span>]+np.sum(a*np.cos(l[<span class="number">0</span>]*np.pi*tao/m)))/(<span class="number">2</span>*m)</span><br><span class="line"> Sl[<span class="number">-1</span>]=(r[<span class="number">0</span>]+np.sum(a*np.cos(l[<span class="number">-1</span>]*np.pi*tao/m)))/(<span class="number">2</span>*m)</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(l.shape[<span class="number">0</span>]):</span><br><span class="line"> Tl[i]=<span class="number">2</span>*m/l[i]</span><br><span class="line"> f=(<span class="number">2</span>*n-m/<span class="number">2</span>)/m</span><br><span class="line"> S=np.mean(Sl)</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(l.shape[<span class="number">0</span>]):</span><br><span class="line"> S0l[i]=S*(<span class="number">1</span>-r[<span class="number">1</span>]*r[<span class="number">1</span>])/(<span class="number">1</span>+r[<span class="number">1</span>]*r[<span class="number">1</span>]<span class="number">-2</span>*r[<span class="number">1</span>]*np.cos(l[i]*np.pi/m))</span><br><span class="line"> x2r = chi2.ppf(<span class="number">1</span>-alpha1,df = f)</span><br><span class="line"> Sr=S0l*x2r/f</span><br><span class="line"> x2w = chi2.ppf(<span class="number">1</span>-alpha2,df = f)</span><br><span class="line"> Sw=S*x2w/f;</span><br><span class="line"> r1=r[<span class="number">1</span>]</span><br><span class="line"> <span class="keyword">return</span> l,Sl,Sr,Sw,r1</span><br></pre></td></tr></table></figure><p>示例:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">x = np.array([<span class="number">16.80</span>, <span class="number">15.35</span>, <span class="number">17.00</span>, <span class="number">22.50</span>, <span class="number">23.50</span>, <span class="number">27.00</span>, <span class="number">27.60</span>, <span class="number">28.00</span>, <span class="number">27.15</span>, <span class="number">24.00</span>, <span class="number">20.85</span>, <span class="number">18.25</span>,</span><br><span class="line"> <span class="number">16.20</span>, <span class="number">14.30</span>, <span class="number">16.55</span>, <span class="number">21.10</span>, <span class="number">24.00</span>, <span class="number">26.25</span>, <span class="number">27.80</span>, <span class="number">27.30</span>, <span class="number">27.05</span>, <span class="number">25.50</span>, <span class="number">23.80</span>, <span class="number">19.95</span>,</span><br><span class="line"> <span class="number">15.60</span>, <span class="number">17.00</span>, <span class="number">19.70</span>, <span class="number">20.90</span>, <span class="number">24.00</span>, <span class="number">24.80</span>, <span class="number">26.95</span>, <span class="number">26.70</span>, <span class="number">27.40</span>, <span class="number">24.85</span>, <span class="number">22.20</span>, <span class="number">18.90</span>,</span><br><span class="line"> <span class="number">15.80</span>, <span class="number">13.55</span>, <span class="number">17.60</span>, <span class="number">21.75</span>, <span class="number">25.00</span>, <span class="number">26.20</span>, <span class="number">26.95</span>, <span class="number">27.00</span>, <span class="number">26.35</span>, <span class="number">24.60</span>, <span class="number">21.55</span>, <span class="number">17.85</span>,</span><br><span class="line"> <span class="number">15.60</span>, <span class="number">18.05</span>, <span class="number">18.90</span>, <span class="number">21.90</span>, <span class="number">24.35</span>, <span class="number">26.20</span>, <span class="number">26.80</span>, <span class="number">26.90</span>, <span class="number">28.05</span>, <span class="number">25.60</span>, <span class="number">22.00</span>, <span class="number">17.80</span>,</span><br><span class="line"> <span class="number">16.20</span>, <span class="number">15.20</span>, <span class="number">17.60</span>, <span class="number">20.00</span>, <span class="number">23.75</span>, <span class="number">25.20</span>, <span class="number">27.00</span>, <span class="number">27.80</span>, <span class="number">26.90</span>, <span class="number">24.40</span>, <span class="number">21.00</span>, <span class="number">17.80</span>,</span><br><span class="line"> <span class="number">14.00</span>, <span class="number">13.55</span>, <span class="number">19.95</span>, <span class="number">23.00</span>, <span class="number">25.15</span>, <span class="number">26.80</span>, <span class="number">27.00</span>, <span class="number">27.10</span>, <span class="number">26.80</span>, <span class="number">25.50</span>, <span class="number">22.20</span>, <span class="number">19.50</span>,</span><br><span class="line"> <span class="number">18.00</span>, <span class="number">17.80</span>, <span class="number">18.95</span>, <span class="number">21.70</span>, <span class="number">23.40</span>, <span class="number">27.35</span>, <span class="number">28.00</span>, <span class="number">27.80</span>, <span class="number">27.20</span>, <span class="number">25.00</span>, <span class="number">22.20</span>, <span class="number">19.95</span>,</span><br><span class="line"> <span class="number">18.95</span>, <span class="number">19.00</span>, <span class="number">20.50</span>, <span class="number">22.20</span>, <span class="number">23.35</span>, <span class="number">25.55</span>, <span class="number">27.90</span>, <span class="number">27.80</span>, <span class="number">28.00</span>, <span class="number">24.60</span>, <span class="number">22.50</span>, <span class="number">19.20</span>,</span><br><span class="line"> <span class="number">17.70</span>, <span class="number">15.10</span>, <span class="number">16.50</span>, <span class="number">22.00</span>, <span class="number">24.00</span>, <span class="number">28.00</span>, <span class="number">28.60</span>, <span class="number">27.90</span>, <span class="number">27.00</span>, <span class="number">25.40</span>, <span class="number">23.00</span>, <span class="number">21.30</span>,</span><br><span class="line"> <span class="number">18.50</span>, <span class="number">18.00</span>, <span class="number">19.00</span>, <span class="number">23.25</span>, <span class="number">24.25</span>, <span class="number">25.40</span>, <span class="number">28.10</span>, <span class="number">28.50</span>, <span class="number">26.70</span>, <span class="number">25.70</span>, <span class="number">22.00</span>, <span class="number">18.00</span>,</span><br><span class="line"> <span class="number">18.00</span>, <span class="number">17.00</span>, <span class="number">18.00</span>, <span class="number">20.00</span>, <span class="number">24.05</span>, <span class="number">25.50</span>, <span class="number">27.55</span>, <span class="number">27.50</span>, <span class="number">26.60</span>, <span class="number">26.00</span>, <span class="number">23.50</span>, <span class="number">20.00</span>])</span><br><span class="line"></span><br><span class="line">l,Sl,Sr,Sw,r1 = specx_anal(x,x.shape[<span class="number">0</span>]//<span class="number">3</span>,<span class="number">0.1</span>,<span class="number">0.1</span>)</span><br><span class="line">plt.plot(l,Sl,<span class="string">'-b'</span>,label=<span class="string">'Real'</span>)</span><br><span class="line">plt.plot(l,Sr,<span class="string">'--r'</span>,label=<span class="string">'red noise'</span>)</span><br><span class="line">plt.plot(l,np.linspace(Sw,Sw,l.shape[<span class="number">0</span>]),<span class="string">'--m'</span>,label=<span class="string">'white noise'</span>)</span><br><span class="line">plt.legend()</span><br><span class="line">plt.show()</span><br><span class="line">print(r1)</span><br></pre></td></tr></table></figure><p><img src="/image/image-20200527155848450.png" alt="image-20200527155848450"></p><p>参考:<a href="http://bbs.06climate.com/forum.php?mod=viewthread&tid=14978&extra=page%3D3" target="_blank" rel="noopener">http://bbs.06climate.com/forum.php?mod=viewthread&tid=14978&extra=page%3D3</a></p>]]></content>
<categories>
<category> Function </category>
</categories>
</entry>
<entry>
<title>Bash for Download</title>
<link href="/2020/05/23/bashfordownload/"/>
<url>/2020/05/23/bashfordownload/</url>
<content type="html"><![CDATA[<p>利用Bash脚本下载资料(默认用于NOAA网站相关资料集)。使用时修改https内容。格式化函数${i}使用方法类似Python语言的format函数。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><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>Use CDO in Python</title>
<link href="/2020/05/23/cdopython/"/>
<url>/2020/05/23/cdopython/</url>
<content type="html"><![CDATA[<p>在Python中调用CDO批量处理文件(非cdo-python库)。</p><p>实际上可以利用CDO的chain方式连锁处理,代码会更简洁。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><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>]]></content>
<categories>
<category> Other </category>
</categories>
<tags>
<tag> Python </tag>
<tag> Plot </tag>
</tags>
</entry>
<entry>
<title>常用绘图类型</title>
<link href="/2020/05/23/plot/"/>
<url>/2020/05/23/plot/</url>
<content type="html"><![CDATA[<p>整理了常用的气候统计方法,包括源码及示例。</p><a id="more"></a><p>def函数使用方法如下:</p><p>第一种:将代码内容复制在脚本最前部,函数用法参考代码说明。</p><p>第二种:将代码保存复制存进A.py,与所要编辑脚本放在同一文件夹内,在脚本内 import A 即可。通过help(A)查看函数用法(A可任意替换,不冲突即可)。</p><p>一、折线图</p><ol><li><a href="/2020/09/01/zhexian1/">基本折线图(单变量,多变量)</a></li><li><a href="/2020/09/01/zhexian2/">双y轴折线图</a></li><li><a href="/2020/09/01/zhexian3/">多y轴折线图</a></li><li><a href="/2020/09/01/zhexian4/">非等比例坐标折线图</a></li><li><a href="/2020/09/03/zhexian5/">折线间颜色填充</a></li></ol><p>二、柱状图</p><ol><li><a href="/2020/09/03/bar1/">单变量柱状图</a></li><li><a href="/2020/09/03/bar2/">多变量柱状图</a></li><li><a href="/2020/09/03/bar3/">堆叠柱状图</a></li></ol><p>三、散点图</p><ol><li><a href="/2020/09/09/scatter1/">简单散点图</a></li><li><a href="/2020/09/09/scatter2/">带地图投影的散点图(站点分布图)</a></li></ol><p>四、填色图</p><ol><li><a href="/2021/04/22/contourf1/">带显著性检验的填色图</a></li><li><a href="/2022/11/28/contourf2/">修改显著性打点的颜色</a></li></ol><p>五、其他</p><ol><li><a href="/2021/04/22/huitufengzhuang/">绘图函数封装</a></li><li><a href="/2020/05/23/TaylorDiagram/">泰勒图</a></li><li><a href="/2020/07/02/lat-time-lev/">经纬度-时间分布图</a></li><li><a href="/2021/06/15/guiji1/">轨迹</a></li></ol>]]></content>
<categories>
<category> Other </category>
</categories>
<tags>
<tag> Python </tag>
<tag> Plot </tag>
</tags>
</entry>
<entry>
<title>泰勒图</title>
<link href="/2020/05/23/TaylorDiagram/"/>
<url>/2020/05/23/TaylorDiagram/</url>
<content type="html"><![CDATA[<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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><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>Windows10下的Linux子系统启用及JupyterNotebook入门</title>
<link href="/2020/05/21/wsl-and-jupyternotebook/"/>
<url>/2020/05/21/wsl-and-jupyternotebook/</url>
<content type="html"><![CDATA[<p>介绍Windows10系统如何启用Linux子系统,以及安装conda、python(各种库),并介绍一个非常好用非常推荐的脚本编辑运行应用——JupyterNotebook。</p><a id="more"></a><h3 id="引言"><a href="#引言" class="headerlink" title="引言"></a>引言</h3><p>作为气象专业的一员,是离不开Linux系统的,无论是各类数值模式,还是各种编程语言还是超级计算机的使用,都依赖于Linux系统(即使python可以在windows系统运行,但仍有很多库并不能很好的兼容windows系统)。如果在自己的计算机安装双系统或者虚拟机,显然有些大题小做并且十分麻烦,对于windows10的伙伴来说,启用Linux子系统就势在必得了。win10独有的Linux子系统功能(Windows Subsystem for Linux,简称WSL) 会给你的科研之路带来全新的体验。</p><h3 id="1-启用WSL"><a href="#1-启用WSL" class="headerlink" title="1. 启用WSL"></a>1. 启用WSL</h3><p>首先在控制面板里打开“程序和功能”,选择“启用或关闭Windows功能”,然后勾选“适用于Linux的Windows子系统(beta)”。然后系统就会提示你是否重新启动以启用更新。重启之后,WSL功能已经打开,但linux子系统还未安装。</p><img src="/image/image-20200521220133123.png" alt="image-20200521220133123" style="zoom:50%;" /><img src="/image/image-20200521220149246.png" alt="image-20200521220149246" style="zoom:50%;" /><p>1703版之后的win10把Ubuntu作为一个软件放在了应用商店。打开应用商店,直接下载Ubuntu。</p><p>下载完成之后打开Ubuntu就自动下载了。然后就是设置密码用户名(建议不要以admin,root这类用户名作为自己的用户名,后续使用中容易出现权限问题)。</p><p>至此,WSL就启用成功了。</p><h3 id="2-安装Miniconda"><a href="#2-安装Miniconda" class="headerlink" title="2. 安装Miniconda"></a>2. 安装Miniconda</h3><p>进入<a href="https://docs.conda.io/en/latest/miniconda.html" target="_blank" rel="noopener">miniconda官网下载地址</a>,找到Linux安装文件(如下图),选择python3.7版本,右建选择复制下载链接:</p><p><img src="/image/image-20200521220528952.png" alt="image-20200521220528952"></p><p>之后,打开Ubuntu进入WSL交互端口,键入wget+空格+右建,如下:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh</span><br></pre></td></tr></table></figure><p>回车即可下载。下载完成后,输入bash+空格+<strong>***</strong>.sh (<strong>***</strong>为刚刚下载的文件名)进行安装。如下:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bash Miniconda3-latest-Linux-x86_64.sh</span><br></pre></td></tr></table></figure><p>conda安装完成后,输入指令</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">conda create --name 123 python=3.7</span><br></pre></td></tr></table></figure><p>来创建一个名叫123的基于python3.7语言的环境(123可以任意改名)。</p><p>通俗的讲,可以将WSL当做是一个公寓,conda相当于一个管理员,而创建的每个环境都是一个独立的房间,你可以通过conda去管理每一个房间,如果一个房间遭到了破坏,那么重建它,而不会影响其他的房间。那么接下来请将自己代入conda这个管理员的身份,来使用你的环境,也就是说,我们尽可能的通过conda去设计房间(安装各种软件,依赖库,python库等等),不经过管理员就私自改造房间,容易造成混乱。</p><p>我们每次开启WSL(打开Ubuntu)后也就是进入了公寓后,需要先进入我们工作的房间,指令如下</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">conda activate 123</span><br></pre></td></tr></table></figure><p>那么比如说我们只使用一个房间,有没有办法打开公寓大门就能直接进入房间呢?有的,修改环境变量就好了(但是不建议)。</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><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="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">source activate 123</span><br></pre></td></tr></table></figure><p>之后重启Ubuntu即可,再次打开就会发现用户名前出现了“(123)”。</p><p>房间盖好了,接下来我们要装修了,也就是说安装各种常用的python库,比如numpy, pandas, scipy, xarray, cartopy等等等等。</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">conda install numpy</span><br><span class="line">conda install pandas</span><br><span class="line">conda install Scipy</span><br><span class="line">conda install -c conda-forge xarray</span><br><span class="line">conda install -c conda-forge cartopy</span><br></pre></td></tr></table></figure><p>-c表明 chanel的意思,表明这个包在conda-forge的安装频道。</p><p>接下来,尝试下是否安装成功了。首先输入</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python</span><br></pre></td></tr></table></figure><p>进入交互,然后尝试:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy</span><br></pre></td></tr></table></figure><p>检查是否安装成功。</p><h3 id="3-安装Jupyter-Notebook及其插件"><a href="#3-安装Jupyter-Notebook及其插件" class="headerlink" title="3. 安装Jupyter Notebook及其插件"></a>3. 安装Jupyter Notebook及其插件</h3><h4 id="3-1-安装"><a href="#3-1-安装" class="headerlink" title="3.1 安装"></a>3.1 安装</h4><p>同样的,我们还是通过conda安装一系列Jupyter Notebook的插件</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">conda install jupyter notebook </span><br><span class="line">python -m ipykernel install --user</span><br><span class="line">conda install -c conda-forge jupyter_contrib_nbextensions </span><br><span class="line">conda install jupyterthemes</span><br></pre></td></tr></table></figure><p>以上四条分别代表安装jupyter notebook ,为环境添加内核,安装jupyter插件功能,安装jupyter主题功能。</p><p>安装完成后,在终端输入jupyter notebook ,回车后会出现一串地址</p><img src="/image/image-20200522090912077.png" alt="image-20200522090912077" style="zoom:150%;" /><p>将其复制在浏览器地址栏即可(推荐使用Chrome浏览器)。</p><p>可以看到其主界面是这样子的:</p><p><img src="/image/image-20200522091232007.png" alt="image-20200522091232007"></p><p>1:根目录列表</p><p>2:当前正在运行这什么东西</p><p>3:忽略这个东西,用不到的</p><p>4:扩展插件,这个非常有用,就是刚刚第三条语句安装的辅助插件,后边详细介绍</p><p>5:上传文件,WSL目录与windows目录是有些区别的,在一定程度上相当于开辟了一个独立空间,使用upload可以将其他位置的文件传至这里,但是WSL是可以调用windows下的文件的。</p><p>6:新建一项任务,python3就是新建python3脚本,通过其他设置,还可以使notebook支持其他语言(NCL是不行的)这里不做过多介绍。</p><h4 id="3-2-插件设置"><a href="#3-2-插件设置" class="headerlink" title="3.2 插件设置"></a>3.2 插件设置</h4><p>点击进入NBextension,有这么几项功能是一定要添加的:</p><img src="/image/image-20200522092213561.png" alt="image-20200522092213561" style="zoom:150%;" /><p>AutoSaveTime:自动保存时间,指定间隔时间自动保存</p><p>Table of Contents:支持生成markdown目录,让代码结构清晰,更有条理</p><p>Variable Inspector: 变量追踪,查看目前已使用过的变量的相关信息(名,大小,形状,值)</p><p>Execute Time:记录代码块运行时间</p><p>其余插件根据自己需要自行添加即可。</p><h4 id="3-3-主题设置"><a href="#3-3-主题设置" class="headerlink" title="3.3 主题设置"></a>3.3 主题设置</h4><p>主题指的是可视化界面的主题,比如你不喜欢白色的界面,想换深色背景,或者调整字体,字体颜色等等,都通过主题插件进行设置。</p><p>终端执行命令</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">jt -t xxx -f xxx -fs xxx -cellw xx% -ofs xx -dfs xx -T -T</span><br></pre></td></tr></table></figure><p>-t 主题 -f(字体) -fs(字体大小) -cellw(占屏比或宽度) -ofs(输出段的字号) -T(显示工具栏) -T(显示自己主机名)</p><p>如果设置出现问题,那么输入</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">jt -r</span><br></pre></td></tr></table></figure><p>进行初始化。</p><p>点击这里查看:<a href="https://github.com/dunovank/jupyter-themes" target="_blank" rel="noopener">主题字体大全</a>。</p><h3 id="4-使用Jupyter-Notebook"><a href="#4-使用Jupyter-Notebook" class="headerlink" title="4. 使用Jupyter Notebook"></a>4. 使用Jupyter Notebook</h3><p>参照3.1,点击new新建一个python3脚本进入编辑界面:</p><p><img src="/image/image-20200522094237828.png" alt="image-20200522094237828"></p><p>这便是一个ipy脚本的可视化界面了。</p><p><u><strong><em>红色框内是菜单栏,对脚本的设置、编辑等选项均在此处选择。</em></strong></u></p><p><strong>File</strong>中主要为文件保存,下载等等</p><p><strong>Edit</strong>十分常用,包括删除,还原,复制,剪切,合并cell,也就是代码块</p><p><strong>View</strong>主要是可视化界面的调整</p><p><strong>Insert</strong>为插入代码块,插入标题等等</p><p><strong>Cell</strong>主要为代码块的运行,停止,代码块类型设置等等</p><p><strong>Kernel</strong>为该内核的重启,中断,重运行等等</p><p><strong>Help</strong>主要是各类参考,建议使用前阅读</p><p><strong>*<u>绿色框内是工具栏,存放了一些快捷工具的按钮。</u>*</strong></p><p>鼠标在按钮上停留就会展示该按钮的作用,在此不一一介绍。</p><p><strong>*<u>蓝色框就是脚本主体了,一个灰色的块叫一个CELL,也叫一个代码块,就是在此处进行编程。</u>*</strong></p><p>之所以推荐JupyterNotebook,很大原因就是由于这个代码块的设计理念,你可以将一个脚本拆分为很多个代码块,比如说加载库,读数据,数据处理,绘图分别存放在四个代码块里,这样在debug时只需要修改运行有Bug的代码块,而耗时很长的加载库,读数据都只需要运行一次即可,同样,最终绘图时,只需要调整绘图指令,而不需要将全部脚本重新运行,这样大大节省了运行时间,提高工作效率。</p><p>另外需要说明的一点,Jupyter Notebook支持快捷键的使用,熟练掌握常用快捷键可以获得更好的使用体验。快捷键使用在help->Keyboard Shortcuts中查看和编辑。</p><p>如有问题或遇到BUG,请在评论区留言反馈。</p>]]></content>
<categories>
<category> Paper </category>
</categories>
<tags>
<tag> Python </tag>
<tag> Linux </tag>
</tags>
</entry>
<entry>
<title>曼-肯德尔(Mann-Kendall)检验</title>
<link href="/2020/05/21/f1-3-2-1/"/>
<url>/2020/05/21/f1-3-2-1/</url>
<content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">'''</span></span><br><span class="line"><span class="string">曼-肯德尔(Mann-Kendall)检验</span></span><br><span class="line"><span class="string">输入:</span></span><br><span class="line"><span class="string">inputdata:输入数据,一维序列</span></span><br><span class="line"><span class="string">输出:UF,UB</span></span><br><span class="line"><span class="string">'''</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">mktest</span><span class="params">(inputdata)</span>:</span></span><br><span class="line"> inputdata = np.array(inputdata)</span><br><span class="line"> n=inputdata.shape[<span class="number">0</span>]</span><br><span class="line"> Sk = [<span class="number">0</span>]</span><br><span class="line"> UFk = [<span class="number">0</span>]</span><br><span class="line"> s = <span class="number">0</span></span><br><span class="line"> Exp_value = [<span class="number">0</span>]</span><br><span class="line"> Var_value = [<span class="number">0</span>]</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">1</span>,n):</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> range(i):</span><br><span class="line"> <span class="keyword">if</span> inputdata[i] > inputdata[j]:</span><br><span class="line"> s = s+<span class="number">1</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> s = s+<span class="number">0</span></span><br><span class="line"> Sk.append(s)</span><br><span class="line"> Exp_value.append((i+<span class="number">1</span>)*(i+<span class="number">2</span>)/<span class="number">4</span> ) </span><br><span class="line"> Var_value.append((i+<span class="number">1</span>)*i*(<span class="number">2</span>*(i+<span class="number">1</span>)+<span class="number">5</span>)/<span class="number">72</span> ) </span><br><span class="line"> UFk.append((Sk[i]-Exp_value[i])/np.sqrt(Var_value[i]))</span><br><span class="line"> Sk2 = [<span class="number">0</span>]</span><br><span class="line"> UBk = [<span class="number">0</span>]</span><br><span class="line"> UBk2 = [<span class="number">0</span>]</span><br><span class="line"> s2 = <span class="number">0</span></span><br><span class="line"> Exp_value2 = [<span class="number">0</span>]</span><br><span class="line"> Var_value2 = [<span class="number">0</span>]</span><br><span class="line"> inputdataT = list(reversed(inputdata))</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">1</span>,n):</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> range(i):</span><br><span class="line"> <span class="keyword">if</span> inputdataT[i] > inputdataT[j]:</span><br><span class="line"> s2 = s2+<span class="number">1</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> s2 = s2+<span class="number">0</span></span><br><span class="line"> Sk2.append(s2)</span><br><span class="line"> Exp_value2.append((i+<span class="number">1</span>)*(i+<span class="number">2</span>)/<span class="number">4</span> ) </span><br><span class="line"> Var_value2.append((i+<span class="number">1</span>)*i*(<span class="number">2</span>*(i+<span class="number">1</span>)+<span class="number">5</span>)/<span class="number">72</span> ) </span><br><span class="line"> UBk.append((Sk2[i]-Exp_value2[i])/np.sqrt(Var_value2[i]))</span><br><span class="line"> UBk2.append(-UBk[i])</span><br><span class="line"> UBkT = list(reversed(UBk2))</span><br><span class="line"> <span class="keyword">return</span> UFk, UBkT</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> scipy <span class="keyword">import</span> signal</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line">y = np.array([<span class="number">15.4</span>,<span class="number">14.6</span>,<span class="number">15.8</span>,<span class="number">14.8</span>,<span class="number">15.0</span>,<span class="number">15.1</span>,<span class="number">15.1</span>,<span class="number">15.0</span>,<span class="number">15.2</span>,<span class="number">15.4</span>,</span><br><span class="line"> <span class="number">14.8</span>,<span class="number">15.0</span>,<span class="number">15.1</span>,<span class="number">14.7</span>,<span class="number">16.0</span>,<span class="number">15.7</span>,<span class="number">15.4</span>,<span class="number">14.5</span>,<span class="number">15.1</span>,<span class="number">15.3</span>,</span><br><span class="line"> <span class="number">15.5</span>,<span class="number">15.1</span>,<span class="number">15.6</span>,<span class="number">15.1</span>,<span class="number">15.1</span>,<span class="number">14.9</span>,<span class="number">15.5</span>,<span class="number">15.3</span>,<span class="number">15.3</span>,<span class="number">15.4</span>,</span><br><span class="line"> <span class="number">15.7</span>,<span class="number">15.2</span>,<span class="number">15.5</span>,<span class="number">15.5</span>,<span class="number">15.6</span>,<span class="number">15.1</span>,<span class="number">15.1</span>,<span class="number">16.0</span>,<span class="number">16.0</span>,<span class="number">16.8</span>,</span><br><span class="line"> <span class="number">16.2</span>,<span class="number">16.2</span>,<span class="number">16.0</span>,<span class="number">15.6</span>,<span class="number">15.9</span>,<span class="number">16.2</span>,<span class="number">16.7</span>,<span class="number">15.8</span>,<span class="number">16.2</span>,<span class="number">15.9</span>,</span><br><span class="line"> <span class="number">15.8</span>,<span class="number">15.5</span>,<span class="number">15.9</span>,<span class="number">16.8</span>,<span class="number">15.5</span>,<span class="number">15.8</span>,<span class="number">15.0</span>,<span class="number">14.9</span>,<span class="number">15.3</span>,<span class="number">16.0</span>,</span><br><span class="line"> <span class="number">16.1</span>,<span class="number">16.5</span>,<span class="number">15.5</span>,<span class="number">15.6</span>,<span class="number">16.1</span>,<span class="number">15.6</span>,<span class="number">16.0</span>,<span class="number">15.4</span>,<span class="number">15.5</span>,<span class="number">15.2</span>,</span><br><span class="line"> <span class="number">15.4</span>,<span class="number">15.6</span>,<span class="number">15.1</span>,<span class="number">15.8</span>,<span class="number">15.5</span>,<span class="number">16.0</span>,<span class="number">15.2</span>,<span class="number">15.8</span>,<span class="number">16.2</span>,<span class="number">16.2</span>,</span><br><span class="line"> <span class="number">15.2</span>,<span class="number">15.7</span>,<span class="number">16.0</span>,<span class="number">16.0</span>,<span class="number">15.7</span>,<span class="number">15.9</span>,<span class="number">15.7</span>,<span class="number">16.7</span>,<span class="number">15.3</span>,<span class="number">16.1</span>])</span><br><span class="line"></span><br><span class="line">uf,uk = mktest(y)</span><br><span class="line"></span><br><span class="line">fig = plt.figure(figsize=(<span class="number">15</span>,<span class="number">15</span>))</span><br><span class="line">f_ax1 = fig.add_axes([<span class="number">0.1</span>, <span class="number">0.1</span>, <span class="number">0.4</span>, <span class="number">0.3</span>])</span><br><span class="line">f_ax1.plot(np.arange(<span class="number">1900</span>,<span class="number">1990</span>,<span class="number">1</span>),y,<span class="string">'k'</span>)</span><br><span class="line"></span><br><span class="line">f_ax2 = fig.add_axes([<span class="number">0.6</span>, <span class="number">0.1</span>, <span class="number">0.4</span>, <span class="number">0.3</span>])</span><br><span class="line">f_ax2.plot(np.arange(<span class="number">1900</span>,<span class="number">1990</span>,<span class="number">1</span>),uf,<span class="string">'b'</span>,label=<span class="string">'UF'</span>)</span><br><span class="line">f_ax2.plot(np.arange(<span class="number">1900</span>,<span class="number">1990</span>,<span class="number">1</span>),uk,<span class="string">'r'</span>,label=<span class="string">'UK'</span>)</span><br><span class="line">f_ax2.set_xlim(<span class="number">1900</span>,<span class="number">1990</span>)</span><br><span class="line">f_ax2.set_ylim(<span class="number">-4</span>,<span class="number">7</span>)</span><br><span class="line"><span class="comment"># 0.01显著性检验</span></span><br><span class="line">f_ax2.axhline(<span class="number">1.96</span>)</span><br><span class="line">f_ax2.axhline(<span class="number">-1.96</span>)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="/image/image-20200521090912932.png" alt="image-20200521090912932"></p>]]></content>
<categories>
<category> Function </category>
</categories>
</entry>
<entry>
<title>滑动t检验</title>
<link href="/2020/05/21/f1-3-1-1/"/>
<url>/2020/05/21/f1-3-1-1/</url>
<content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">'''</span></span><br><span class="line"><span class="string">滑动t检验</span></span><br><span class="line"><span class="string">输入:</span></span><br><span class="line"><span class="string">inputdata:输入数据,一维序列</span></span><br><span class="line"><span class="string">step:滑动步长</span></span><br><span class="line"><span class="string">输出:t1:t统计量</span></span><br><span class="line"><span class="string">注:自由度v =2*n-2</span></span><br><span class="line"><span class="string">'''</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">slide_t</span><span class="params">(inputdata,step)</span>:</span></span><br><span class="line"> inputdata = np.array(inputdata)</span><br><span class="line"> n = inputdata.shape[<span class="number">0</span>]</span><br><span class="line"> t = np.zeros(n)</span><br><span class="line"> t1 = np.empty(n)</span><br><span class="line"> n1 = step <span class="comment">#n1, n2为滑动步长,需调整</span></span><br><span class="line"> n2 = step</span><br><span class="line"> n11 = <span class="number">1</span> / n1</span><br><span class="line"> n22 = <span class="number">1</span> / n2</span><br><span class="line"> m = np.sqrt(n11 + n22)</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range (step, n-step+<span class="number">1</span>):</span><br><span class="line"> x1_mean = np.mean(inputdata[i-step : i]) </span><br><span class="line"> x2_mean = np.mean(inputdata[i : i+step])</span><br><span class="line"> s1 = np.var(inputdata[i-step : i]) </span><br><span class="line"> s2 = np.var(inputdata[i : i+step])</span><br><span class="line"> s = np.sqrt((n1 * s1 + n2 * s2) / (n1 + n2 - <span class="number">2</span>))</span><br><span class="line"> t[i-step] = (x2_mean - x1_mean) / (s * m)</span><br><span class="line"> t1 = np.roll(t , step<span class="number">-1</span>)</span><br><span class="line"> t1[:step]=np.nan </span><br><span class="line"> t1[n-step+<span class="number">1</span>:]=np.nan </span><br><span class="line"> <span class="keyword">return</span> t1</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> scipy <span class="keyword">import</span> signal</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line">y = np.array([<span class="number">15.4</span>,<span class="number">14.6</span>,<span class="number">15.8</span>,<span class="number">14.8</span>,<span class="number">15.0</span>,<span class="number">15.1</span>,<span class="number">15.1</span>,<span class="number">15.0</span>,<span class="number">15.2</span>,<span class="number">15.4</span>,</span><br><span class="line"> <span class="number">14.8</span>,<span class="number">15.0</span>,<span class="number">15.1</span>,<span class="number">14.7</span>,<span class="number">16.0</span>,<span class="number">15.7</span>,<span class="number">15.4</span>,<span class="number">14.5</span>,<span class="number">15.1</span>,<span class="number">15.3</span>,</span><br><span class="line"> <span class="number">15.5</span>,<span class="number">15.1</span>,<span class="number">15.6</span>,<span class="number">15.1</span>,<span class="number">15.1</span>,<span class="number">14.9</span>,<span class="number">15.5</span>,<span class="number">15.3</span>,<span class="number">15.3</span>,<span class="number">15.4</span>,</span><br><span class="line"> <span class="number">15.7</span>,<span class="number">15.2</span>,<span class="number">15.5</span>,<span class="number">15.5</span>,<span class="number">15.6</span>,<span class="number">15.1</span>,<span class="number">15.1</span>,<span class="number">16.0</span>,<span class="number">16.0</span>,<span class="number">16.8</span>,</span><br><span class="line"> <span class="number">16.2</span>,<span class="number">16.2</span>,<span class="number">16.0</span>,<span class="number">15.6</span>,<span class="number">15.9</span>,<span class="number">16.2</span>,<span class="number">16.7</span>,<span class="number">15.8</span>,<span class="number">16.2</span>,<span class="number">15.9</span>,</span><br><span class="line"> <span class="number">15.8</span>,<span class="number">15.5</span>,<span class="number">15.9</span>,<span class="number">16.8</span>,<span class="number">15.5</span>,<span class="number">15.8</span>,<span class="number">15.0</span>,<span class="number">14.9</span>,<span class="number">15.3</span>,<span class="number">16.0</span>,</span><br><span class="line"> <span class="number">16.1</span>,<span class="number">16.5</span>,<span class="number">15.5</span>,<span class="number">15.6</span>,<span class="number">16.1</span>,<span class="number">15.6</span>,<span class="number">16.0</span>,<span class="number">15.4</span>,<span class="number">15.5</span>,<span class="number">15.2</span>,</span><br><span class="line"> <span class="number">15.4</span>,<span class="number">15.6</span>,<span class="number">15.1</span>,<span class="number">15.8</span>,<span class="number">15.5</span>,<span class="number">16.0</span>,<span class="number">15.2</span>,<span class="number">15.8</span>,<span class="number">16.2</span>,<span class="number">16.2</span>,</span><br><span class="line"> <span class="number">15.2</span>,<span class="number">15.7</span>,<span class="number">16.0</span>,<span class="number">16.0</span>,<span class="number">15.7</span>,<span class="number">15.9</span>,<span class="number">15.7</span>,<span class="number">16.7</span>,<span class="number">15.3</span>,<span class="number">16.1</span>])</span><br><span class="line"></span><br><span class="line">t = slide_t(y,<span class="number">10</span>)</span><br><span class="line"></span><br><span class="line">fig = plt.figure(figsize=(<span class="number">15</span>,<span class="number">15</span>))</span><br><span class="line">f_ax1 = fig.add_axes([<span class="number">0.1</span>, <span class="number">0.1</span>, <span class="number">0.4</span>, <span class="number">0.3</span>])</span><br><span class="line">f_ax1.plot(np.arange(<span class="number">1900</span>,<span class="number">1990</span>,<span class="number">1</span>),y,<span class="string">'k'</span>)</span><br><span class="line"></span><br><span class="line">f_ax2 = fig.add_axes([<span class="number">0.6</span>, <span class="number">0.1</span>, <span class="number">0.4</span>, <span class="number">0.3</span>])</span><br><span class="line">f_ax2.plot(np.arange(<span class="number">1900</span>,<span class="number">1990</span>,<span class="number">1</span>),t,<span class="string">'k'</span>)</span><br><span class="line">f_ax2.set_xlim(<span class="number">1900</span>,<span class="number">1990</span>)</span><br><span class="line">f_ax2.set_ylim(<span class="number">-4</span>,<span class="number">7</span>)</span><br><span class="line"><span class="comment"># 0.01显著性检验</span></span><br><span class="line">f_ax2.axhline(<span class="number">2.9</span>)</span><br><span class="line">f_ax2.axhline(<span class="number">-2.9</span>)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="/image/image-20200521090717453.png" alt="image-20200521090717453"></p>]]></content>
<categories>
<category> Function </category>
</categories>
</entry>
<entry>
<title>线性倾向估计(一元线性回归)</title>
<link href="/2020/05/19/f1-2-1-1/"/>
<url>/2020/05/19/f1-2-1-1/</url>
<content type="html"><![CDATA[<p>除1.132节介绍的的线性回归系数可用来计算线性回归外,sklearn库中也有相关的函数用来计算一元线性回归,同时还可以输出回归线,为数据可视化提供了便利。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sklearn.linear_model <span class="keyword">import</span> LinearRegression</span><br><span class="line">LinearRegression(fit_intercept=<span class="literal">True</span>, normalize=<span class="literal">False</span>, copy_X=<span class="literal">True</span>)</span><br></pre></td></tr></table></figure><p>参数:</p><p>fit_intercept :是否计算截距,若数据已中心化,则可以不计算。默认True。</p><p>normalize :若开启,则对数据进行归一化处理。</p><p>copy_X :若开启,则复制X,否则对X进行重写覆盖。</p><p>属性:</p><p>coef_ :线性回归系数</p><p>intercept_ : 截距</p><p>方法:</p><p>fit(x,y) :建立x,y的回归模型</p><p>predict(x) :利用回归模型进行预测</p><p>score(x, y[, sample_weight]) :返回R^2</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sklearn.linear_model <span class="keyword">import</span> LinearRegression</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> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="comment">#建立数据</span></span><br><span class="line">x = np.arange(<span class="number">2000</span>,<span class="number">2011</span>,<span class="number">1</span>).reshape(<span class="number">-1</span>, <span class="number">1</span>)</span><br><span class="line">y = np.array([<span class="number">3.9</span>, <span class="number">4.4</span>, <span class="number">10.8</span>, <span class="number">10.3</span>, <span class="number">11.2</span>, <span class="number">13.1</span>, <span class="number">14.1</span>, <span class="number">9.9</span>, <span class="number">13.9</span>, <span class="number">15.1</span>, <span class="number">12.5</span>]).reshape(<span class="number">-1</span>,<span class="number">1</span>)</span><br><span class="line"><span class="comment">#创建回归模型</span></span><br><span class="line">solver = LinearRegression()</span><br><span class="line"><span class="comment">#对x,y进行回归计算</span></span><br><span class="line">solver.fit(x,y)</span><br><span class="line"><span class="comment">#计算x对应的回归值</span></span><br><span class="line">regressline = solver.predict(x)</span><br><span class="line"><span class="comment">#绘图</span></span><br><span class="line">plt.scatter(x,y)</span><br><span class="line">plt.plot(x, regressline, color=<span class="string">'k'</span>,linewidth=<span class="number">3</span>)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="/image/image-20200519214110927.png" alt="image-20200519214110927"></p><p>该方法较1.132节相对繁琐,甚至有些小题大做。因为该方法主要用于通过已有数据建立回归模型,对未知数据进行一元回归预测,在机器学习中使用更为广泛,在此处,仅仅体现了较为方便的回归线的绘制。</p>]]></content>
<categories>
<category> Function </category>
</categories>
</entry>
<entry>
<title>滑动平均</title>
<link href="/2020/05/19/f1-2-2-1/"/>
<url>/2020/05/19/f1-2-2-1/</url>
<content type="html"><![CDATA[<p>滑动平均是趋势拟合的基础方法,也相当于一个滤波器,比如使用九点滑动平均来分析时间序列的年代际变化。 python的常用算法库中并未给出直接计算滑动平均的函数。但是numpy库中给出了一个更加强大更加基础的函数,卷积numpy.convolve()。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">numpy.convolve(a, v, mode=<span class="string">'full'</span>)</span><br></pre></td></tr></table></figure><p>参数:</p><p> a:(N,)一维数组</p><p> v:(M,)一维数组</p><p> mode:{‘full’, ‘valid’, ‘same’}参数可选</p><p> ‘full’ 默认值,返回每一个卷积值,长度是N+M-1,在卷积的边缘处,信号不重叠,存在边际效应。</p><p> ‘same’ 返回的数组长度为max(M, N),存在边际效应。</p><p> ‘valid’ 返回的数组长度为max(M,N)-min(M,N)+1,此时返回的是完全重叠的点。无边际效应。</p><p>通俗地讲,a是原始序列,v是卷积核。将上述函数转化为滑动平均的原理,就是设置一个等权重的卷积核,对原始序列进行卷积运算即可。实际上,卷积运算就是滑动平均的推广。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">np_move_avg</span><span class="params">(a,n,mode)</span>:</span></span><br><span class="line"> <span class="keyword">return</span>(np.convolve(a, np.repeat(<span class="number">1</span>/n, n), mode=mode))</span><br></pre></td></tr></table></figure><p>参数:</p><p> a:(N,)一维数组</p><p> n:int型整数,n=9即为9点滑动平均</p><p> mode 等同numpy.convolve()中的参数mode</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><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 class="function"><span class="keyword">def</span> <span class="title">np_move_avg</span><span class="params">(a,n,mode)</span>:</span></span><br><span class="line"> <span class="keyword">return</span>(np.convolve(a, np.repeat(<span class="number">1</span>/n, n), mode=mode))</span><br><span class="line"></span><br><span class="line">y = np.array([<span class="number">6.08</span>, <span class="number">4.56</span>, <span class="number">5.63</span>, <span class="number">5.31</span>, <span class="number">5.15</span>, <span class="number">5.44</span>, <span class="number">4.65</span>, <span class="number">4.24</span>, <span class="number">7.3</span>, <span class="number">5.86</span>, <span class="number">4.51</span>, <span class="number">6.28</span>, <span class="number">5.55</span>, <span class="number">5.35</span>,</span><br><span class="line"> <span class="number">5.12</span>, <span class="number">4.76</span>, <span class="number">4.35</span>, <span class="number">3.76</span>, <span class="number">4.74</span>, <span class="number">5.55</span>, <span class="number">4.54</span>, <span class="number">5.74</span>, <span class="number">5.54</span>, <span class="number">3.67</span>, <span class="number">4.77</span>, <span class="number">4.9</span>, <span class="number">3.06</span>, <span class="number">3.9</span>,</span><br><span class="line"> <span class="number">4.18</span>, <span class="number">5.44</span>, <span class="number">5.21</span>, <span class="number">3.86</span>, <span class="number">3.96</span>, <span class="number">4.47</span>, <span class="number">4.37</span>, <span class="number">4.86</span>, <span class="number">4.43</span>, <span class="number">3.63</span>, <span class="number">3.98</span>, <span class="number">3.94</span>, <span class="number">5.09</span>, <span class="number">4.48</span>,</span><br><span class="line"> <span class="number">4.05</span>, <span class="number">4.81</span>, <span class="number">4.07</span>, <span class="number">4.48</span>, <span class="number">4.46</span>, <span class="number">3.95</span>, <span class="number">5.24</span>, <span class="number">3.54</span>, <span class="number">3.11</span>, <span class="number">5.07</span>, <span class="number">6.09</span>, <span class="number">4.59</span>, <span class="number">4.55</span>, <span class="number">4.7</span>,</span><br><span class="line"> <span class="number">3.43</span>, <span class="number">4.37</span>, <span class="number">4.79</span>, <span class="number">3.64</span>, <span class="number">4.3</span>, <span class="number">3.5</span> ])</span><br><span class="line">y_smooth9_full = np_move_avg(y,<span class="number">9</span>,<span class="string">'full'</span>)</span><br><span class="line">y_smooth9_same = np_move_avg(y,<span class="number">9</span>,<span class="string">'same'</span>)</span><br><span class="line">y_smooth9_valid = np_move_avg(y,<span class="number">9</span>,<span class="string">'valid'</span>)</span><br><span class="line"></span><br><span class="line">plt.plot(np.arange(<span class="number">0</span>,<span class="number">62</span>,<span class="number">1</span>),y,<span class="string">'k'</span>,label=<span class="string">'y'</span>)</span><br><span class="line">plt.plot(np.arange(<span class="number">0</span>,<span class="number">62</span>+<span class="number">8</span>,<span class="number">1</span>),y_smooth9_full,<span class="string">'r'</span>,label=<span class="string">'full'</span>)</span><br><span class="line">plt.plot(np.arange(<span class="number">0</span>,<span class="number">62</span>,<span class="number">1</span>),y_smooth9_same,<span class="string">'b'</span>,label=<span class="string">'same'</span>)</span><br><span class="line">plt.plot(np.arange(<span class="number">0</span>+<span class="number">4</span>,<span class="number">62</span><span class="number">-4</span>,<span class="number">1</span>),y_smooth9_valid,<span class="string">'g'</span>,label=<span class="string">'valid'</span>)</span><br><span class="line">plt.legend()</span><br></pre></td></tr></table></figure><p><img src="/image/image-20200519214305477.png" alt="image-20200519214305477"></p>]]></content>
<categories>
<category> Function </category>
</categories>
</entry>
<entry>
<title>去趋势</title>
<link href="/2020/05/19/f1-2-3-1/"/>
<url>/2020/05/19/f1-2-3-1/</url>
<content type="html"><![CDATA[<p>去趋势主要指的是去除带有趋势的序列中的线性趋势。scipy库提供了对应的函数以实现这一目的。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">scipy.signal.detrend(data, axis=<span class="number">-1</span>, type=<span class="string">'linear'</span>, bp=<span class="number">0</span>, overwrite_data=<span class="literal">False</span>)</span><br></pre></td></tr></table></figure><p>参数:</p><p> data: 数组</p><p> axis: 整形,去趋势的维度</p><p> type:{‘linear’, ‘constant’}参数可选</p><p> ‘linear’ 默认值,数据减去线性最小二乘法拟合的结果</p><p> ‘constant’ 去掉序列的均值,即求距平</p><p> bp:整形,一系列的断点。如果给定,则在两个断点之间对数据的每个部分执行单独的线性拟合。断点被 指定为数据的索引</p><p> overwrite_data :布尔型,默认为False,若为真则结果覆盖data</p><p>注:由于是扣除了最小二乘法拟合,因此最终结果与原始序列均值之和才是原始数据去除线性趋势的结果。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> scipy <span class="keyword">import</span> signal</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">y = np.array([<span class="number">6.08</span>, <span class="number">4.56</span>, <span class="number">5.63</span>, <span class="number">5.31</span>, <span class="number">5.15</span>, <span class="number">5.44</span>, <span class="number">4.65</span>, <span class="number">4.24</span>, <span class="number">7.3</span>, <span class="number">5.86</span>, <span class="number">4.51</span>, <span class="number">6.28</span>, <span class="number">5.55</span>, <span class="number">5.35</span>,</span><br><span class="line"> <span class="number">5.12</span>, <span class="number">4.76</span>, <span class="number">4.35</span>, <span class="number">3.76</span>, <span class="number">4.74</span>, <span class="number">5.55</span>, <span class="number">4.54</span>, <span class="number">5.74</span>, <span class="number">5.54</span>, <span class="number">3.67</span>, <span class="number">4.77</span>, <span class="number">4.9</span>, <span class="number">3.06</span>, <span class="number">3.9</span>,</span><br><span class="line"> <span class="number">4.18</span>, <span class="number">5.44</span>, <span class="number">5.21</span>, <span class="number">3.86</span>, <span class="number">3.96</span>, <span class="number">4.47</span>, <span class="number">4.37</span>, <span class="number">4.86</span>, <span class="number">4.43</span>, <span class="number">3.63</span>, <span class="number">3.98</span>, <span class="number">3.94</span>, <span class="number">5.09</span>, <span class="number">4.48</span>,</span><br><span class="line"> <span class="number">4.05</span>, <span class="number">4.81</span>, <span class="number">4.07</span>, <span class="number">4.48</span>, <span class="number">4.46</span>, <span class="number">3.95</span>, <span class="number">5.24</span>, <span class="number">3.54</span>, <span class="number">3.11</span>, <span class="number">5.07</span>, <span class="number">6.09</span>, <span class="number">4.59</span>, <span class="number">4.55</span>, <span class="number">4.7</span>,</span><br><span class="line"> <span class="number">3.43</span>, <span class="number">4.37</span>, <span class="number">4.79</span>, <span class="number">3.64</span>, <span class="number">4.3</span>, <span class="number">3.5</span> ])</span><br><span class="line">y_detrend_linear = signal.detrend(y,axis = <span class="number">0</span>,type=<span class="string">'linear'</span>)</span><br><span class="line">y_detrend_constant = signal.detrend(y,axis = <span class="number">0</span>,type=<span class="string">'constant'</span>)</span><br><span class="line">plt.plot(np.arange(<span class="number">0</span>,<span class="number">62</span>,<span class="number">1</span>),y,<span class="string">'k'</span>,label=<span class="string">'y'</span>)</span><br><span class="line">plt.plot(np.arange(<span class="number">0</span>,<span class="number">62</span>,<span class="number">1</span>),y_detrend_linear+y.mean(),<span class="string">'r'</span>,label=<span class="string">'linear'</span>)</span><br><span class="line">plt.legend()</span><br></pre></td></tr></table></figure><p><img src="/image/image-20200519214452584.png" alt="image-20200519214452584"></p>]]></content>
<categories>
<category> Function </category>
</categories>
</entry>
<entry>
<title>滤波(Butterworth滤波器)</title>
<link href="/2020/05/19/f1-2-4-1/"/>
<url>/2020/05/19/f1-2-4-1/</url>
<content type="html"><![CDATA[<p>分析气候变化趋势中常用的方法还有滤波技术,主要分为低通滤波,高通滤波以及带通滤波。Scipy库中提供了构造Butterworth滤波器的函数。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">scipy.signal.butter(N, Wn, btype=<span class="string">'low'</span>, analog=<span class="literal">False</span>, output=<span class="string">'ba'</span>)</span><br></pre></td></tr></table></figure><p>参数:</p><p> N: 滤波器阶数</p><p> Wn: 归一化的截止频率。计算公式为Wn=2*截止频率/采样频率。(注意:采样频率要大于两倍的信号本身最大的频率,才能还原信号。截止频率一定小于信号本身最大的频率,所以Wn一定在0和1之间)。当构造带通滤波器或者带阻滤波器时,Wn为长度为2的列表。</p><p> btype:{‘lowpass’, ‘highpass’, ‘bandpass’, ‘bandstop’}参数可选</p><p> ‘lowpass’ 默认值,低通滤波</p><p> ‘highpass’ 高通滤波</p><p> ‘bandpass’ 带通滤波</p><p> ‘bandstop’ 阻通滤波</p><p>analog:若为True,返回模拟滤波器,否则为数字滤波器</p><p>默认设置下,构造滤波器函数会返回滤波器的分子系数向量b和滤波器的分母系数向量a。</p><p>滤波器构建成功后,即可对数据进行滤波。滤波函数:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">scipy.signal.filtfilt(b, a, x, axis=<span class="number">-1</span>, padtype=<span class="string">'odd'</span>, padlen=<span class="literal">None</span>, method=<span class="string">'pad'</span>, irlen=<span class="literal">None</span>)</span><br></pre></td></tr></table></figure><p>参数:</p><p> b: 滤波器的分子系数向量</p><p> a: 滤波器的分母系数向量</p><p> x: 要过滤的数据数组</p><p> x: 指定要过滤的数据数组的x维</p><p> padtype: {‘odd’, ‘even’, ‘constant’, None} 参数可选,默认为’odd’</p><p> padlen:整形,在应用滤波器之前在轴两端延伸的元素数。此值必须小于要滤波元素个数-1</p><p> method:确定处理信号边缘的方法,{‘pad’ ,’gust’}参数可选</p><p> ‘pad’ 填充信号;填充类型padtype和padlen决定,irlen被忽略</p><p> ‘gust’ 使用古斯塔夫森方法,而忽略padtype和padlen</p><p> irlen:当method为’gust’时,irlen指定滤波器的响应长度。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> scipy <span class="keyword">import</span> signal</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">y = np.array([<span class="number">6.08</span>, <span class="number">4.56</span>, <span class="number">5.63</span>, <span class="number">5.31</span>, <span class="number">5.15</span>, <span class="number">5.44</span>, <span class="number">4.65</span>, <span class="number">4.24</span>, <span class="number">7.3</span>, <span class="number">5.86</span>, <span class="number">4.51</span>, <span class="number">6.28</span>, <span class="number">5.55</span>, <span class="number">5.35</span>,</span><br><span class="line"> <span class="number">5.12</span>, <span class="number">4.76</span>, <span class="number">4.35</span>, <span class="number">3.76</span>, <span class="number">4.74</span>, <span class="number">5.55</span>, <span class="number">4.54</span>, <span class="number">5.74</span>, <span class="number">5.54</span>, <span class="number">3.67</span>, <span class="number">4.77</span>, <span class="number">4.9</span>, <span class="number">3.06</span>, <span class="number">3.9</span>,</span><br><span class="line"> <span class="number">4.18</span>, <span class="number">5.44</span>, <span class="number">5.21</span>, <span class="number">3.86</span>, <span class="number">3.96</span>, <span class="number">4.47</span>, <span class="number">4.37</span>, <span class="number">4.86</span>, <span class="number">4.43</span>, <span class="number">3.63</span>, <span class="number">3.98</span>, <span class="number">3.94</span>, <span class="number">5.09</span>, <span class="number">4.48</span>,</span><br><span class="line"> <span class="number">4.05</span>, <span class="number">4.81</span>, <span class="number">4.07</span>, <span class="number">4.48</span>, <span class="number">4.46</span>, <span class="number">3.95</span>, <span class="number">5.24</span>, <span class="number">3.54</span>, <span class="number">3.11</span>, <span class="number">5.07</span>, <span class="number">6.09</span>, <span class="number">4.59</span>, <span class="number">4.55</span>, <span class="number">4.7</span>,</span><br><span class="line"> <span class="number">3.43</span>, <span class="number">4.37</span>, <span class="number">4.79</span>, <span class="number">3.64</span>, <span class="number">4.3</span>, <span class="number">3.5</span> ])</span><br><span class="line"><span class="comment">####高通滤波####</span></span><br><span class="line">b, a = signal.butter(<span class="number">3</span>, <span class="number">2</span>/<span class="number">3</span>, <span class="string">'highpass'</span>)</span><br><span class="line">high_series = signal.filtfilt(b, a, y)</span><br><span class="line">plt.plot(np.arange(<span class="number">0</span>,<span class="number">62</span>,<span class="number">1</span>),y,<span class="string">'k'</span>,label=<span class="string">'y'</span>)</span><br><span class="line">plt.plot(np.arange(<span class="number">0</span>,<span class="number">62</span>,<span class="number">1</span>),high_series+y.mean(),<span class="string">'r'</span>,label=<span class="string">'highpass'</span>)</span><br><span class="line">plt.legend()</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="/image/image-20200519214619977.png" alt="image-20200519214619977"></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">####低通滤波####获得10年以上的信号</span></span><br><span class="line">b, a = signal.butter(<span class="number">3</span>, <span class="number">2</span>/<span class="number">10</span>, <span class="string">'lowpass'</span>)</span><br><span class="line">low_series = signal.filtfilt(b, a, y)</span><br><span class="line">plt.plot(np.arange(<span class="number">0</span>,<span class="number">62</span>,<span class="number">1</span>),y,<span class="string">'k'</span>,label=<span class="string">'y'</span>)</span><br><span class="line">plt.plot(np.arange(<span class="number">0</span>,<span class="number">62</span>,<span class="number">1</span>),low_series,<span class="string">'r'</span>,label=<span class="string">'lowpass'</span>)</span><br><span class="line">plt.legend()</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="/image/image-20200519214647083.png" alt="image-20200519214647083"></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">####带通滤波####获得3-10年间的信号</span></span><br><span class="line">b, a = signal.butter(<span class="number">3</span>, [<span class="number">2</span>/<span class="number">10</span>,<span class="number">2</span>/<span class="number">3</span>], <span class="string">'bandpass'</span>)</span><br><span class="line">low_series = signal.filtfilt(b, a, y)</span><br><span class="line">plt.plot(np.arange(<span class="number">0</span>,<span class="number">62</span>,<span class="number">1</span>),y,<span class="string">'k'</span>,label=<span class="string">'y'</span>)</span><br><span class="line">plt.plot(np.arange(<span class="number">0</span>,<span class="number">62</span>,<span class="number">1</span>),low_series+y.mean(),<span class="string">'r'</span>,label=<span class="string">'bandpass'</span>)</span><br><span class="line">plt.legend()</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="/image/image-20200519214659491.png" alt="image-20200519214659491"></p>]]></content>
<categories>
<category> Function </category>
</categories>
</entry>
<entry>
<title>数据标准化</title>
<link href="/2020/05/19/f1-1-4-1/"/>
<url>/2020/05/19/f1-1-4-1/</url>
<content type="html"><![CDATA[<p>将以下内容复制进A.py文件,与使用脚本放在同一文件夹内,通过import A 调用。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">'''</span></span><br><span class="line"><span class="string">function :standardized(x,a)</span></span><br><span class="line"><span class="string">将数据标准化。 </span></span><br><span class="line"><span class="string">对x的a轴标准化。</span></span><br><span class="line"><span class="string">x为序列或数组,</span></span><br><span class="line"><span class="string">a为int;如1或(0,1)</span></span><br><span class="line"><span class="string">'''</span></span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">standardized</span><span class="params">(x,a)</span>:</span></span><br><span class="line"> y = (x - x.mean(axis=(a)))/x.std(axis=(a))</span><br><span class="line"> <span class="keyword">return</span> y</span><br><span class="line">improt A</span><br><span class="line">standardized(x,a)</span><br></pre></td></tr></table></figure><p>x为任意形状数组,函数对x的a轴进行标准化,</p><p>a为int型;如1或(0,1)。</p>]]></content>
<categories>
<category> Function </category>
</categories>
</entry>
<entry>
<title>线性回归系数</title>
<link href="/2020/05/19/f1-1-3-2/"/>
<url>/2020/05/19/f1-1-3-2/</url>
<content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> scipy <span class="keyword">import</span> stats</span><br><span class="line">stats.linregress(x, y)</span><br></pre></td></tr></table></figure><p>输入:</p><p>x:输入数据1(1维序列)</p><p>y:输入数据2(1维序列)</p><p>返回:</p><p>slope:回归斜率</p><p>intercept:回归截距</p><p>r-value :相关系数</p><p>p-value :假设检验的双侧p值,其零假设是斜率为零</p><p>stderr :标准误差估计</p><p>同相关系数一致,该函数优点在于可以直接输出P值,省去了再次计算置信区间的步骤,缺点在于仅适用于两个一维序列。</p><p>改进:将以下内容复制进A.py文件,与使用脚本放在同一文件夹内,通过import A 调用。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">'''</span></span><br><span class="line"><span class="string">function :linearregress(x,y,opt)</span></span><br><span class="line"><span class="string">计算x与y的相关系数,及其双尾P值。 </span></span><br><span class="line"><span class="string">x必须为一维数组</span></span><br><span class="line"><span class="string">y可以为一维数组或三维数组,若y为一维数组,opt为1,计算两序列线性回归;</span></span><br><span class="line"><span class="string">若y为三维数组,则时间维度必须在最左边,即axis=0,opt =2,计算序列和场的线性回归。</span></span><br><span class="line"><span class="string">返回slope, intercept, r_value, p_value, std_err</span></span><br><span class="line"><span class="string">'''</span></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> scipy <span class="keyword">import</span> stats</span><br><span class="line"><span class="keyword">from</span> numba <span class="keyword">import</span> jit</span><br><span class="line"><span class="meta">@jit</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">linearregress</span><span class="params">(x,y,opt)</span>:</span></span><br><span class="line"> <span class="keyword">if</span> opt==<span class="number">1</span>:</span><br><span class="line"> slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)</span><br><span class="line"> <span class="keyword">elif</span> opt ==<span class="number">2</span>:</span><br><span class="line"> lat = y.shape[<span class="number">1</span>]</span><br><span class="line"> lon = y.shape[<span class="number">2</span>]</span><br><span class="line"> slope, intercept, r_value, p_value, std_err = np.zeros((lat,lon)),np.zeros((lat,lon)),np.zeros((lat,lon)),np.zeros((lat,lon))</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(lat):</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> range(lon):</span><br><span class="line"> slope[i,j], intercept[i,j], r_value[i,j], p_value[i,j], std_err[i,j] = stats.linregress(x,y[:,i,j])</span><br><span class="line"> <span class="keyword">return</span> slope, intercept, r_value, p_value, std_err</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> A</span><br><span class="line">slope, intercept, r_value, p_value, std_err = linearregress(x,y,opt)</span><br></pre></td></tr></table></figure><p>x必须为一维数组</p><p>y可以为一维数组或三维数组,若y为一维数组,opt为1,计算两序列线性回归;</p><p>若y为三维数组,则时间维度必须在最左边,即axis=0,opt =2,计算序列和气候要素场的线性回归。</p><p>返回slope, intercept, r_value, p_value, std_err</p>]]></content>
<categories>
<category> Function </category>
</categories>
</entry>
<entry>
<title>皮尔逊相关系数</title>
<link href="/2020/05/19/f1-1-3-1/"/>
<url>/2020/05/19/f1-1-3-1/</url>
<content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> scipy.stats <span class="keyword">import</span> pearsonr</span><br><span class="line">pearsonr(x,r)</span><br></pre></td></tr></table></figure><p>输入:</p><p>x:输入数据1(1维序列)</p><p>y:输入数据2(1维序列)</p><p>返回:</p><p>r:皮尔逊相关系数</p><p>p-value :双尾P值</p><p>该函数优点在于可以直接输出P值,省去了再次计算置信区间的步骤,缺点在于仅适用于两个一维序列。</p><p>改进: 将以下内容复制进*.py文件,与使用脚本放在同一文件夹内,通过import * 调用。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">'''</span></span><br><span class="line"><span class="string">function :escorc(x,y,opt)</span></span><br><span class="line"><span class="string">计算x与y的相关系数,及其双尾P值。 </span></span><br><span class="line"><span class="string">x必须为一维数组</span></span><br><span class="line"><span class="string">y可以为一维数组或三维数组,若y为一维数组,opt为1,计算两序列相关系数;</span></span><br><span class="line"><span class="string">若y为三维数组,则时间维度必须在最左边,即axis=0,opt =2,计算序列和场的相关关系分布。</span></span><br><span class="line"><span class="string">返回r,t</span></span><br><span class="line"><span class="string">'''</span></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> scipy.stats <span class="keyword">import</span> pearsonr</span><br><span class="line"><span class="keyword">from</span> numba <span class="keyword">import</span> jit</span><br><span class="line"><span class="meta">@jit</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">escorc</span><span class="params">(x,y,opt)</span>:</span></span><br><span class="line"> <span class="keyword">if</span> opt==<span class="number">1</span>:</span><br><span class="line"> r,p = pearsonr(x,y)</span><br><span class="line"> <span class="keyword">elif</span> opt ==<span class="number">2</span>:</span><br><span class="line"> lat = y.shape[<span class="number">1</span>]</span><br><span class="line"> lon = y.shape[<span class="number">2</span>]</span><br><span class="line"> r,p = np.zeros((lat,lon)),np.zeros((lat,lon))</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(lat):</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> range(lon):</span><br><span class="line"> r[i,j],p[i,j] = pearsonr(x,y[:,i,j])</span><br><span class="line"> <span class="keyword">return</span> r,p</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> **</span><br><span class="line">r,p = escorc(x,y,opt)</span><br></pre></td></tr></table></figure><p>x必须为一维数组</p><p>y可以为一维数组或三维数组,若y为一维数组,opt为1,计算两序列相关系数;</p><p>若y为三维数组,则时间维度必须在最左边,即axis=0,opt =2,计算序列和场的相关关系分布。</p><p>返回相关系数r和双尾p值。</p><p>该自定义函数保留了NCL计算相关系数的函数名escorc(),同时加入了numba提高了循环计算的速度,同时支持两序列以及序列和气候要素场相关系数的计算。缺点是输入数据有格式要求,即时间维必须是最左维,同时y为序列时opt=1,y为三维数组时opt=2。</p>]]></content>
<categories>
<category> Function </category>
</categories>
</entry>
<entry>