AeroViz 0.1.6__tar.gz → 0.1.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of AeroViz might be problematic. Click here for more details.
- aeroviz-0.1.8/AeroViz/data/240228_00.txt +101 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/Chemistry/_ocec.py +20 -7
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/__init__.py +2 -0
- aeroviz-0.1.8/AeroViz/plot/hysplit/__init__.py +1 -0
- aeroviz-0.1.8/AeroViz/plot/hysplit/hysplit.py +79 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/meteorology/meteorology.py +2 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/optical/optical.py +60 -59
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/pie.py +14 -2
- aeroviz-0.1.8/AeroViz/plot/radar.py +184 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/scatter.py +16 -7
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/templates/diurnal_pattern.py +24 -7
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/templates/koschmieder.py +11 -8
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/timeseries/template.py +2 -2
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/timeseries/timeseries.py +47 -7
- aeroviz-0.1.8/AeroViz/rawDataReader/__init__.py +117 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/rawDataReader/config/supported_instruments.py +52 -19
- aeroviz-0.1.8/AeroViz/rawDataReader/core/__init__.py +380 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/rawDataReader/script/AE33.py +11 -6
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/rawDataReader/script/AE43.py +10 -5
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/rawDataReader/script/Aurora.py +14 -10
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/rawDataReader/script/BC1054.py +10 -6
- aeroviz-0.1.8/AeroViz/rawDataReader/script/EPA.py +39 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/rawDataReader/script/GRIMM.py +1 -2
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/rawDataReader/script/IGAC.py +6 -23
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/rawDataReader/script/MA350.py +12 -5
- aeroviz-0.1.8/AeroViz/rawDataReader/script/Minion.py +180 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/rawDataReader/script/NEPH.py +15 -5
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/rawDataReader/script/OCEC.py +39 -15
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/rawDataReader/script/SMPS.py +1 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/rawDataReader/script/TEOM.py +15 -11
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/rawDataReader/script/VOC.py +1 -1
- aeroviz-0.1.8/AeroViz/rawDataReader/script/XRF.py +11 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/rawDataReader/script/__init__.py +2 -2
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz.egg-info/PKG-INFO +54 -30
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz.egg-info/SOURCES.txt +11 -20
- {aeroviz-0.1.6 → aeroviz-0.1.8}/PKG-INFO +54 -30
- {aeroviz-0.1.6 → aeroviz-0.1.8}/README.md +53 -29
- {aeroviz-0.1.6 → aeroviz-0.1.8}/setup.py +1 -1
- aeroviz-0.1.8/test/test_aeroviz_imports.py +18 -0
- aeroviz-0.1.8/test/test_plot.py +132 -0
- aeroviz-0.1.6/AeroViz/process/__init__.py +0 -31
- aeroviz-0.1.6/AeroViz/process/core/DataProc.py +0 -19
- aeroviz-0.1.6/AeroViz/process/core/SizeDist.py +0 -90
- aeroviz-0.1.6/AeroViz/process/core/__init__.py +0 -4
- aeroviz-0.1.6/AeroViz/process/method/__init__.py +0 -2
- aeroviz-0.1.6/AeroViz/process/method/prop.py +0 -62
- aeroviz-0.1.6/AeroViz/process/script/AbstractDistCalc.py +0 -143
- aeroviz-0.1.6/AeroViz/process/script/Chemical.py +0 -177
- aeroviz-0.1.6/AeroViz/process/script/IMPACT.py +0 -49
- aeroviz-0.1.6/AeroViz/process/script/IMPROVE.py +0 -161
- aeroviz-0.1.6/AeroViz/process/script/Others.py +0 -65
- aeroviz-0.1.6/AeroViz/process/script/PSD.py +0 -103
- aeroviz-0.1.6/AeroViz/process/script/PSD_dry.py +0 -93
- aeroviz-0.1.6/AeroViz/process/script/__init__.py +0 -5
- aeroviz-0.1.6/AeroViz/process/script/retrieve_RI.py +0 -69
- aeroviz-0.1.6/AeroViz/rawDataReader/__init__.py +0 -110
- aeroviz-0.1.6/AeroViz/rawDataReader/core/__init__.py +0 -292
- aeroviz-0.1.6/AeroViz/rawDataReader/script/EPA_vertical.py +0 -46
- aeroviz-0.1.6/AeroViz/rawDataReader/script/Minion.py +0 -103
- aeroviz-0.1.6/AeroViz/rawDataReader/script/Table.py +0 -27
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/__init__.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/data/DEFAULT_DATA.csv +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/data/DEFAULT_PNSD_DATA.csv +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/Chemistry/__init__.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/Chemistry/_calculate.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/Chemistry/_isoropia.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/Chemistry/_mass_volume.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/Chemistry/_partition.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/Chemistry/_teom.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/Chemistry/isrpia.cnf +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/Chemistry/isrpia2.exe +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/Optical/Angstrom_exponent.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/Optical/_IMPROVE.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/Optical/__init__.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/Optical/_absorption.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/Optical/_extinction.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/Optical/_mie.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/Optical/_mie_sd.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/Optical/_scattering.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/Optical/fRH.pkl +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/SizeDistr/__init__.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/SizeDistr/__merge.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/SizeDistr/_merge.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/SizeDistr/_merge_v1.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/SizeDistr/_merge_v2.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/SizeDistr/_merge_v3.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/SizeDistr/_merge_v4.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/SizeDistr/_size_distr.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/VOC/__init__.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/VOC/_potential_par.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/VOC/support_voc.json +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/__init__.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/dataProcess/core/__init__.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/bar.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/box.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/distribution/__init__.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/distribution/distribution.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/meteorology/__init__.py +0 -0
- {aeroviz-0.1.6/AeroViz/process/method → aeroviz-0.1.8/AeroViz/plot/optical}/PyMieScatt_update.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/optical/__init__.py +0 -0
- {aeroviz-0.1.6/AeroViz/process/method → aeroviz-0.1.8/AeroViz/plot/optical}/mie_theory.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/regression.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/templates/__init__.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/templates/ammonium_rich.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/templates/contour.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/templates/corr_matrix.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/templates/metal_heatmap.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/timeseries/__init__.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/utils/__init__.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/utils/_color.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/utils/_unit.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/utils/fRH.json +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/utils/plt_utils.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/utils/sklearn_utils.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/utils/units.json +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/plot/violin.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/rawDataReader/config/__init__.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/rawDataReader/script/APS_3321.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/tools/__init__.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/tools/database.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/tools/dataclassifier.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/tools/dataprinter.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz/tools/datareader.py +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz.egg-info/dependency_links.txt +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz.egg-info/requires.txt +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/AeroViz.egg-info/top_level.txt +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/LICENSE +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/MANIFEST.in +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/requirements.txt +0 -0
- {aeroviz-0.1.6 → aeroviz-0.1.8}/setup.cfg +0 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
1 1
|
|
2
|
+
AWRF 24 1 25 0 0
|
|
3
|
+
4 BACKWARD OMEGA
|
|
4
|
+
24 2 27 16 22.630 120.346 10.0
|
|
5
|
+
24 2 27 16 22.630 120.346 100.0
|
|
6
|
+
24 2 27 16 22.630 120.346 500.0
|
|
7
|
+
24 2 27 16 22.630 120.346 1000.0
|
|
8
|
+
1 PRESSURE
|
|
9
|
+
1 1 24 2 27 16 0 808 0.0 22.630 120.346 10.0 1018.1
|
|
10
|
+
2 1 24 2 27 16 0 808 0.0 22.630 120.346 100.0 1007.1
|
|
11
|
+
3 1 24 2 27 16 0 808 0.0 22.630 120.346 500.0 961.2
|
|
12
|
+
4 1 24 2 27 16 0 808 0.0 22.630 120.346 1000.0 906.2
|
|
13
|
+
1 1 24 2 27 15 0 807 -1.0 22.700 120.337 13.4 1016.4
|
|
14
|
+
2 1 24 2 27 15 0 807 -1.0 22.779 120.325 115.8 1004.4
|
|
15
|
+
3 1 24 2 27 15 0 807 -1.0 22.615 120.313 471.0 964.8
|
|
16
|
+
4 1 24 2 27 15 0 807 -1.0 22.535 120.469 1035.2 902.9
|
|
17
|
+
1 1 24 2 27 14 0 806 -2.0 22.795 120.323 24.3 1015.4
|
|
18
|
+
2 1 24 2 27 14 0 806 -2.0 23.026 120.322 128.8 1001.6
|
|
19
|
+
3 1 24 2 27 14 0 806 -2.0 22.606 120.315 471.5 964.7
|
|
20
|
+
4 1 24 2 27 14 0 806 -2.0 22.484 120.626 1025.3 893.1
|
|
21
|
+
1 1 24 2 27 13 0 805 -3.0 22.936 120.308 56.6 1010.4
|
|
22
|
+
2 1 24 2 27 13 0 805 -3.0 23.275 120.355 142.2 1000.7
|
|
23
|
+
3 1 24 2 27 13 0 805 -3.0 22.612 120.341 492.9 961.7
|
|
24
|
+
4 1 24 2 27 13 0 805 -3.0 22.490 120.729 641.9 860.0
|
|
25
|
+
1 1 24 2 27 12 0 804 -4.0 23.133 120.283 74.9 1010.2
|
|
26
|
+
2 1 24 2 27 12 0 804 -4.0 23.491 120.413 187.7 994.2
|
|
27
|
+
3 1 24 2 27 12 0 804 -4.0 22.670 120.382 482.0 960.7
|
|
28
|
+
4 1 24 2 27 12 0 804 -4.0 22.538 120.774 830.3 801.8
|
|
29
|
+
1 1 24 2 27 11 0 803 -5.0 23.363 120.276 94.7 1007.0
|
|
30
|
+
2 1 24 2 27 11 0 803 -5.0 23.702 120.464 202.2 992.8
|
|
31
|
+
3 1 24 2 27 11 0 803 -5.0 22.708 120.455 327.6 977.5
|
|
32
|
+
4 1 24 2 27 11 0 803 -5.0 22.576 120.736 629.4 831.5
|
|
33
|
+
1 1 24 2 27 10 0 802 -6.0 23.611 120.281 123.4 1003.6
|
|
34
|
+
2 1 24 2 27 10 0 802 -6.0 23.924 120.507 235.0 988.9
|
|
35
|
+
3 1 24 2 27 10 0 802 -6.0 22.691 120.521 95.4 1004.1
|
|
36
|
+
4 1 24 2 27 10 0 802 -6.0 22.631 120.727 385.5 834.4
|
|
37
|
+
1 1 24 2 27 9 0 801 -7.0 23.910 120.338 185.0 996.9
|
|
38
|
+
2 1 24 2 27 9 0 801 -7.0 24.136 120.570 314.7 974.2
|
|
39
|
+
3 1 24 2 27 9 0 801 -7.0 22.702 120.585 125.1 999.7
|
|
40
|
+
4 1 24 2 27 9 0 801 -7.0 22.669 120.749 200.9 817.0
|
|
41
|
+
1 1 24 2 27 8 0 800 -8.0 24.287 120.521 321.6 982.5
|
|
42
|
+
2 1 24 2 27 8 0 800 -8.0 24.195 120.654 531.7 942.2
|
|
43
|
+
3 1 24 2 27 8 0 800 -8.0 22.707 120.608 170.4 993.9
|
|
44
|
+
4 1 24 2 27 8 0 800 -8.0 22.689 120.756 313.0 822.5
|
|
45
|
+
1 1 24 2 27 7 0 799 -9.0 24.612 120.810 428.8 969.2
|
|
46
|
+
2 1 24 2 27 7 0 799 -9.0 24.193 120.736 697.7 917.4
|
|
47
|
+
3 1 24 2 27 7 0 799 -9.0 22.719 120.610 229.7 986.5
|
|
48
|
+
4 1 24 2 27 7 0 799 -9.0 22.689 120.751 248.2 833.6
|
|
49
|
+
1 1 24 2 27 6 0 798 -10.0 24.859 121.146 538.3 932.4
|
|
50
|
+
2 1 24 2 27 6 0 798 -10.0 24.145 120.757 664.1 919.1
|
|
51
|
+
3 1 24 2 27 6 0 798 -10.0 22.738 120.605 305.9 978.9
|
|
52
|
+
4 1 24 2 27 6 0 798 -10.0 22.711 120.761 0.0 888.3
|
|
53
|
+
1 1 24 2 27 5 0 797 -11.0 24.984 121.430 392.9 975.2
|
|
54
|
+
2 1 24 2 27 5 0 797 -11.0 24.074 120.749 654.4 923.5
|
|
55
|
+
3 1 24 2 27 5 0 797 -11.0 22.731 120.603 495.6 958.3
|
|
56
|
+
4 1 24 2 27 5 0 797 -11.0 22.700 120.785 175.9 829.1
|
|
57
|
+
1 1 24 2 27 4 0 796 -12.0 25.158 121.638 503.0 954.6
|
|
58
|
+
2 1 24 2 27 4 0 796 -12.0 23.989 120.737 641.7 927.8
|
|
59
|
+
3 1 24 2 27 4 0 796 -12.0 22.693 120.592 648.1 943.6
|
|
60
|
+
4 1 24 2 27 4 0 796 -12.0 22.685 120.810 145.4 853.0
|
|
61
|
+
1 1 24 2 27 3 0 795 -13.0 25.451 121.825 386.1 978.5
|
|
62
|
+
2 1 24 2 27 3 0 795 -13.0 23.906 120.739 645.3 929.6
|
|
63
|
+
3 1 24 2 27 3 0 795 -13.0 22.657 120.583 682.1 940.8
|
|
64
|
+
4 1 24 2 27 3 0 795 -13.0 22.655 120.810 8.7 903.0
|
|
65
|
+
1 1 24 2 27 2 0 794 -14.0 25.789 121.989 450.1 971.0
|
|
66
|
+
2 1 24 2 27 2 0 794 -14.0 23.854 120.722 640.7 924.2
|
|
67
|
+
3 1 24 2 27 2 0 794 -14.0 22.618 120.552 686.5 941.2
|
|
68
|
+
4 1 24 2 27 2 0 794 -14.0 22.628 120.817 147.7 890.5
|
|
69
|
+
1 1 24 2 27 1 0 793 -15.0 26.127 122.136 554.7 959.4
|
|
70
|
+
2 1 24 2 27 1 0 793 -15.0 23.815 120.684 526.0 936.4
|
|
71
|
+
3 1 24 2 27 1 0 793 -15.0 22.537 120.538 763.0 933.1
|
|
72
|
+
4 1 24 2 27 1 0 793 -15.0 22.630 120.825 156.0 898.7
|
|
73
|
+
1 1 24 2 27 0 0 792 -16.0 26.425 122.289 711.1 940.7
|
|
74
|
+
2 1 24 2 27 0 0 792 -16.0 23.793 120.665 527.9 942.8
|
|
75
|
+
3 1 24 2 27 0 0 792 -16.0 22.498 120.642 901.2 897.5
|
|
76
|
+
4 1 24 2 27 0 0 792 -16.0 22.633 120.822 130.8 898.3
|
|
77
|
+
1 1 24 2 26 23 0 791 -17.0 26.705 122.454 872.6 921.4
|
|
78
|
+
2 1 24 2 26 23 0 791 -17.0 23.798 120.671 524.1 940.3
|
|
79
|
+
3 1 24 2 26 23 0 791 -17.0 22.514 120.689 734.8 863.9
|
|
80
|
+
4 1 24 2 26 23 0 791 -17.0 22.628 120.825 80.9 904.3
|
|
81
|
+
2 1 24 2 26 22 0 790 -18.0 23.816 120.688 493.1 939.0
|
|
82
|
+
3 1 24 2 26 22 0 790 -18.0 22.559 120.685 771.9 865.4
|
|
83
|
+
4 1 24 2 26 22 0 790 -18.0 22.623 120.829 56.0 907.8
|
|
84
|
+
2 1 24 2 26 21 0 789 -19.0 23.836 120.711 427.5 946.0
|
|
85
|
+
3 1 24 2 26 21 0 789 -19.0 22.557 120.666 660.4 899.0
|
|
86
|
+
4 1 24 2 26 21 0 789 -19.0 22.623 120.833 82.4 907.7
|
|
87
|
+
2 1 24 2 26 20 0 788 -20.0 23.865 120.751 489.8 941.5
|
|
88
|
+
3 1 24 2 26 20 0 788 -20.0 22.525 120.624 588.1 942.1
|
|
89
|
+
4 1 24 2 26 20 0 788 -20.0 22.636 120.848 98.3 914.3
|
|
90
|
+
2 1 24 2 26 19 0 787 -21.0 23.874 120.791 693.5 909.2
|
|
91
|
+
3 1 24 2 26 19 0 787 -21.0 22.492 120.608 624.9 943.0
|
|
92
|
+
4 1 24 2 26 19 0 787 -21.0 22.667 120.865 193.7 891.2
|
|
93
|
+
2 1 24 2 26 18 0 786 -22.0 23.874 120.793 743.4 902.1
|
|
94
|
+
3 1 24 2 26 18 0 786 -22.0 22.482 120.601 703.4 938.1
|
|
95
|
+
4 1 24 2 26 18 0 786 -22.0 22.747 120.984 287.0 906.5
|
|
96
|
+
2 1 24 2 26 17 0 785 -23.0 23.885 120.793 766.4 902.4
|
|
97
|
+
3 1 24 2 26 17 0 785 -23.0 22.471 120.582 842.0 922.5
|
|
98
|
+
4 1 24 2 26 17 0 785 -23.0 22.867 121.070 462.0 920.8
|
|
99
|
+
2 1 24 2 26 16 0 784 -24.0 23.895 120.778 859.2 898.6
|
|
100
|
+
3 1 24 2 26 16 0 784 -24.0 22.446 120.618 1090.1 893.0
|
|
101
|
+
4 1 24 2 26 16 0 784 -24.0 22.973 121.135 790.6 906.9
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
|
|
1
3
|
import numpy as np
|
|
2
4
|
from pandas import concat, DataFrame
|
|
3
|
-
from scipy.optimize import curve_fit
|
|
5
|
+
from scipy.optimize import curve_fit, least_squares, OptimizeWarning
|
|
4
6
|
|
|
5
7
|
from AeroViz.dataProcess.core import union_index
|
|
6
8
|
|
|
@@ -22,15 +24,26 @@ def _min_Rsq(_oc, _ec, _rng):
|
|
|
22
24
|
for _ocec, _out in _out_table.items():
|
|
23
25
|
_df = DataFrame([_out.values, _ec.values]).T.dropna()
|
|
24
26
|
|
|
25
|
-
_x, _y = _df[0], _df[1]
|
|
26
|
-
|
|
27
|
+
_x, _y = _df[0].values, _df[1].values
|
|
28
|
+
|
|
29
|
+
# 初始參數估計
|
|
30
|
+
slope_guess = (_y[-1] - _y[0]) / (_x[-1] - _x[0])
|
|
31
|
+
intercept_guess = _y[0] - slope_guess * _x[0]
|
|
32
|
+
|
|
33
|
+
try:
|
|
34
|
+
with warnings.catch_warnings():
|
|
35
|
+
warnings.filterwarnings('error')
|
|
36
|
+
_opt, _ = curve_fit(_func, _x, _y, p0=[slope_guess, intercept_guess], maxfev=5000)
|
|
37
|
+
except (RuntimeWarning, OptimizeWarning):
|
|
38
|
+
# 如果 curve_fit 失敗,嘗試使用 least_squares
|
|
39
|
+
residuals = lambda p: _func(_x, *p) - _y
|
|
40
|
+
_opt = least_squares(residuals, [slope_guess, intercept_guess]).x
|
|
27
41
|
|
|
28
|
-
_tss = np.sum((_y -
|
|
29
|
-
_rss = np.sum((_y - _func(_x, *_opt)) ** 2
|
|
42
|
+
_tss = np.sum((_y - np.mean(_y)) ** 2)
|
|
43
|
+
_rss = np.sum((_y - _func(_x, *_opt)) ** 2)
|
|
30
44
|
|
|
31
|
-
_r2_dic[round(_ocec, 3)] = 1
|
|
45
|
+
_r2_dic[round(_ocec, 3)] = 1 - _rss / _tss
|
|
32
46
|
|
|
33
|
-
# get the min R2
|
|
34
47
|
_ratio = DataFrame(_r2_dic, index=[0]).idxmin(axis=1).values[0]
|
|
35
48
|
|
|
36
49
|
return _ratio, _out_table[_ratio]
|
|
@@ -3,7 +3,9 @@ from . import meteorology
|
|
|
3
3
|
from . import optical
|
|
4
4
|
from .bar import bar
|
|
5
5
|
from .box import box
|
|
6
|
+
from .hysplit import hysplit
|
|
6
7
|
from .pie import pie, donuts
|
|
8
|
+
from .radar import radar
|
|
7
9
|
from .regression import linear_regression, multiple_linear_regression
|
|
8
10
|
from .scatter import scatter
|
|
9
11
|
from .templates import *
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .hysplit import *
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import cartopy.crs as ccrs
|
|
4
|
+
import cartopy.feature as cfeature
|
|
5
|
+
import matplotlib.pyplot as plt
|
|
6
|
+
import pandas as pd
|
|
7
|
+
|
|
8
|
+
from AeroViz.plot.utils import set_figure
|
|
9
|
+
|
|
10
|
+
# TODO: Hybrid Single-Particle Lagrangian Integrated Trajectory (HYSPLIT) model
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
__all__ = ['hysplit']
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def read_hysplit_data(file: Path):
|
|
17
|
+
data = pd.read_csv(file, skiprows=8, sep=r'\s+', names=range(0, 12), engine='python')
|
|
18
|
+
data = data.reset_index(drop=False)
|
|
19
|
+
data.columns = ['category', 'name', 'abc', 'year', 'month', 'hour', 'min', 'cont', 'backward', 'lat', 'lon',
|
|
20
|
+
'height', 'pressure']
|
|
21
|
+
|
|
22
|
+
return data
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@set_figure
|
|
26
|
+
def hysplit(file: Path):
|
|
27
|
+
data = read_hysplit_data(file)
|
|
28
|
+
|
|
29
|
+
# 創建地圖
|
|
30
|
+
fig, ax = plt.subplots(figsize=(4, 5), subplot_kw={'projection': ccrs.PlateCarree()})
|
|
31
|
+
|
|
32
|
+
# 設置地圖範圍
|
|
33
|
+
ax.set_extent([116, 126, 17, 30], crs=ccrs.PlateCarree())
|
|
34
|
+
|
|
35
|
+
# 添加自然地理特徵
|
|
36
|
+
ax.add_feature(cfeature.LAND)
|
|
37
|
+
ax.add_feature(cfeature.OCEAN)
|
|
38
|
+
ax.add_feature(cfeature.COASTLINE)
|
|
39
|
+
ax.add_feature(cfeature.BORDERS, linestyle=':')
|
|
40
|
+
|
|
41
|
+
# 添加經緯度網格
|
|
42
|
+
ax.gridlines(draw_labels=True, dms=True, x_inline=False, y_inline=False)
|
|
43
|
+
|
|
44
|
+
# 定義四種顏色
|
|
45
|
+
colors = ['red', 'blue', 'green', 'purple']
|
|
46
|
+
|
|
47
|
+
# 繪製四條軌跡線
|
|
48
|
+
group = data.groupby('category')
|
|
49
|
+
for i, (name, _data) in enumerate(group):
|
|
50
|
+
trajectory = _data
|
|
51
|
+
ax.plot(trajectory['lon'], trajectory['lat'], color=colors[i],
|
|
52
|
+
linewidth=2, transform=ccrs.Geodetic(),
|
|
53
|
+
label=f'Trajectory {name}')
|
|
54
|
+
|
|
55
|
+
# 添加起點和終點標記
|
|
56
|
+
# ax.plot(trajectory['lon'].iloc[-1], trajectory['lat'].iloc[-1], 'o',
|
|
57
|
+
# color=colors[i], markersize=4, transform=ccrs.Geodetic())
|
|
58
|
+
# ax.plot(trajectory['lon'].iloc[0], trajectory['lat'].iloc[0], 's',
|
|
59
|
+
# color=colors[i], markersize=4, transform=ccrs.Geodetic())
|
|
60
|
+
|
|
61
|
+
ax.legend(loc='upper right')
|
|
62
|
+
# 添加色標
|
|
63
|
+
# cbar = plt.colorbar(scatter, ax=ax, shrink=0.6, pad=0.12)
|
|
64
|
+
# cbar.set_label('Height (m)')
|
|
65
|
+
|
|
66
|
+
# 添加標題
|
|
67
|
+
plt.title("HYSPLIT model", pad=12)
|
|
68
|
+
|
|
69
|
+
plt.tight_layout()
|
|
70
|
+
|
|
71
|
+
# 保存地圖
|
|
72
|
+
plt.savefig('backward_hysplit.png', dpi=300, bbox_inches='tight')
|
|
73
|
+
|
|
74
|
+
# 顯示地圖(可選)
|
|
75
|
+
plt.show()
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
if __name__ == "__main__":
|
|
79
|
+
hysplit(Path("../../data/240228_00.txt")) # 請替換為您的實際檔案路徑
|
|
@@ -70,6 +70,7 @@ def wind_rose(df: DataFrame,
|
|
|
70
70
|
rlabel_position=rlabel_pos,
|
|
71
71
|
theta_direction=-1,
|
|
72
72
|
theta_zero_location='N',
|
|
73
|
+
title=kwargs.get('title', None)
|
|
73
74
|
)
|
|
74
75
|
ax.set_thetagrids(angles=[0, 45, 90, 135, 180, 225, 270, 315],
|
|
75
76
|
labels=["N", "NE", "E", "SE", "S", "SW", "W", "NW"])
|
|
@@ -81,6 +82,7 @@ def wind_rose(df: DataFrame,
|
|
|
81
82
|
return fig, ax
|
|
82
83
|
|
|
83
84
|
|
|
85
|
+
# TODO: fix the bug of the CBPF function
|
|
84
86
|
@set_figure(figsize=(4.3, 4))
|
|
85
87
|
def CBPF(df: DataFrame,
|
|
86
88
|
WS: Series | str,
|
|
@@ -6,13 +6,14 @@ import numpy as np
|
|
|
6
6
|
# from PyMieScatt import ScatteringFunction
|
|
7
7
|
from matplotlib.pyplot import Figure, Axes
|
|
8
8
|
|
|
9
|
+
from AeroViz.plot.optical.PyMieScatt_update import ScatteringFunction
|
|
10
|
+
from AeroViz.plot.optical.mie_theory import Mie_Q, Mie_MEE, Mie_PESD
|
|
9
11
|
from AeroViz.plot.utils import *
|
|
10
|
-
from AeroViz.process.method.mie_theory import Mie_Q, Mie_MEE, Mie_PESD
|
|
11
12
|
|
|
12
13
|
__all__ = ['Q_plot',
|
|
13
14
|
'RI_couple',
|
|
14
15
|
'RRI_2D',
|
|
15
|
-
|
|
16
|
+
'scattering_phase',
|
|
16
17
|
'response_surface',
|
|
17
18
|
]
|
|
18
19
|
|
|
@@ -252,59 +253,59 @@ def RRI_2D(mode: Literal["ext", "sca", "abs"] = 'ext',
|
|
|
252
253
|
return fig, ax
|
|
253
254
|
|
|
254
255
|
|
|
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
|
-
|
|
256
|
+
@set_figure
|
|
257
|
+
def scattering_phase(m: complex = 1.55 + 0.01j,
|
|
258
|
+
wave: float = 600,
|
|
259
|
+
dp: float = 200) -> tuple[Figure, Axes]:
|
|
260
|
+
"""
|
|
261
|
+
Generate a polar plot to visualize the scattering phase function.
|
|
262
|
+
|
|
263
|
+
Parameters
|
|
264
|
+
----------
|
|
265
|
+
m : complex, optional
|
|
266
|
+
The complex refractive index of the scattering medium. Default is 1.55 + 0.01j.
|
|
267
|
+
wave : float, optional
|
|
268
|
+
The wavelength of the incident light in nanometers. Default is 600 nm.
|
|
269
|
+
dp : float, optional
|
|
270
|
+
The particle diameter in nanometers. Default is 200 nm.
|
|
271
|
+
|
|
272
|
+
Returns
|
|
273
|
+
-------
|
|
274
|
+
ax : Axes
|
|
275
|
+
Matplotlib Axes object containing the generated polar plot.
|
|
276
|
+
|
|
277
|
+
Examples
|
|
278
|
+
--------
|
|
279
|
+
Example usage of the scattering_phase function:
|
|
280
|
+
|
|
281
|
+
>>> ax = scattering_phase(m=1.55 + 0.01j, wave=600, dp=200)
|
|
282
|
+
"""
|
|
283
|
+
theta, _SL, _SR, _SU = ScatteringFunction(m, wave, dp)
|
|
284
|
+
|
|
285
|
+
SL = np.append(_SL, _SL[::-1])
|
|
286
|
+
SR = np.append(_SR, _SR[::-1])
|
|
287
|
+
SU = np.append(_SU, _SU[::-1])
|
|
288
|
+
|
|
289
|
+
angles = ['0', '60', '120', '180', '240', '300']
|
|
290
|
+
|
|
291
|
+
fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
|
|
292
|
+
|
|
293
|
+
theta = np.linspace(0, 2 * np.pi, len(SL))
|
|
294
|
+
|
|
295
|
+
plt.thetagrids(range(0, 360, int(360 / len(angles))), angles)
|
|
296
|
+
|
|
297
|
+
plt.plot(theta, SL, '-', linewidth=2, color='#115162', label='SL')
|
|
298
|
+
plt.fill(theta, SL, '#afe0f5', alpha=0.5)
|
|
299
|
+
plt.plot(theta, SR, '-', linewidth=2, color='#7FAE80', label='SR')
|
|
300
|
+
plt.fill(theta, SR, '#b5e6c5', alpha=0.5)
|
|
301
|
+
plt.plot(theta, SU, '-', linewidth=2, color='#621129', label='SU')
|
|
302
|
+
plt.fill(theta, SU, '#f5afbd', alpha=0.5)
|
|
303
|
+
|
|
304
|
+
plt.legend(loc='best', bbox_to_anchor=(1, 0, 0.2, 1), prop={'weight': 'bold'})
|
|
305
|
+
plt.title(r'$\bf Scattering\ phase\ function$')
|
|
306
|
+
|
|
307
|
+
plt.show()
|
|
308
|
+
return fig, ax
|
|
308
309
|
|
|
309
310
|
|
|
310
311
|
@set_figure
|
|
@@ -368,7 +369,7 @@ def response_surface(real_range=(1.33, 1.7),
|
|
|
368
369
|
ax.plot_surface(real, gmd, ext, rstride=1, cstride=1, cmap=plt.get_cmap('jet'), edgecolor='none')
|
|
369
370
|
|
|
370
371
|
ax.set(xlabel='Real part (n)', ylabel='GMD (nm)', zlabel=Unit('Extinction'),
|
|
371
|
-
title='Sensitive tests of
|
|
372
|
+
title='Sensitive tests of extinction')
|
|
372
373
|
|
|
373
374
|
ax.zaxis.get_offset_text().set_visible(False)
|
|
374
375
|
exponent = math.floor(math.log10(np.max(ext)))
|
|
@@ -381,8 +382,8 @@ def response_surface(real_range=(1.33, 1.7),
|
|
|
381
382
|
|
|
382
383
|
|
|
383
384
|
if __name__ == '__main__':
|
|
384
|
-
|
|
385
|
-
|
|
385
|
+
Q_plot(['AS', 'AN', 'OM', 'Soil', 'SS', 'BC'], x='dp', y='MEE')
|
|
386
|
+
Q_plot(['AS', 'AN', 'OM', 'Soil', 'SS', 'BC'], x='dp', y='Q')
|
|
386
387
|
|
|
387
|
-
|
|
388
|
+
RI_couple()
|
|
388
389
|
response_surface()
|
|
@@ -81,7 +81,9 @@ def pie(data_set: DataFrame | dict,
|
|
|
81
81
|
radius = 4
|
|
82
82
|
width = 4 if style == 'pie' else 1
|
|
83
83
|
|
|
84
|
-
text = [''] * pies if style == 'pie' else [Unit(unit) + '\n\n' +
|
|
84
|
+
text = [''] * pies if style == 'pie' else [Unit(unit) + '\n\n' +
|
|
85
|
+
'{:.2f} ± {:.2f}'.format(x, s)
|
|
86
|
+
for x, s in zip(data.sum(axis=1), data.std(axis=1))]
|
|
85
87
|
pct_distance = 0.6 if style == 'pie' else 0.88
|
|
86
88
|
|
|
87
89
|
fig, ax = plt.subplots(1, pies, figsize=((pies * 2) + 1, 2)) if ax is None else (ax.get_figure(), ax)
|
|
@@ -99,7 +101,17 @@ def pie(data_set: DataFrame | dict,
|
|
|
99
101
|
pctdistance=1.3, radius=radius, wedgeprops=dict(width=width, edgecolor='w'))
|
|
100
102
|
ax[i].axis('equal')
|
|
101
103
|
ax[i].text(0, 0, text[i], ha='center', va='center')
|
|
102
|
-
|
|
104
|
+
|
|
105
|
+
if kwargs.get('title') is None:
|
|
106
|
+
ax[i].set_title(category_names[i])
|
|
107
|
+
|
|
108
|
+
else:
|
|
109
|
+
if len(kwargs.get('title')) == pies:
|
|
110
|
+
title = kwargs.get('title')
|
|
111
|
+
else:
|
|
112
|
+
raise ValueError('The length of the title list must match the number of pies.')
|
|
113
|
+
|
|
114
|
+
ax[i].set_title(title[i])
|
|
103
115
|
|
|
104
116
|
ax[-1].legend(labels, loc='center left', prop={'size': 8, 'weight': 'normal'}, bbox_to_anchor=(1, 0, 1.15, 1))
|
|
105
117
|
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import matplotlib.pyplot as plt
|
|
2
|
+
import numpy as np
|
|
3
|
+
from matplotlib.patches import Circle, RegularPolygon
|
|
4
|
+
from matplotlib.path import Path
|
|
5
|
+
from matplotlib.projections import register_projection
|
|
6
|
+
from matplotlib.projections.polar import PolarAxes
|
|
7
|
+
from matplotlib.spines import Spine
|
|
8
|
+
from matplotlib.transforms import Affine2D
|
|
9
|
+
|
|
10
|
+
from AeroViz.plot.utils import *
|
|
11
|
+
|
|
12
|
+
__all__ = ['radar']
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def radar_factory(num_vars, frame='circle'):
|
|
16
|
+
"""
|
|
17
|
+
Create a radar chart with `num_vars` axes.
|
|
18
|
+
|
|
19
|
+
This function creates a RadarAxes projection and registers it.
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
num_vars : int
|
|
24
|
+
Number of variables for radar chart.
|
|
25
|
+
frame : {'circle', 'polygon'}
|
|
26
|
+
Shape of frame surrounding axes.
|
|
27
|
+
|
|
28
|
+
"""
|
|
29
|
+
# calculate evenly-spaced axis angles
|
|
30
|
+
theta = np.linspace(0, 2 * np.pi, num_vars, endpoint=False)
|
|
31
|
+
|
|
32
|
+
class RadarTransform(PolarAxes.PolarTransform):
|
|
33
|
+
|
|
34
|
+
def transform_path_non_affine(self, path):
|
|
35
|
+
# Paths with non-unit interpolation steps correspond to gridlines,
|
|
36
|
+
# in which case we force interpolation (to defeat PolarTransform's
|
|
37
|
+
# autoconversion to circular arcs).
|
|
38
|
+
if path._interpolation_steps > 1:
|
|
39
|
+
path = path.interpolated(num_vars)
|
|
40
|
+
return Path(self.transform(path.vertices), path.codes)
|
|
41
|
+
|
|
42
|
+
class RadarAxes(PolarAxes):
|
|
43
|
+
|
|
44
|
+
name = 'radar'
|
|
45
|
+
PolarTransform = RadarTransform
|
|
46
|
+
|
|
47
|
+
def __init__(self, *args, **kwargs):
|
|
48
|
+
super().__init__(*args, **kwargs)
|
|
49
|
+
# rotate plot such that the first axis is at the top
|
|
50
|
+
self.set_theta_zero_location('N')
|
|
51
|
+
|
|
52
|
+
def fill(self, *args, closed=True, **kwargs):
|
|
53
|
+
"""Override fill so that line is closed by default"""
|
|
54
|
+
return super().fill(closed=closed, *args, **kwargs)
|
|
55
|
+
|
|
56
|
+
def plot(self, *args, **kwargs):
|
|
57
|
+
"""Override plot so that line is closed by default"""
|
|
58
|
+
lines = super().plot(*args, **kwargs)
|
|
59
|
+
for line in lines:
|
|
60
|
+
self._close_line(line)
|
|
61
|
+
|
|
62
|
+
def _close_line(self, line):
|
|
63
|
+
x, y = line.get_data()
|
|
64
|
+
if x[0] != x[-1]:
|
|
65
|
+
x = np.append(x, x[0])
|
|
66
|
+
y = np.append(y, y[0])
|
|
67
|
+
line.set_data(x, y)
|
|
68
|
+
|
|
69
|
+
def set_varlabels(self, labels):
|
|
70
|
+
self.set_thetagrids(np.degrees(theta), labels)
|
|
71
|
+
|
|
72
|
+
@staticmethod
|
|
73
|
+
def _gen_axes_patch():
|
|
74
|
+
# The Axes patch must be centered at (0.5, 0.5) and of radius 0.5
|
|
75
|
+
# in axes coordinates.
|
|
76
|
+
if frame == 'circle':
|
|
77
|
+
return Circle((0.5, 0.5), 0.5)
|
|
78
|
+
elif frame == 'polygon':
|
|
79
|
+
return RegularPolygon((0.5, 0.5), num_vars,
|
|
80
|
+
radius=.5, edgecolor="k")
|
|
81
|
+
else:
|
|
82
|
+
raise ValueError("Unknown value for 'frame': %s" % frame)
|
|
83
|
+
|
|
84
|
+
def _gen_axes_spines(self):
|
|
85
|
+
if frame == 'circle':
|
|
86
|
+
return super()._gen_axes_spines()
|
|
87
|
+
elif frame == 'polygon':
|
|
88
|
+
# spine_type must be 'left'/'right'/'top'/'bottom'/'circle'.
|
|
89
|
+
spine = Spine(axes=self,
|
|
90
|
+
spine_type='circle',
|
|
91
|
+
path=Path.unit_regular_polygon(num_vars))
|
|
92
|
+
# unit_regular_polygon gives a polygon of radius 1 centered at
|
|
93
|
+
# (0, 0) but we want a polygon of radius 0.5 centered at (0.5,
|
|
94
|
+
# 0.5) in axes coordinates.
|
|
95
|
+
spine.set_transform(Affine2D().scale(.5).translate(.5, .5)
|
|
96
|
+
+ self.transAxes)
|
|
97
|
+
return {'polar': spine}
|
|
98
|
+
else:
|
|
99
|
+
raise ValueError("Unknown value for 'frame': %s" % frame)
|
|
100
|
+
|
|
101
|
+
register_projection(RadarAxes)
|
|
102
|
+
return theta
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@set_figure(figsize=(3, 3))
|
|
106
|
+
def radar(data, labels=None, legend_labels=None, **kwargs) -> tuple[plt.Figure, plt.Axes]:
|
|
107
|
+
"""
|
|
108
|
+
Creates a radar chart based on the provided data.
|
|
109
|
+
|
|
110
|
+
Parameters
|
|
111
|
+
----------
|
|
112
|
+
data : list of list
|
|
113
|
+
A 2D list where each inner list represents a factor, and each element
|
|
114
|
+
within the inner lists represents a value for a species.
|
|
115
|
+
Shape: (n_factors, n_species)
|
|
116
|
+
Example: [[0.88, 0.01, 0.03, ...], [0.07, 0.95, 0.04, ...], ...]
|
|
117
|
+
|
|
118
|
+
labels : list, optional
|
|
119
|
+
A list of strings representing the names of species (variables).
|
|
120
|
+
If provided, it should have the same length as the number of elements
|
|
121
|
+
in each inner list of `data`.
|
|
122
|
+
Example: ['Sulfate', 'Nitrate', 'EC', 'OC1', 'OC2', 'OP', 'CO', 'O3']
|
|
123
|
+
|
|
124
|
+
legend_labels : list, optional
|
|
125
|
+
A list of strings for labeling each factor in the legend.
|
|
126
|
+
If provided, it should have the same length as the number of inner lists in `data`.
|
|
127
|
+
|
|
128
|
+
**kwargs : dict
|
|
129
|
+
Additional keyword arguments to be passed to the plotting function.
|
|
130
|
+
This may include 'title' for setting the chart title.
|
|
131
|
+
|
|
132
|
+
Returns
|
|
133
|
+
-------
|
|
134
|
+
tuple[plt.Figure, plt.Axes]
|
|
135
|
+
A tuple containing the Figure and Axes objects of the created plot.
|
|
136
|
+
|
|
137
|
+
Example
|
|
138
|
+
-------
|
|
139
|
+
>>> data = [[0.88, 0.01, 0.03, 0.03, 0.00, 0.06, 0.01, 0.00],
|
|
140
|
+
>>> [0.07, 0.95, 0.04, 0.05, 0.00, 0.02, 0.01, 0.00],
|
|
141
|
+
>>> [0.01, 0.02, 0.85, 0.19, 0.05, 0.10, 0.00, 0.00],
|
|
142
|
+
>>> [0.02, 0.01, 0.07, 0.01, 0.21, 0.12, 0.98, 0.00],
|
|
143
|
+
>>> [0.01, 0.01, 0.02, 0.71, 0.74, 0.70, 0.30, 0.20]]
|
|
144
|
+
>>> labels = ['Sulfate', 'Nitrate', 'EC', 'OC1', 'OC2', 'OP', 'CO', 'O3']
|
|
145
|
+
>>> fig, ax = radar(data, labels=labels, title='Basecase')
|
|
146
|
+
|
|
147
|
+
Note
|
|
148
|
+
----
|
|
149
|
+
The first dimension of `data` represents each factor, while the second
|
|
150
|
+
dimension represents each species.
|
|
151
|
+
"""
|
|
152
|
+
theta = radar_factory(np.array(data).shape[1], frame='polygon')
|
|
153
|
+
|
|
154
|
+
fig, ax = plt.subplots(subplot_kw=dict(projection='radar'))
|
|
155
|
+
fig.subplots_adjust(wspace=0.25, hspace=0.20, top=0.80, bottom=0.05, right=0.80)
|
|
156
|
+
|
|
157
|
+
colors = ['b', 'r', 'g', 'm', 'y']
|
|
158
|
+
|
|
159
|
+
# Plot the four cases from the example data on separate axes
|
|
160
|
+
for d, color in zip(data, colors):
|
|
161
|
+
ax.plot(theta, d, color=color)
|
|
162
|
+
ax.fill(theta, d, facecolor=color, alpha=0.25, label='_nolegend_')
|
|
163
|
+
|
|
164
|
+
ax.set_varlabels(labels)
|
|
165
|
+
ax.set_rgrids([0.2, 0.4, 0.6, 0.8])
|
|
166
|
+
ax.set(title=kwargs.get('title', ''))
|
|
167
|
+
|
|
168
|
+
# add legend relative to top-left plot
|
|
169
|
+
legend_labels = legend_labels or ('Factor 1', 'Factor 2', 'Factor 3', 'Factor 4', 'Factor 5')
|
|
170
|
+
legend = ax.legend(legend_labels, loc=(0.95, 0.95), labelspacing=0.1)
|
|
171
|
+
|
|
172
|
+
plt.show()
|
|
173
|
+
|
|
174
|
+
return fig, ax
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
if __name__ == '__main__':
|
|
178
|
+
data = [[0.88, 0.01, 0.03, 0.03, 0.00, 0.06, 0.01, 0.00],
|
|
179
|
+
[0.07, 0.95, 0.04, 0.05, 0.00, 0.02, 0.01, 0.00],
|
|
180
|
+
[0.01, 0.02, 0.85, 0.19, 0.05, 0.10, 0.00, 0.00],
|
|
181
|
+
[0.02, 0.01, 0.07, 0.01, 0.21, 0.12, 0.98, 0.00],
|
|
182
|
+
[0.01, 0.01, 0.02, 0.71, 0.74, 0.70, 0.30, 0.20]]
|
|
183
|
+
|
|
184
|
+
fig, ax = radar(data=data, labels=['Sulfate', 'Nitrate', 'EC', 'OC1', 'OC2', 'OP', 'CO', 'O3'], title='Basecase')
|