AeroViz 0.1.9.5__tar.gz → 0.1.10__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.9.5 → aeroviz-0.1.10}/AeroViz/__init__.py +1 -2
- aeroviz-0.1.10/AeroViz/__pycache__/__init__.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/dataProcess/Chemistry/__pycache__/__init__.cpython-312.pyc +0 -0
- {aeroviz-0.1.9.5/AeroViz/plot/optical → aeroviz-0.1.10/AeroViz/dataProcess/Optical}/PyMieScatt_update.py +4 -11
- aeroviz-0.1.10/AeroViz/dataProcess/Optical/__pycache__/PyMieScatt_update.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/dataProcess/Optical/__pycache__/__init__.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/dataProcess/Optical/__pycache__/mie_theory.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/dataProcess/SizeDistr/__pycache__/__init__.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/dataProcess/SizeDistr/prop.py +62 -0
- aeroviz-0.1.10/AeroViz/dataProcess/VOC/__pycache__/__init__.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/dataProcess/__pycache__/__init__.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/dataProcess/core/__pycache__/__init__.cpython-312.pyc +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/__init__.py +0 -1
- aeroviz-0.1.10/AeroViz/plot/__pycache__/__init__.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/__pycache__/bar.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/__pycache__/box.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/__pycache__/pie.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/__pycache__/radar.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/__pycache__/regression.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/__pycache__/scatter.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/__pycache__/violin.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/distribution/__pycache__/__init__.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/distribution/__pycache__/distribution.cpython-312.pyc +0 -0
- aeroviz-0.1.9.5/AeroViz/plot/meteorology/meteorology.py → aeroviz-0.1.10/AeroViz/plot/meteorology/CBPF.py +150 -122
- aeroviz-0.1.10/AeroViz/plot/meteorology/__init__.py +3 -0
- aeroviz-0.1.10/AeroViz/plot/meteorology/__pycache__/CBPF.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/meteorology/__pycache__/__init__.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/meteorology/__pycache__/hysplit.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/meteorology/__pycache__/wind_rose.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/meteorology/wind_rose.py +77 -0
- aeroviz-0.1.10/AeroViz/plot/optical/__pycache__/__init__.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/optical/__pycache__/optical.cpython-312.pyc +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/optical/optical.py +2 -3
- aeroviz-0.1.10/AeroViz/plot/templates/__pycache__/__init__.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/templates/__pycache__/ammonium_rich.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/templates/__pycache__/contour.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/templates/__pycache__/corr_matrix.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/templates/__pycache__/diurnal_pattern.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/templates/__pycache__/koschmieder.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/templates/__pycache__/metal_heatmap.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/timeseries/__pycache__/__init__.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/timeseries/__pycache__/template.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/timeseries/__pycache__/timeseries.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/utils/__pycache__/__init__.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/utils/__pycache__/_color.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/utils/__pycache__/_unit.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/utils/__pycache__/plt_utils.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/plot/utils/__pycache__/sklearn_utils.cpython-312.pyc +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/utils/plt_utils.py +1 -1
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/__init__.py +4 -2
- aeroviz-0.1.10/AeroViz/rawDataReader/__pycache__/__init__.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/config/__pycache__/__init__.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/config/__pycache__/supported_instruments.cpython-312.pyc +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/core/__init__.py +71 -72
- aeroviz-0.1.10/AeroViz/rawDataReader/core/__pycache__/__init__.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/core/__pycache__/logger.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/core/__pycache__/qc.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/core/logger.py +78 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/script/EPA.py +1 -1
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/script/Minion.py +4 -3
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/script/SMPS.py +9 -7
- aeroviz-0.1.10/AeroViz/rawDataReader/script/__pycache__/AE33.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/script/__pycache__/AE43.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/script/__pycache__/APS_3321.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/script/__pycache__/Aurora.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/script/__pycache__/BC1054.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/script/__pycache__/EPA.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/script/__pycache__/GRIMM.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/script/__pycache__/IGAC.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/script/__pycache__/MA350.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/script/__pycache__/Minion.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/script/__pycache__/NEPH.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/script/__pycache__/OCEC.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/script/__pycache__/SMPS.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/script/__pycache__/TEOM.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/script/__pycache__/VOC.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/script/__pycache__/XRF.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/rawDataReader/script/__pycache__/__init__.cpython-312.pyc +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/tools/__init__.py +0 -1
- aeroviz-0.1.10/AeroViz/tools/__pycache__/__init__.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/tools/__pycache__/database.cpython-312.pyc +0 -0
- aeroviz-0.1.10/AeroViz/tools/__pycache__/dataclassifier.cpython-312.pyc +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz.egg-info/PKG-INFO +39 -79
- aeroviz-0.1.10/AeroViz.egg-info/SOURCES.txt +175 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz.egg-info/requires.txt +2 -2
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/PKG-INFO +39 -79
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/README.md +34 -75
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/pyproject.toml +21 -4
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/tests/test_RawDataReader.py +3 -0
- aeroviz-0.1.9.5/tests/test_aeroviz_import.py → aeroviz-0.1.10/tests/test_import.py +2 -2
- aeroviz-0.1.9.5/AeroViz/plot/hysplit/__init__.py +0 -1
- aeroviz-0.1.9.5/AeroViz/plot/meteorology/__init__.py +0 -1
- aeroviz-0.1.9.5/AeroViz/tools/datareader.py +0 -66
- aeroviz-0.1.9.5/AeroViz.egg-info/SOURCES.txt +0 -108
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/data/DEFAULT_DATA.csv +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/data/DEFAULT_PNSD_DATA.csv +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/data/hysplit_example_data.txt +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/Chemistry/__init__.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/Chemistry/_calculate.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/Chemistry/_isoropia.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/Chemistry/_mass_volume.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/Chemistry/_ocec.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/Chemistry/_partition.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/Chemistry/_teom.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/Chemistry/isrpia.cnf +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/Chemistry/isrpia2.exe +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/Optical/Angstrom_exponent.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/Optical/_IMPROVE.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/Optical/__init__.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/Optical/_absorption.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/Optical/_extinction.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/Optical/_mie.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/Optical/_mie_sd.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/Optical/_scattering.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/Optical/fRH.pkl +0 -0
- {aeroviz-0.1.9.5/AeroViz/plot/optical → aeroviz-0.1.10/AeroViz/dataProcess/Optical}/mie_theory.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/SizeDistr/__init__.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/SizeDistr/__merge.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/SizeDistr/_merge.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/SizeDistr/_merge_v1.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/SizeDistr/_merge_v2.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/SizeDistr/_merge_v3.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/SizeDistr/_merge_v4.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/SizeDistr/_size_distr.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/VOC/__init__.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/VOC/_potential_par.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/VOC/support_voc.json +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/__init__.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/dataProcess/core/__init__.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/bar.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/box.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/distribution/__init__.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/distribution/distribution.py +0 -0
- {aeroviz-0.1.9.5/AeroViz/plot/hysplit → aeroviz-0.1.10/AeroViz/plot/meteorology}/hysplit.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/optical/__init__.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/pie.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/radar.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/regression.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/scatter.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/templates/__init__.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/templates/ammonium_rich.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/templates/contour.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/templates/corr_matrix.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/templates/diurnal_pattern.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/templates/koschmieder.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/templates/metal_heatmap.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/timeseries/__init__.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/timeseries/template.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/timeseries/timeseries.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/utils/__init__.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/utils/_color.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/utils/_unit.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/utils/fRH.json +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/utils/sklearn_utils.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/utils/units.json +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/plot/violin.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/config/__init__.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/config/supported_instruments.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/core/qc.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/script/AE33.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/script/AE43.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/script/APS_3321.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/script/Aurora.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/script/BC1054.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/script/GRIMM.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/script/IGAC.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/script/MA350.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/script/NEPH.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/script/OCEC.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/script/TEOM.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/script/VOC.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/script/XRF.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/rawDataReader/script/__init__.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/tools/database.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/tools/dataclassifier.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz/tools/dataprinter.py +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz.egg-info/dependency_links.txt +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/AeroViz.egg-info/top_level.txt +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/LICENSE +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/setup.cfg +0 -0
- {aeroviz-0.1.9.5 → aeroviz-0.1.10}/setup.py +0 -0
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
from AeroViz import plot
|
|
3
3
|
from AeroViz.dataProcess import DataProcess
|
|
4
4
|
from AeroViz.rawDataReader import RawDataReader
|
|
5
|
-
from AeroViz.tools import DataBase,
|
|
5
|
+
from AeroViz.tools import DataBase, DataClassifier
|
|
6
6
|
|
|
7
7
|
__all__ = [
|
|
8
8
|
'plot',
|
|
9
9
|
'RawDataReader',
|
|
10
10
|
'DataProcess',
|
|
11
11
|
'DataBase',
|
|
12
|
-
'DataReader',
|
|
13
12
|
'DataClassifier'
|
|
14
13
|
]
|
|
Binary file
|
|
@@ -6,13 +6,6 @@ import numpy as np
|
|
|
6
6
|
from scipy.special import jv, yv
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
def coerceDType(d):
|
|
10
|
-
if type(d) is not np.ndarray:
|
|
11
|
-
return np.array(d)
|
|
12
|
-
else:
|
|
13
|
-
return d
|
|
14
|
-
|
|
15
|
-
|
|
16
9
|
def MieQ(m, wavelength, diameter, nMedium=1.0, asDict=False, asCrossSection=False):
|
|
17
10
|
# http://pymiescatt.readthedocs.io/en/latest/forward.html#MieQ
|
|
18
11
|
nMedium = nMedium.real
|
|
@@ -271,8 +264,8 @@ def Mie_SD(m, wavelength, dp, ndp, nMedium=1.0, SMPS=True, interpolate=False, as
|
|
|
271
264
|
nMedium = nMedium.real
|
|
272
265
|
m /= nMedium
|
|
273
266
|
wavelength /= nMedium
|
|
274
|
-
dp =
|
|
275
|
-
ndp =
|
|
267
|
+
dp = np.array(dp)
|
|
268
|
+
ndp = np.array(ndp)
|
|
276
269
|
_length = np.size(dp)
|
|
277
270
|
Q_ext = np.zeros(_length)
|
|
278
271
|
Q_sca = np.zeros(_length)
|
|
@@ -373,8 +366,8 @@ def SF_SD(m, wavelength, dp, ndp, nMedium=1.0, minAngle=0, maxAngle=180, angular
|
|
|
373
366
|
wavelength /= nMedium
|
|
374
367
|
|
|
375
368
|
_steps = int(1 + (maxAngle - minAngle) / angularResolution)
|
|
376
|
-
ndp =
|
|
377
|
-
dp =
|
|
369
|
+
ndp = np.array(ndp)
|
|
370
|
+
dp = np.array(dp)
|
|
378
371
|
SL = np.zeros(_steps)
|
|
379
372
|
SR = np.zeros(_steps)
|
|
380
373
|
SU = np.zeros(_steps)
|
|
Binary file
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from numpy import exp, log
|
|
3
|
+
from scipy.signal import find_peaks
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def geometric(dp: np.ndarray,
|
|
7
|
+
dist: np.ndarray
|
|
8
|
+
) -> tuple[float, float]:
|
|
9
|
+
""" Calculate the geometric mean and standard deviation. """
|
|
10
|
+
|
|
11
|
+
_gmd = (((dist * log(dp)).sum()) / dist.sum())
|
|
12
|
+
|
|
13
|
+
logdp_mesh, gmd_mesh = np.meshgrid(log(dp), _gmd)
|
|
14
|
+
_gsd = ((((logdp_mesh - gmd_mesh) ** 2) * dist).sum() / dist.sum()) ** .5
|
|
15
|
+
|
|
16
|
+
return exp(_gmd), exp(_gsd)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def contribution(dp: np.ndarray,
|
|
20
|
+
dist: np.ndarray
|
|
21
|
+
) -> tuple[float, float, float]:
|
|
22
|
+
""" Calculate the relative contribution of each mode. """
|
|
23
|
+
|
|
24
|
+
ultra = dist[(dp >= 11.8) & (dp < 100)].sum() / dist.sum()
|
|
25
|
+
accum = dist[(dp >= 100) & (dp < 1000)].sum() / dist.sum()
|
|
26
|
+
coars = dist[(dp >= 1000) & (dp < 2500)].sum() / dist.sum()
|
|
27
|
+
|
|
28
|
+
return ultra, accum, coars
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def mode(dp: np.ndarray,
|
|
32
|
+
dist: np.ndarray
|
|
33
|
+
) -> np.ndarray:
|
|
34
|
+
""" Find three peak mode in distribution. """
|
|
35
|
+
|
|
36
|
+
min_value = np.array([dist.min()])
|
|
37
|
+
mode, _ = find_peaks(np.concatenate([min_value, dist, min_value]), distance=len(dist) - 1)
|
|
38
|
+
|
|
39
|
+
return dp[mode - 1]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def properties(dist,
|
|
43
|
+
dp: np.ndarray,
|
|
44
|
+
dlogdp: np.ndarray,
|
|
45
|
+
weighting: str
|
|
46
|
+
) -> dict:
|
|
47
|
+
""" for apply """
|
|
48
|
+
dist = np.array(dist)
|
|
49
|
+
|
|
50
|
+
gmd, gsd = geometric(dp, dist)
|
|
51
|
+
ultra, accum, coarse = contribution(dp, dist)
|
|
52
|
+
peak = mode(dp, dist)
|
|
53
|
+
|
|
54
|
+
return {key: round(value, 3) for key, value in
|
|
55
|
+
{f'total_{weighting}': (dist * dlogdp).sum(),
|
|
56
|
+
f'GMD_{weighting}': gmd,
|
|
57
|
+
f'GSD_{weighting}': gsd,
|
|
58
|
+
f'mode_{weighting}': peak[0],
|
|
59
|
+
f'ultra_{weighting}': ultra,
|
|
60
|
+
f'accum_{weighting}': accum,
|
|
61
|
+
f'coarse_{weighting}': coarse}
|
|
62
|
+
.items()}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,85 +1,159 @@
|
|
|
1
1
|
import math
|
|
2
|
-
from typing import Literal
|
|
3
2
|
|
|
4
3
|
import matplotlib.pyplot as plt
|
|
5
4
|
import numpy as np
|
|
6
5
|
import pandas as pd
|
|
7
|
-
import windrose
|
|
8
6
|
from matplotlib.pyplot import Figure, Axes
|
|
9
7
|
from pandas import DataFrame, Series
|
|
10
8
|
from scipy.ndimage import gaussian_filter
|
|
11
9
|
|
|
12
10
|
from AeroViz.plot.utils import *
|
|
13
11
|
|
|
14
|
-
__all__ = ['
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
__all__ = ['CBPF']
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def improve_density_estimation(df, WS, WD, val, resolution=100, bandwidth=None):
|
|
16
|
+
"""
|
|
17
|
+
改進的密度估計函數,使用KDE方法來產生更平滑的分布
|
|
18
|
+
|
|
19
|
+
Parameters:
|
|
20
|
+
-----------
|
|
21
|
+
df : DataFrame
|
|
22
|
+
包含風速風向數據的DataFrame
|
|
23
|
+
WS : str
|
|
24
|
+
風速列名
|
|
25
|
+
WD : str
|
|
26
|
+
風向列名
|
|
27
|
+
val : str
|
|
28
|
+
要分析的變量列名
|
|
29
|
+
resolution : int
|
|
30
|
+
網格解析度
|
|
31
|
+
bandwidth : float or tuple
|
|
32
|
+
KDE的頻寬參數,如果為None則自動選擇
|
|
33
|
+
"""
|
|
34
|
+
from scipy.stats import gaussian_kde
|
|
35
|
+
import numpy as np
|
|
36
|
+
|
|
37
|
+
# 轉換為笛卡爾坐標
|
|
38
|
+
u = df[WS] * np.sin(np.radians(df[WD]))
|
|
39
|
+
v = df[WS] * np.cos(np.radians(df[WD]))
|
|
40
|
+
|
|
41
|
+
# 創建網格
|
|
42
|
+
u_range = np.linspace(u.min(), u.max(), resolution)
|
|
43
|
+
v_range = np.linspace(v.min(), v.max(), resolution)
|
|
44
|
+
U, V = np.meshgrid(u_range, v_range)
|
|
45
|
+
|
|
46
|
+
# 準備KDE的位置
|
|
47
|
+
positions = np.vstack([U.ravel(), V.ravel()])
|
|
48
|
+
values = np.vstack([u, v])
|
|
49
|
+
|
|
50
|
+
# 使用KDE進行密度估計
|
|
51
|
+
kernel = gaussian_kde(values, bw_method=bandwidth)
|
|
52
|
+
Z = np.reshape(kernel(positions), U.shape)
|
|
53
|
+
|
|
54
|
+
# 將密度值歸一化到[0,1]區間
|
|
55
|
+
Z = (Z - Z.min()) / (Z.max() - Z.min())
|
|
56
|
+
|
|
57
|
+
# 應用極坐標遮罩
|
|
58
|
+
center_u = len(u_range) // 2
|
|
59
|
+
center_v = len(v_range) // 2
|
|
60
|
+
max_radius = min(center_u, center_v)
|
|
61
|
+
|
|
62
|
+
Y, X = np.ogrid[-center_v:resolution - center_v, -center_u:resolution - center_u]
|
|
63
|
+
mask = X * X + Y * Y > max_radius * max_radius
|
|
64
|
+
Z[mask] = np.nan
|
|
65
|
+
|
|
66
|
+
return Z, U, V
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def smooth_and_clean(Z, smooth_radius=2, min_density=1):
|
|
70
|
+
"""
|
|
71
|
+
平滑並清理密度圖,去除孤立點
|
|
72
|
+
|
|
73
|
+
Parameters:
|
|
74
|
+
-----------
|
|
75
|
+
Z : ndarray
|
|
76
|
+
密度估計結果
|
|
77
|
+
smooth_radius : int
|
|
78
|
+
平滑半徑
|
|
79
|
+
min_density : float
|
|
80
|
+
最小密度閾值
|
|
81
|
+
"""
|
|
82
|
+
from scipy.ndimage import gaussian_filter
|
|
83
|
+
|
|
84
|
+
# 先進行高斯平滑
|
|
85
|
+
Z_smooth = gaussian_filter(Z, sigma=smooth_radius)
|
|
86
|
+
|
|
87
|
+
# 去除低於閾值的點
|
|
88
|
+
# Z_smooth[Z_smooth < min_density] = np.nan
|
|
89
|
+
|
|
90
|
+
# 去除孤立點
|
|
91
|
+
rows, cols = Z_smooth.shape
|
|
92
|
+
for i in range(rows):
|
|
93
|
+
for j in range(cols):
|
|
94
|
+
if not np.isnan(Z_smooth[i, j]):
|
|
95
|
+
# 檢查周圍點
|
|
96
|
+
neighborhood = Z_smooth[
|
|
97
|
+
max(0, i - smooth_radius):min(rows, i + smooth_radius + 1),
|
|
98
|
+
max(0, j - smooth_radius):min(cols, j + smooth_radius + 1)
|
|
99
|
+
]
|
|
100
|
+
if np.count_nonzero(~np.isnan(neighborhood)) < 1: # 如果周圍有效點太少
|
|
101
|
+
Z_smooth[i, j] = np.nan
|
|
102
|
+
|
|
103
|
+
return Z_smooth
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def is_within_circle(center_row, center_col, row, col, radius):
|
|
107
|
+
return np.sqrt((center_row - row) ** 2 + (center_col - col) ** 2) <= radius
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def remove_lonely_point(filtered_histogram, radius=4, magic_num=13):
|
|
111
|
+
rows, cols = filtered_histogram.shape
|
|
112
|
+
data_positions = np.where(~np.isnan(filtered_histogram))
|
|
113
|
+
|
|
114
|
+
for row, col in zip(*data_positions):
|
|
115
|
+
valid_data_count = 0
|
|
116
|
+
for i in range(max(0, row - radius), min(rows, row + radius + 1)):
|
|
117
|
+
for j in range(max(0, col - radius), min(cols, col + radius + 1)):
|
|
118
|
+
if (i, j) != (row, col) and is_within_circle(row, col, i, j, radius):
|
|
119
|
+
if not np.isnan(filtered_histogram[i, j]):
|
|
120
|
+
valid_data_count += 1
|
|
121
|
+
|
|
122
|
+
if valid_data_count <= magic_num:
|
|
123
|
+
filtered_histogram[row, col] = np.nan
|
|
124
|
+
|
|
125
|
+
return filtered_histogram
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def fill_nan_with_mean(filtered_histogram, radius=4, magic_num=13):
|
|
129
|
+
rows, cols = filtered_histogram.shape
|
|
130
|
+
nan_positions = np.where(np.isnan(filtered_histogram))
|
|
131
|
+
|
|
132
|
+
for row, col in zip(*nan_positions):
|
|
133
|
+
surrounding_values = []
|
|
134
|
+
surrounding_values_within_one = []
|
|
135
|
+
nan_count = 0
|
|
17
136
|
|
|
137
|
+
for i in range(max(0, row - radius), min(rows, row + radius + 1)):
|
|
138
|
+
for j in range(max(0, col - radius), min(cols, col + radius + 1)):
|
|
139
|
+
if (i, j) != (row, col) and is_within_circle(row, col, i, j, radius):
|
|
140
|
+
if np.isnan(filtered_histogram[i, j]):
|
|
141
|
+
nan_count += 1
|
|
142
|
+
else:
|
|
143
|
+
surrounding_values.append(filtered_histogram[i, j])
|
|
18
144
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
**kwargs
|
|
27
|
-
) -> tuple[Figure, Axes]:
|
|
28
|
-
# conditional bivariate probability function (cbpf) python
|
|
29
|
-
# https://davidcarslaw.github.io/openair/reference/polarPlot.html
|
|
30
|
-
# https://github.com/davidcarslaw/openair/blob/master/R/polarPlot.R
|
|
31
|
-
windrose.WindroseAxes._info = 'WindroseAxes'
|
|
32
|
-
|
|
33
|
-
df = df.dropna(subset=[WS, WD] + ([val] if val is not None else []))
|
|
34
|
-
|
|
35
|
-
radius = df[WS].to_numpy()
|
|
36
|
-
theta = df[WD].to_numpy()
|
|
37
|
-
radian = np.radians(theta)
|
|
38
|
-
values = df[val].to_numpy() if val is not None else None
|
|
39
|
-
|
|
40
|
-
# In this case, the windrose is a simple frequency diagram,
|
|
41
|
-
# the function automatically calculates the radians of the given wind direction.
|
|
42
|
-
if typ == 'bar':
|
|
43
|
-
fig, ax = plt.subplots(figsize=(5.5, 4), subplot_kw={'projection': 'windrose'})
|
|
44
|
-
fig.subplots_adjust(left=0)
|
|
45
|
-
|
|
46
|
-
ax.bar(theta, radius, bins=[0, 1, 2, 3], normed=True, colors=['#0F1035', '#365486', '#7FC7D9', '#DCF2F1'])
|
|
47
|
-
ax.set(
|
|
48
|
-
ylim=(0, 30),
|
|
49
|
-
yticks=[0, 15, 30],
|
|
50
|
-
yticklabels=['', '15 %', '30 %'],
|
|
51
|
-
rlabel_position=rlabel_pos
|
|
52
|
-
)
|
|
53
|
-
ax.set_thetagrids(angles=[0, 45, 90, 135, 180, 225, 270, 315],
|
|
54
|
-
labels=["E", "NE", "N", "NW", "W", "SW", "S", "SE"])
|
|
55
|
-
|
|
56
|
-
ax.legend(units='m/s', bbox_to_anchor=[1.1, 0.5], loc='center left', ncol=1)
|
|
57
|
-
|
|
58
|
-
# In this case, the windrose is a scatter plot,
|
|
59
|
-
# in contrary, this function does not calculate the radians, so user have to input the radian.
|
|
60
|
-
else:
|
|
61
|
-
fig, ax = plt.subplots(figsize=(5, 4), subplot_kw={'projection': 'windrose'})
|
|
62
|
-
fig.subplots_adjust(left=0)
|
|
63
|
-
|
|
64
|
-
scatter = ax.scatter(radian, radius, s=15, c=values, vmax=np.quantile(values, 0.90), edgecolors='none',
|
|
65
|
-
cmap='jet', alpha=0.8)
|
|
66
|
-
ax.set(
|
|
67
|
-
ylim=(0, 7),
|
|
68
|
-
yticks=[1, 3, 5, 7],
|
|
69
|
-
yticklabels=['1 m/s', '3 m/s', '5 m/s', '7 m/s'],
|
|
70
|
-
rlabel_position=rlabel_pos,
|
|
71
|
-
theta_direction=-1,
|
|
72
|
-
theta_zero_location='N',
|
|
73
|
-
title=kwargs.get('title', None)
|
|
74
|
-
)
|
|
75
|
-
ax.set_thetagrids(angles=[0, 45, 90, 135, 180, 225, 270, 315],
|
|
76
|
-
labels=["N", "NE", "E", "SE", "S", "SW", "W", "NW"])
|
|
77
|
-
|
|
78
|
-
plt.colorbar(scatter, ax=ax, label=Unit(val), pad=0.1, fraction=0.04)
|
|
145
|
+
for i in range(max(0, row - 2), min(rows, row + 2 + 1)):
|
|
146
|
+
for j in range(max(0, col - 2), min(cols, col + 2 + 1)):
|
|
147
|
+
if (i, j) != (row, col) and is_within_circle(row, col, i, j, 2):
|
|
148
|
+
if np.isnan(filtered_histogram[i, j]):
|
|
149
|
+
pass
|
|
150
|
+
else:
|
|
151
|
+
surrounding_values_within_one.append(filtered_histogram[i, j])
|
|
79
152
|
|
|
80
|
-
|
|
153
|
+
if nan_count < magic_num and surrounding_values_within_one:
|
|
154
|
+
filtered_histogram[row, col] = np.mean(surrounding_values)
|
|
81
155
|
|
|
82
|
-
return
|
|
156
|
+
return filtered_histogram
|
|
83
157
|
|
|
84
158
|
|
|
85
159
|
# TODO: fix the bug of the CBPF function
|
|
@@ -90,7 +164,7 @@ def CBPF(df: DataFrame,
|
|
|
90
164
|
val: Series | str | None = None,
|
|
91
165
|
percentile: list | float | int | None = None,
|
|
92
166
|
max_ws: float | None = 5,
|
|
93
|
-
resolution: int =
|
|
167
|
+
resolution: int = 50,
|
|
94
168
|
sigma: float | tuple = 2,
|
|
95
169
|
rlabel_pos: float = 30,
|
|
96
170
|
bottom_text: str | bool | None = None,
|
|
@@ -157,64 +231,18 @@ def CBPF(df: DataFrame,
|
|
|
157
231
|
histogram_filled = np.nan_to_num(histogram, nan=0) # 將 NaN 替換為 0
|
|
158
232
|
|
|
159
233
|
filtered_histogram = gaussian_filter(histogram_filled, sigma=sigma)
|
|
160
|
-
filtered_histogram[np.isnan(histogram)] = np.nan
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
return np.sqrt((center_row - row) ** 2 + (center_col - col) ** 2) <= radius
|
|
164
|
-
|
|
165
|
-
def remove_lonely_point(filtered_histogram, radius=4, magic_num=13):
|
|
166
|
-
rows, cols = filtered_histogram.shape
|
|
167
|
-
data_positions = np.where(~np.isnan(filtered_histogram))
|
|
168
|
-
|
|
169
|
-
for row, col in zip(*data_positions):
|
|
170
|
-
valid_data_count = 0
|
|
171
|
-
for i in range(max(0, row - radius), min(rows, row + radius + 1)):
|
|
172
|
-
for j in range(max(0, col - radius), min(cols, col + radius + 1)):
|
|
173
|
-
if (i, j) != (row, col) and is_within_circle(row, col, i, j, radius):
|
|
174
|
-
if not np.isnan(filtered_histogram[i, j]):
|
|
175
|
-
valid_data_count += 1
|
|
176
|
-
|
|
177
|
-
if valid_data_count <= magic_num:
|
|
178
|
-
filtered_histogram[row, col] = np.nan
|
|
179
|
-
|
|
180
|
-
return filtered_histogram
|
|
181
|
-
|
|
182
|
-
def fill_nan_with_mean(filtered_histogram, radius=4, magic_num=13):
|
|
183
|
-
rows, cols = filtered_histogram.shape
|
|
184
|
-
nan_positions = np.where(np.isnan(filtered_histogram))
|
|
185
|
-
|
|
186
|
-
for row, col in zip(*nan_positions):
|
|
187
|
-
surrounding_values = []
|
|
188
|
-
surrounding_values_within_one = []
|
|
189
|
-
nan_count = 0
|
|
190
|
-
|
|
191
|
-
for i in range(max(0, row - radius), min(rows, row + radius + 1)):
|
|
192
|
-
for j in range(max(0, col - radius), min(cols, col + radius + 1)):
|
|
193
|
-
if (i, j) != (row, col) and is_within_circle(row, col, i, j, radius):
|
|
194
|
-
if np.isnan(filtered_histogram[i, j]):
|
|
195
|
-
nan_count += 1
|
|
196
|
-
else:
|
|
197
|
-
surrounding_values.append(filtered_histogram[i, j])
|
|
198
|
-
|
|
199
|
-
for i in range(max(0, row - 2), min(rows, row + 2 + 1)):
|
|
200
|
-
for j in range(max(0, col - 2), min(cols, col + 2 + 1)):
|
|
201
|
-
if (i, j) != (row, col) and is_within_circle(row, col, i, j, 2):
|
|
202
|
-
if np.isnan(filtered_histogram[i, j]):
|
|
203
|
-
pass
|
|
204
|
-
else:
|
|
205
|
-
surrounding_values_within_one.append(filtered_histogram[i, j])
|
|
206
|
-
|
|
207
|
-
if nan_count < magic_num and surrounding_values_within_one:
|
|
208
|
-
filtered_histogram[row, col] = np.mean(surrounding_values)
|
|
209
|
-
|
|
210
|
-
return filtered_histogram
|
|
234
|
+
# filtered_histogram[np.isnan(histogram)] = np.nan
|
|
235
|
+
# breakpoint()
|
|
236
|
+
# filtered_histogram = smooth_and_clean(filtered_histogram)
|
|
211
237
|
|
|
212
238
|
# Apply the function to your data
|
|
213
|
-
fil_radius, magic_num = 3, 13
|
|
214
|
-
filtered_histogram = remove_lonely_point(filtered_histogram, fil_radius, magic_num)
|
|
215
|
-
filtered_histogram = fill_nan_with_mean(filtered_histogram, fil_radius, magic_num)
|
|
239
|
+
# fil_radius, magic_num = 3, 13
|
|
240
|
+
# filtered_histogram = remove_lonely_point(filtered_histogram, fil_radius, magic_num)
|
|
241
|
+
# filtered_histogram = fill_nan_with_mean(filtered_histogram, fil_radius, magic_num)
|
|
242
|
+
|
|
216
243
|
if np.all(np.isnan(filtered_histogram)):
|
|
217
244
|
raise ValueError("All values in the filtered histogram are NaN. Please decrease the resolution.")
|
|
245
|
+
|
|
218
246
|
# plot
|
|
219
247
|
fig, ax = plt.subplots()
|
|
220
248
|
fig.subplots_adjust(left=0)
|
|
Binary file
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from typing import Literal
|
|
2
|
+
|
|
3
|
+
import matplotlib.pyplot as plt
|
|
4
|
+
import numpy as np
|
|
5
|
+
import windrose
|
|
6
|
+
from matplotlib.pyplot import Figure, Axes
|
|
7
|
+
from pandas import DataFrame, Series
|
|
8
|
+
|
|
9
|
+
from AeroViz.plot.utils import *
|
|
10
|
+
|
|
11
|
+
__all__ = ['wind_rose']
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@set_figure(figsize=(4.3, 4))
|
|
15
|
+
def wind_rose(df: DataFrame,
|
|
16
|
+
WS: Series | str,
|
|
17
|
+
WD: Series | str,
|
|
18
|
+
val: Series | str | None = None,
|
|
19
|
+
typ: Literal['bar', 'scatter'] = 'scatter',
|
|
20
|
+
rlabel_pos: float = 30,
|
|
21
|
+
**kwargs
|
|
22
|
+
) -> tuple[Figure, Axes]:
|
|
23
|
+
# conditional bivariate probability function (cbpf) python
|
|
24
|
+
# https://davidcarslaw.github.io/openair/reference/polarPlot.html
|
|
25
|
+
# https://github.com/davidcarslaw/openair/blob/master/R/polarPlot.R
|
|
26
|
+
windrose.WindroseAxes._info = 'WindroseAxes'
|
|
27
|
+
|
|
28
|
+
df = df.dropna(subset=[WS, WD] + ([val] if val is not None else []))
|
|
29
|
+
|
|
30
|
+
radius = df[WS].to_numpy()
|
|
31
|
+
theta = df[WD].to_numpy()
|
|
32
|
+
radian = np.radians(theta)
|
|
33
|
+
values = df[val].to_numpy() if val is not None else None
|
|
34
|
+
|
|
35
|
+
# In this case, the windrose is a simple frequency diagram,
|
|
36
|
+
# the function automatically calculates the radians of the given wind direction.
|
|
37
|
+
if typ == 'bar':
|
|
38
|
+
fig, ax = plt.subplots(figsize=(5.5, 4), subplot_kw={'projection': 'windrose'})
|
|
39
|
+
fig.subplots_adjust(left=0)
|
|
40
|
+
|
|
41
|
+
ax.bar(theta, radius, bins=[0, 1, 2, 3], normed=True, colors=['#0F1035', '#365486', '#7FC7D9', '#DCF2F1'])
|
|
42
|
+
ax.set(
|
|
43
|
+
ylim=(0, 30),
|
|
44
|
+
yticks=[0, 15, 30],
|
|
45
|
+
yticklabels=['', '15 %', '30 %'],
|
|
46
|
+
rlabel_position=rlabel_pos
|
|
47
|
+
)
|
|
48
|
+
ax.set_thetagrids(angles=[0, 45, 90, 135, 180, 225, 270, 315],
|
|
49
|
+
labels=["E", "NE", "N", "NW", "W", "SW", "S", "SE"])
|
|
50
|
+
|
|
51
|
+
ax.legend(units='m/s', bbox_to_anchor=[1.1, 0.5], loc='center left', ncol=1)
|
|
52
|
+
|
|
53
|
+
# In this case, the windrose is a scatter plot,
|
|
54
|
+
# in contrary, this function does not calculate the radians, so user have to input the radian.
|
|
55
|
+
else:
|
|
56
|
+
fig, ax = plt.subplots(figsize=(5, 4), subplot_kw={'projection': 'windrose'})
|
|
57
|
+
fig.subplots_adjust(left=0)
|
|
58
|
+
|
|
59
|
+
scatter = ax.scatter(radian, radius, s=15, c=values, vmax=np.quantile(values, 0.90), edgecolors='none',
|
|
60
|
+
cmap='jet', alpha=0.8)
|
|
61
|
+
ax.set(
|
|
62
|
+
ylim=(0, 7),
|
|
63
|
+
yticks=[1, 3, 5, 7],
|
|
64
|
+
yticklabels=['1 m/s', '3 m/s', '5 m/s', '7 m/s'],
|
|
65
|
+
rlabel_position=rlabel_pos,
|
|
66
|
+
theta_direction=-1,
|
|
67
|
+
theta_zero_location='N',
|
|
68
|
+
title=kwargs.get('title', None)
|
|
69
|
+
)
|
|
70
|
+
ax.set_thetagrids(angles=[0, 45, 90, 135, 180, 225, 270, 315],
|
|
71
|
+
labels=["N", "NE", "E", "SE", "S", "SW", "W", "NW"])
|
|
72
|
+
|
|
73
|
+
plt.colorbar(scatter, ax=ax, label=Unit(val), pad=0.1, fraction=0.04)
|
|
74
|
+
|
|
75
|
+
plt.show()
|
|
76
|
+
|
|
77
|
+
return fig, ax
|
|
Binary file
|
|
Binary file
|
|
@@ -3,11 +3,10 @@ from typing import Literal
|
|
|
3
3
|
|
|
4
4
|
import matplotlib.pyplot as plt
|
|
5
5
|
import numpy as np
|
|
6
|
-
# from PyMieScatt import ScatteringFunction
|
|
7
6
|
from matplotlib.pyplot import Figure, Axes
|
|
8
7
|
|
|
9
|
-
from AeroViz.
|
|
10
|
-
from AeroViz.
|
|
8
|
+
from AeroViz.dataProcess.Optical.PyMieScatt_update import ScatteringFunction
|
|
9
|
+
from AeroViz.dataProcess.Optical.mie_theory import Mie_Q, Mie_MEE, Mie_PESD
|
|
11
10
|
from AeroViz.plot.utils import *
|
|
12
11
|
|
|
13
12
|
__all__ = ['Q_plot',
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -50,7 +50,7 @@ def set_figure(func=None,
|
|
|
50
50
|
plt.rcParams['legend.labelspacing'] = 0.7
|
|
51
51
|
|
|
52
52
|
plt.rcParams['figure.figsize'] = figsize or (4, 4)
|
|
53
|
-
plt.rcParams['figure.dpi'] =
|
|
53
|
+
plt.rcParams['figure.dpi'] = 300
|
|
54
54
|
plt.rcParams['figure.autolayout'] = autolayout
|
|
55
55
|
|
|
56
56
|
if not autolayout:
|