AeroViz 0.1.0__py3-none-any.whl

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.

Files changed (102) hide show
  1. AeroViz/__init__.py +15 -0
  2. AeroViz/dataProcess/Chemistry/__init__.py +63 -0
  3. AeroViz/dataProcess/Chemistry/_calculate.py +27 -0
  4. AeroViz/dataProcess/Chemistry/_isoropia.py +99 -0
  5. AeroViz/dataProcess/Chemistry/_mass_volume.py +175 -0
  6. AeroViz/dataProcess/Chemistry/_ocec.py +184 -0
  7. AeroViz/dataProcess/Chemistry/_partition.py +29 -0
  8. AeroViz/dataProcess/Chemistry/_teom.py +16 -0
  9. AeroViz/dataProcess/Optical/_IMPROVE.py +61 -0
  10. AeroViz/dataProcess/Optical/__init__.py +62 -0
  11. AeroViz/dataProcess/Optical/_absorption.py +54 -0
  12. AeroViz/dataProcess/Optical/_extinction.py +36 -0
  13. AeroViz/dataProcess/Optical/_mie.py +16 -0
  14. AeroViz/dataProcess/Optical/_mie_sd.py +143 -0
  15. AeroViz/dataProcess/Optical/_scattering.py +30 -0
  16. AeroViz/dataProcess/SizeDistr/__init__.py +61 -0
  17. AeroViz/dataProcess/SizeDistr/__merge.py +250 -0
  18. AeroViz/dataProcess/SizeDistr/_merge.py +245 -0
  19. AeroViz/dataProcess/SizeDistr/_merge_v1.py +254 -0
  20. AeroViz/dataProcess/SizeDistr/_merge_v2.py +243 -0
  21. AeroViz/dataProcess/SizeDistr/_merge_v3.py +518 -0
  22. AeroViz/dataProcess/SizeDistr/_merge_v4.py +424 -0
  23. AeroViz/dataProcess/SizeDistr/_size_distr.py +93 -0
  24. AeroViz/dataProcess/VOC/__init__.py +19 -0
  25. AeroViz/dataProcess/VOC/_potential_par.py +76 -0
  26. AeroViz/dataProcess/__init__.py +11 -0
  27. AeroViz/dataProcess/core/__init__.py +92 -0
  28. AeroViz/plot/__init__.py +7 -0
  29. AeroViz/plot/distribution/__init__.py +1 -0
  30. AeroViz/plot/distribution/distribution.py +582 -0
  31. AeroViz/plot/improve/__init__.py +1 -0
  32. AeroViz/plot/improve/improve.py +240 -0
  33. AeroViz/plot/meteorology/__init__.py +1 -0
  34. AeroViz/plot/meteorology/meteorology.py +317 -0
  35. AeroViz/plot/optical/__init__.py +2 -0
  36. AeroViz/plot/optical/aethalometer.py +77 -0
  37. AeroViz/plot/optical/optical.py +388 -0
  38. AeroViz/plot/templates/__init__.py +8 -0
  39. AeroViz/plot/templates/contour.py +47 -0
  40. AeroViz/plot/templates/corr_matrix.py +108 -0
  41. AeroViz/plot/templates/diurnal_pattern.py +42 -0
  42. AeroViz/plot/templates/event_evolution.py +65 -0
  43. AeroViz/plot/templates/koschmieder.py +156 -0
  44. AeroViz/plot/templates/metal_heatmap.py +57 -0
  45. AeroViz/plot/templates/regression.py +256 -0
  46. AeroViz/plot/templates/scatter.py +130 -0
  47. AeroViz/plot/templates/templates.py +398 -0
  48. AeroViz/plot/timeseries/__init__.py +1 -0
  49. AeroViz/plot/timeseries/timeseries.py +317 -0
  50. AeroViz/plot/utils/__init__.py +3 -0
  51. AeroViz/plot/utils/_color.py +71 -0
  52. AeroViz/plot/utils/_decorator.py +74 -0
  53. AeroViz/plot/utils/_unit.py +55 -0
  54. AeroViz/process/__init__.py +31 -0
  55. AeroViz/process/core/DataProc.py +19 -0
  56. AeroViz/process/core/SizeDist.py +90 -0
  57. AeroViz/process/core/__init__.py +4 -0
  58. AeroViz/process/method/PyMieScatt_update.py +567 -0
  59. AeroViz/process/method/__init__.py +2 -0
  60. AeroViz/process/method/mie_theory.py +258 -0
  61. AeroViz/process/method/prop.py +62 -0
  62. AeroViz/process/script/AbstractDistCalc.py +143 -0
  63. AeroViz/process/script/Chemical.py +176 -0
  64. AeroViz/process/script/IMPACT.py +49 -0
  65. AeroViz/process/script/IMPROVE.py +161 -0
  66. AeroViz/process/script/Others.py +65 -0
  67. AeroViz/process/script/PSD.py +103 -0
  68. AeroViz/process/script/PSD_dry.py +94 -0
  69. AeroViz/process/script/__init__.py +5 -0
  70. AeroViz/process/script/retrieve_RI.py +70 -0
  71. AeroViz/rawDataReader/__init__.py +68 -0
  72. AeroViz/rawDataReader/core/__init__.py +397 -0
  73. AeroViz/rawDataReader/script/AE33.py +31 -0
  74. AeroViz/rawDataReader/script/AE43.py +34 -0
  75. AeroViz/rawDataReader/script/APS_3321.py +47 -0
  76. AeroViz/rawDataReader/script/Aurora.py +38 -0
  77. AeroViz/rawDataReader/script/BC1054.py +46 -0
  78. AeroViz/rawDataReader/script/EPA_vertical.py +18 -0
  79. AeroViz/rawDataReader/script/GRIMM.py +35 -0
  80. AeroViz/rawDataReader/script/IGAC_TH.py +104 -0
  81. AeroViz/rawDataReader/script/IGAC_ZM.py +90 -0
  82. AeroViz/rawDataReader/script/MA350.py +45 -0
  83. AeroViz/rawDataReader/script/NEPH.py +57 -0
  84. AeroViz/rawDataReader/script/OCEC_LCRES.py +34 -0
  85. AeroViz/rawDataReader/script/OCEC_RES.py +28 -0
  86. AeroViz/rawDataReader/script/SMPS_TH.py +41 -0
  87. AeroViz/rawDataReader/script/SMPS_aim11.py +51 -0
  88. AeroViz/rawDataReader/script/SMPS_genr.py +51 -0
  89. AeroViz/rawDataReader/script/TEOM.py +46 -0
  90. AeroViz/rawDataReader/script/Table.py +28 -0
  91. AeroViz/rawDataReader/script/VOC_TH.py +30 -0
  92. AeroViz/rawDataReader/script/VOC_ZM.py +37 -0
  93. AeroViz/rawDataReader/script/__init__.py +22 -0
  94. AeroViz/tools/__init__.py +3 -0
  95. AeroViz/tools/database.py +94 -0
  96. AeroViz/tools/dataclassifier.py +117 -0
  97. AeroViz/tools/datareader.py +66 -0
  98. AeroViz-0.1.0.dist-info/LICENSE +21 -0
  99. AeroViz-0.1.0.dist-info/METADATA +117 -0
  100. AeroViz-0.1.0.dist-info/RECORD +102 -0
  101. AeroViz-0.1.0.dist-info/WHEEL +5 -0
  102. AeroViz-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,94 @@
1
+ from io import StringIO
2
+ from pathlib import Path
3
+ from typing import Literal
4
+
5
+ from pandas import read_csv, DataFrame
6
+
7
+
8
+ def load_default_chemical_data():
9
+ # The following data is from the chemical composition of real atmospheric particles.
10
+ #
11
+ # The six main chemical components that comprised PM2.5 are listed in the data.
12
+ # Here, we test the radar charts to see if we can clearly identify how the
13
+ # chemical components vary between the three pollutant scenarios:
14
+ #
15
+ # 1) Whole sampling period (Total)
16
+ # 2) Clean period (Clean)
17
+ # 3) Transition period (Transition)
18
+ # 4) Event period (Event)
19
+
20
+ data = {
21
+ 'Sulfate': [0.01, 0.34, 0.02, 0.71],
22
+ 'Nitrate': [0.88, 0.13, 0.34, 0.13],
23
+ 'OC': [0.07, 0.95, 0.04, 0.05],
24
+ 'EC': [0.20, 0.02, 0.85, 0.19],
25
+ 'Soil': [0.20, 0.10, 0.07, 0.01],
26
+ 'SS': [0.20, 0.10, 0.07, 0.01]
27
+ }
28
+
29
+ return DataFrame(data, index=['Total', 'Clean', 'Transition', 'Event'])
30
+
31
+
32
+ def load_dataset_by_url(dataset_name: Literal["Tunghai", "Taipei"] = "Tunghai") -> DataFrame:
33
+ import requests
34
+ dataset_uris = {
35
+ "Tunghai": "https://raw.githubusercontent.com/alex870521/DataPlot/main/DataPlot/config/default_data.csv"
36
+ }
37
+
38
+ # Ensure the dataset name is valid
39
+ if dataset_name not in dataset_uris:
40
+ raise ValueError(f"Dataset {dataset_name} is not supported.")
41
+
42
+ url = dataset_uris[dataset_name]
43
+
44
+ # Make a request to the URL
45
+ response = requests.get(url)
46
+
47
+ if response.status_code == 200:
48
+ return read_csv(StringIO(response.text), parse_dates=['Time'], index_col='Time')
49
+ else:
50
+ print(f"Failed to download file: {response.status_code}")
51
+ print(response.text) # Print the response text for debugging
52
+ return DataFrame() # Return an empty DataFrame in case of failure
53
+
54
+
55
+ def load_dataset_local(dataset_name: Literal["Tunghai", "Taipei"] = "Tunghai") -> DataFrame:
56
+ base_dir = Path(__file__).resolve().parent.parent
57
+ config_dir = base_dir / 'config'
58
+
59
+ dataset_paths = {
60
+ "Tunghai": config_dir / 'DEFAULT_DATA.csv',
61
+ "Taipei": config_dir / 'DEFAULT_DATA.csv',
62
+ }
63
+
64
+ if dataset_name not in dataset_paths:
65
+ raise ValueError(f"Dataset {dataset_name} is not supported.")
66
+
67
+ file_path = dataset_paths[dataset_name]
68
+
69
+ if not file_path.exists():
70
+ raise FileNotFoundError(f"The file {file_path} does not exist.")
71
+
72
+ return read_csv(file_path, parse_dates=['Time'], index_col='Time', na_values=('-', 'E', 'F'), low_memory=False)
73
+
74
+
75
+ class DataBase:
76
+ def __new__(cls, file_path=None):
77
+ file_path = Path(file_path) if file_path is not None else load_dataset_local
78
+
79
+ print(f'\t\t \033[96m --- Loading Data --- \033[0m')
80
+
81
+ if file_path.exists():
82
+ return read_csv(file_path, parse_dates=['Time'], index_col='Time', na_values=('-', 'E', 'F'),
83
+ low_memory=False)
84
+ else:
85
+ use_default = input(
86
+ "The required file does not exist. Do you want to use default data? (yes/no): ").strip().lower()
87
+ if use_default == 'yes':
88
+ return load_dataset_local("Tunghai")
89
+ else:
90
+ raise FileNotFoundError("Required files are missing. Please process data to generate these files.")
91
+
92
+
93
+ if __name__ == '__main__':
94
+ df = DataBase("Tunghai")
@@ -0,0 +1,117 @@
1
+ from datetime import datetime
2
+ from typing import Literal, Sequence
3
+
4
+ import pandas as pd
5
+ from pandas import concat, DataFrame, Series
6
+
7
+
8
+ class Classifier:
9
+ Seasons = {'2020-Summer': (datetime(2020, 9, 4), datetime(2020, 9, 21, 23)),
10
+ '2020-Autumn': (datetime(2020, 9, 22), datetime(2020, 12, 29, 23)),
11
+ '2020-Winter': (datetime(2020, 12, 30), datetime(2021, 3, 25, 23)),
12
+ '2021-Spring': (datetime(2021, 3, 26), datetime(2021, 5, 6, 23))}
13
+
14
+ # '2021-Summer': (datetime(2021, 5, 7), datetime(2021, 10, 16, 23))
15
+ # '2021-Autumn': (datetime(2021, 10, 17), datetime(2021, 12, 31, 23))
16
+
17
+ @classmethod
18
+ def classify(cls, df) -> DataFrame:
19
+ df = cls.classify_by_diurnal(df)
20
+ df = cls.classify_by_state(df)
21
+ df = cls.classify_by_season(df)
22
+ df = cls.classify_by_season_state(df)
23
+
24
+ return df
25
+
26
+ @classmethod
27
+ def classify_by_diurnal(cls, df):
28
+ df['Hour'] = df.index.hour
29
+ df['Diurnal'] = df['Hour'].apply(cls.map_diurnal)
30
+ return df
31
+
32
+ @classmethod
33
+ def classify_by_state(cls, df):
34
+ df['State'] = df.apply(cls.map_state, axis=1, clean_bound=df.Extinction.quantile(0.2),
35
+ event_bound=df.Extinction.quantile(0.8))
36
+ return df
37
+
38
+ @classmethod
39
+ def classify_by_season(cls, df):
40
+ for season, (season_start, season_end) in cls.Seasons.items():
41
+ df.loc[season_start:season_end, 'Season'] = season
42
+ return df
43
+
44
+ @classmethod
45
+ def classify_by_season_state(cls, df):
46
+ for _grp, _df in df.groupby('Season'):
47
+ df['Season_State'] = df.apply(cls.map_state, axis=1, clean_bound=_df.Extinction.quantile(0.2),
48
+ event_bound=_df.Extinction.quantile(0.8))
49
+ return df
50
+
51
+ @staticmethod
52
+ def map_diurnal(hour):
53
+ return 'Day' if 7 <= hour <= 18 else 'Night'
54
+
55
+ @staticmethod
56
+ def map_state(row, clean_bound, event_bound):
57
+ return 'Event' if row['Extinction'] >= event_bound else 'Clean' if row[
58
+ 'Extinction'] < clean_bound else 'Transition'
59
+
60
+
61
+ class DataClassifier(Classifier):
62
+ """
63
+ Notes
64
+ -----
65
+ First, create group then return the selected statistic method.
66
+ If the 'by' does not exist in DataFrame, import the default DataFrame to help to sign the different group.
67
+
68
+ """
69
+
70
+ def __new__(cls,
71
+ df: DataFrame,
72
+ by: Literal["Hour", "State", "Season", "Season_state"] | str,
73
+ df_support: DataFrame | Series = None,
74
+ cut_bins: Sequence = None,
75
+ qcut: int = None,
76
+ labels: list[str] = None
77
+ ) -> tuple[DataFrame, DataFrame]:
78
+ group = cls._group_data(df, by, df_support, cut_bins, qcut, labels)
79
+ return cls._compute_statistics(df, group)
80
+
81
+ @staticmethod
82
+ def _group_data(df, by, df_support, cut_bins, qcut, labels):
83
+ if by not in df.columns:
84
+ if df_support is None:
85
+ raise KeyError(f"Column '{by}' does not exist in DataFrame."
86
+ f"Please provide a support DataFrame or Series to help classify.")
87
+ else:
88
+ df = concat([df, Classifier.classify(df_support.copy())[by]], axis=1)
89
+
90
+ if cut_bins is not None:
91
+ df[f'{by}_cut'] = pd.cut(df.loc[:, f'{by}'], cut_bins,
92
+ labels=labels or (cut_bins + (cut_bins[1] - cut_bins[0]) / 2)[:-1])
93
+ return df.groupby(f'{by}_cut', observed=False)
94
+
95
+ elif qcut is not None:
96
+ df[f'{by}_qcut'] = pd.qcut(df.loc[:, f'{by}'], q=qcut, labels=labels)
97
+ return df.groupby(f'{by}_qcut', observed=False)
98
+
99
+ else:
100
+ if by == 'State':
101
+ return df.groupby(by)
102
+
103
+ elif by == 'Season':
104
+ return df.groupby(pd.Categorical(df['Season'], categories=['2020-Summer', '2020-Autumn', '2020-Winter',
105
+ '2021-Spring']), observed=False)
106
+ else:
107
+ return df.groupby(by, observed=False)
108
+
109
+ @staticmethod
110
+ def _compute_statistics(df, group):
111
+ mean_df = group.mean(numeric_only=True)
112
+ mean_df.loc['Total'] = df.mean(numeric_only=True)
113
+
114
+ std_df = group.std(numeric_only=True)
115
+ std_df.loc['Total'] = df.std(numeric_only=True)
116
+
117
+ return mean_df, std_df
@@ -0,0 +1,66 @@
1
+ from abc import ABC, abstractmethod
2
+ from pathlib import Path
3
+
4
+ from pandas import read_csv, read_json, read_excel, DataFrame
5
+
6
+
7
+ class FileHandler(ABC):
8
+ """ An abstract base class for reading data files with different extensions (.csv, .json, .xls, .xlsx). """
9
+
10
+ @abstractmethod
11
+ def read_data(self, file_path: Path) -> DataFrame:
12
+ pass
13
+
14
+
15
+ class CsvFileHandler(FileHandler):
16
+ def read_data(self, file_path: Path) -> DataFrame:
17
+ return read_csv(file_path, na_values=('-', 'E', 'F', '#', '*'),
18
+ parse_dates=['Time'], index_col='Time', low_memory=False)
19
+
20
+
21
+ class JsonFileHandler(FileHandler):
22
+ def read_data(self, file_path: Path) -> DataFrame:
23
+ return read_json(file_path)
24
+
25
+
26
+ class ExcelFileHandler(FileHandler):
27
+ def read_data(self, file_path: Path) -> DataFrame:
28
+ return read_excel(file_path, parse_dates=['Time'])
29
+
30
+
31
+ class DataReaderFactory:
32
+ _handler_mapping = {
33
+ '.csv': CsvFileHandler(),
34
+ '.json': JsonFileHandler(),
35
+ '.xls': ExcelFileHandler(),
36
+ '.xlsx': ExcelFileHandler(),
37
+ }
38
+
39
+ @staticmethod
40
+ def create_handler(file_extension: str) -> FileHandler:
41
+ reader_class = DataReaderFactory._handler_mapping.get(file_extension)
42
+ if reader_class is None:
43
+ raise ValueError(f"Unsupported file format: {file_extension}")
44
+ return reader_class
45
+
46
+
47
+ class DataReader:
48
+ """
49
+ A class for reading data files with different extensions (.csv, .json, .xls, .xlsx).
50
+
51
+ Parameters
52
+ ----------
53
+ filename (Path | str): The name of the file to be read or the Path of the file.
54
+
55
+ Returns
56
+ -------
57
+ pandas.DataFrame: data
58
+
59
+ Examples
60
+ --------
61
+ >>> psd = DataReader(Path(...))
62
+ """
63
+
64
+ def __new__(cls, file_path: Path | str) -> DataFrame:
65
+ file_path = Path(file_path)
66
+ return DataReaderFactory.create_handler(file_path.suffix.lower()).read_data(file_path)
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Chih-Yu Chan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,117 @@
1
+ Metadata-Version: 2.1
2
+ Name: AeroViz
3
+ Version: 0.1.0
4
+ Summary: Aerosol science
5
+ Home-page: https://github.com/Alex870521/AeroViz
6
+ Author: alex
7
+ Author-email: alex870521@gmail.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.12
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: pandas
15
+ Requires-Dist: numpy
16
+ Requires-Dist: matplotlib
17
+ Requires-Dist: seaborn
18
+ Requires-Dist: scipy
19
+ Requires-Dist: scikit-learn
20
+ Requires-Dist: windrose
21
+ Requires-Dist: tabulate
22
+
23
+ ## <div align="center">AeroViz for Aerosol Science</div>
24
+
25
+ <p align="center">
26
+
27
+ <img alt="Static Badge" src="https://img.shields.io/badge/python-3.12-blue?logo=python">
28
+ <img alt="Static Badge" src="https://img.shields.io/badge/License-MIT-yellow">
29
+ <img alt="Static Badge" src="https://img.shields.io/badge/github-updating-red?logo=github">
30
+ <img src="https://img.shields.io/badge/testing-green?logo=Pytest&logoColor=blue">
31
+
32
+ </p>
33
+
34
+ <div align="center">
35
+
36
+ <a href="https://github.com/Alex870521"><img src="https://github.com/Alex870521/assets_repo/blob/main/assets/media/logo-social-github.png?raw=true" width="3%" alt="Alex870521 GitHub"></a>
37
+ <img src="https://github.com/Alex870521/assets_repo/blob/main/assets/media/logo-transparent.png?raw=true" width="3%">
38
+ <a href="https://www.linkedin.com/in/Alex870521/"><img src="https://github.com/Alex870521/assets_repo/blob/main/assets/media/logo-social-linkedin.png?raw=true" width="3%" alt="Alex870521 LinkedIn"></a>
39
+ <img src="https://github.com/Alex870521/assets_repo/blob/main/assets/media/logo-transparent.png?raw=true" width="3%">
40
+ <a href="https://medium.com/@alex870521"><img src="https://github.com/Alex870521/assets_repo/blob/main/assets/media/logo-social-medium.png?raw=true" width="3%" alt="Alex870521 Medium"></a>
41
+
42
+
43
+ </div>
44
+
45
+ ## <div align="center">Supported Instruments</div>
46
+
47
+ > [!NOTE]\
48
+ > We are continuously working to support more instruments. Please check back for updates or contribute to our project on
49
+ > GitHub.
50
+
51
+ The AeroViz project currently supports data from the following instruments:
52
+
53
+ - **SMPS (Scanning Mobility Particle Sizer)**
54
+ - **APS (Aerodynamic Particle Sizer)**
55
+ - **GRIMM (GRIMM Aerosol Technik)**
56
+ - **TEOM (Continuous Ambient Particulate Monitor)**
57
+ - **NEPH (Nephelometer)**
58
+ - **Aurora (Nephelometer)**
59
+ - **AE33 (Aethalometer Model 33)**
60
+ - **AE43 (Aethalometer Model 43)**
61
+ - **BC1054 (Black Carbon Monitor 1054)**
62
+ - **MA350 (MicroAeth MA350)**
63
+ - **OCEC (Organic Carbon Elemental Carbon Analyzer)**
64
+ - **IGAC (In-situ Gas and Aerosol Compositions monitor)**
65
+ - **VOC (Volatile Organic Compounds Monitor)**
66
+
67
+ [//]: # (## <div align="center">Visual Example</div>)
68
+
69
+ ### <div align="center">WindRose and Conditional Bivariate Probability Function (CBPF)</div>
70
+
71
+ > [!TIP]\
72
+ > The provided code of WindRose and CBPF suitable for wind speed and wind direction data.
73
+
74
+ ![WindRose](https://github.com/Alex870521/assets_repo/blob/main/assets/figure/windrose_CBPF.png?raw=true)
75
+
76
+ ## <div align="center">Particle Size Distribution</div>
77
+
78
+ > [!IMPORTANT]\
79
+ > The provided code of distribution suitable for SMPS and APS data in "dX/dlogdp" unit.
80
+ > It can be converted into surface area and volume distribution. At the same time,
81
+ > chemical composition data can also be used to calculate particle extinction through Mie theory.
82
+
83
+ ![PNSD](https://github.com/Alex870521/assets_repo/blob/main/assets/figure/OverPSD.png?raw=true)
84
+
85
+ ## <div align="center">For some basic plot</div>
86
+
87
+ | **Three_dimension** | **Correlation Matrix** | **Mutiply Linear Regression** |
88
+ |:---------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------:|
89
+ | ![PSD 3D](https://github.com/Alex870521/assets_repo/blob/main/assets/figure/psd_3D.png?raw=true) | ![Correlation Matrix](https://github.com/Alex870521/assets_repo/blob/main/assets/figure/corr_matrix.png?raw=true) | ![IMPROVE MLR](https://github.com/Alex870521/assets_repo/blob/main/assets/figure/IMPROVE_MLR.png?raw=true) |
90
+ | **Pie & Donut** | **Dounts** | **Scatter** |
91
+ | ![IMPROVE donuts](https://github.com/Alex870521/assets_repo/blob/main/assets/figure/IMPROVE_donut.png?raw=true) | ![IMPROVE bar](https://github.com/Alex870521/assets_repo/blob/main/assets/figure/IMPROVE_donuts.png?raw=true) | ![scatter](https://github.com/Alex870521/assets_repo/blob/main/assets/figure/scatter.png?raw=true) |
92
+
93
+ ## <div align="center">PyMieScatt</div>
94
+
95
+ | **Mie_Q** | **Mie_MEE** |
96
+ |:----------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------:|
97
+ | ![Mie Q](https://github.com/Alex870521/assets_repo/blob/main/assets/figure/Mie_Q.png?raw=true) | ![Mie MEE](https://github.com/Alex870521/assets_repo/blob/main/assets/figure/Mie_MEE.png?raw=true) | |
98
+
99
+ ## <div align="center">Related Dependencies</div>
100
+
101
+ * [PyMieScatt](https://github.com/bsumlin/PyMieScatt.git)
102
+ * [py-smps](https://github.com/quant-aq/py-smps.git)
103
+
104
+ ## <div align="center">Contact</div>
105
+
106
+ For bug reports and feature requests please visit [GitHub Issues](https://github.com/Alex870521/DataPlot/issues).
107
+
108
+ <div align="center">
109
+
110
+ <a href="https://github.com/Alex870521"><img src="https://github.com/Alex870521/assets_repo/blob/main/assets/media/logo-social-github.png?raw=true" width="3%" alt="Alex870521 GitHub"></a>
111
+ <img src="https://github.com/Alex870521/assets_repo/blob/main/assets/media/logo-transparent.png?raw=true" width="3%">
112
+ <a href="https://www.linkedin.com/in/Alex870521/"><img src="https://github.com/Alex870521/assets_repo/blob/main/assets/media/logo-social-linkedin.png?raw=true" width="3%" alt="Alex870521 LinkedIn"></a>
113
+ <img src="https://github.com/Alex870521/assets_repo/blob/main/assets/media/logo-transparent.png?raw=true" width="3%">
114
+ <a href="https://medium.com/@alex870521"><img src="https://github.com/Alex870521/assets_repo/blob/main/assets/media/logo-social-medium.png?raw=true" width="3%" alt="Alex870521 Medium"></a>
115
+
116
+
117
+ </div>
@@ -0,0 +1,102 @@
1
+ AeroViz/__init__.py,sha256=5tu5vBrdHbLt152jaEmq2fgRBV6G7_KteIGysZH6lZ4,541
2
+ AeroViz/dataProcess/__init__.py,sha256=6y-sYreiqlI6WIm7rkDCZJdM3JQhK3hsDySS1GpqKOY,179
3
+ AeroViz/dataProcess/Chemistry/__init__.py,sha256=2YZYRcYjREEhDcheC4vH8GfbjA-0gc5hSbJJyymg5jE,1768
4
+ AeroViz/dataProcess/Chemistry/_calculate.py,sha256=LiqJ8mpQLMwg-QuhT7A6zNLojnmOMX4lz6PD5wbqhOw,568
5
+ AeroViz/dataProcess/Chemistry/_isoropia.py,sha256=soHaydApQ-yS0GdHz8jkQcWXlTr6JcyoXCUXHui46_g,3045
6
+ AeroViz/dataProcess/Chemistry/_mass_volume.py,sha256=61KVbqC-Y3LAiLNvTiCwOw35eNcsfxp_m6QM72cvbtI,4587
7
+ AeroViz/dataProcess/Chemistry/_ocec.py,sha256=JZ7HDwfkiz8xfo0W-b-kJbqpC-X7WaKAACRIUxTLt8Q,5497
8
+ AeroViz/dataProcess/Chemistry/_partition.py,sha256=2BoJ3I8N9V4pZcXdRRFywM0BYhTMWPZ7cohZm3xuCKQ,995
9
+ AeroViz/dataProcess/Chemistry/_teom.py,sha256=PuTFQDLs1_e41KUt06nfykDHm8D8jCIRsYC7F-45lxM,447
10
+ AeroViz/dataProcess/Optical/_IMPROVE.py,sha256=b8NuFG4huZKjOLnF21FrwClBQAHlOdcT8Wqv3GzcDoI,1560
11
+ AeroViz/dataProcess/Optical/__init__.py,sha256=3jy6Sw1AEOLAZ_rdYd1r2d-bcM4_5xkKCVFRxLDlzzI,1234
12
+ AeroViz/dataProcess/Optical/_absorption.py,sha256=PUDA-TRvwJzgLKG3nO-H6vX6SNB4I4bbg_77CST2U1g,1395
13
+ AeroViz/dataProcess/Optical/_extinction.py,sha256=phAy57-5KJXQCz3xCEGRMV410Avhge8pvJrpWGlEFOU,894
14
+ AeroViz/dataProcess/Optical/_mie.py,sha256=3eGGIPnWjhX0ofUgQwBsUu2A9Fb_9LF1EI3FiSS-8fo,430
15
+ AeroViz/dataProcess/Optical/_mie_sd.py,sha256=DpBFBDPqhd8ho0Yx4RvIjoe-O_-YJHqI3GJumi5qjn8,4459
16
+ AeroViz/dataProcess/Optical/_scattering.py,sha256=nXKcLX5SC7__jMhrUHs2Rz59F0nbhiHrR0eNggRpjd8,571
17
+ AeroViz/dataProcess/SizeDistr/__init__.py,sha256=0fbwbOYPBo-q-4PaDsZPT5CMcZQ66bgz_BTtEqHA-co,1950
18
+ AeroViz/dataProcess/SizeDistr/__merge.py,sha256=z2aapvU0zg64Pobi2J3d1YRUJrppcAd72saQBFrt9WI,8795
19
+ AeroViz/dataProcess/SizeDistr/_merge.py,sha256=Dnql8ntfPX34e6jkP1h70tgDwegbnEh02NJmSFLvqdE,8512
20
+ AeroViz/dataProcess/SizeDistr/_merge_v1.py,sha256=LrdBjBp5BGlUUm4y-olGuaERwiR5Htfq4_xxpNoK2is,8898
21
+ AeroViz/dataProcess/SizeDistr/_merge_v2.py,sha256=8i3jN5txzctAYjCbVLJBcLoOIZgJYnnSnmj7zY3OKSs,8397
22
+ AeroViz/dataProcess/SizeDistr/_merge_v3.py,sha256=dn-K4mkyzFlYUQ-DDywWUJKZ4Bdp2iPVR9rwT7uUGAY,16780
23
+ AeroViz/dataProcess/SizeDistr/_merge_v4.py,sha256=akq4sGRAX0tERQar3-oNERfyvdo2hL8l6xXewblNxZU,14693
24
+ AeroViz/dataProcess/SizeDistr/_size_distr.py,sha256=dx6l_ue5tdiKSu2wa-VhzDVwhKX_kDfS-glQin8Tdwg,2913
25
+ AeroViz/dataProcess/VOC/__init__.py,sha256=4AwmahvNQHVqC99Kp8FHyXjrmDkYo0Vc7M2sKDhUDR4,266
26
+ AeroViz/dataProcess/VOC/_potential_par.py,sha256=zTYds7blgo9y4i0K54oemXKugX_wx8Zp_7XzOMLoVvQ,2672
27
+ AeroViz/dataProcess/core/__init__.py,sha256=FvoMseJQFb9G44B2PbxJLOJ_TEHvhdYyKryAf76vf7A,2192
28
+ AeroViz/plot/__init__.py,sha256=9mptjlKOL40ZNoYntfON8ZK_4u84kErwQn7l1dAA18I,168
29
+ AeroViz/plot/distribution/__init__.py,sha256=nhbIegWczkuEfWsE7-2jfF0dnpmPDzJJzjq8Fuh6q5k,28
30
+ AeroViz/plot/distribution/distribution.py,sha256=GdGFOTGdHkxfxPP6RKqRbVJXVQdzeNOmBS2s5UkYHVA,19111
31
+ AeroViz/plot/improve/__init__.py,sha256=sfGzwndfWe9Bl-fS0rTUVql_Rf13LuNjs7puVz7DCxM,23
32
+ AeroViz/plot/improve/improve.py,sha256=gPzub6eyp4eD5Xgkn6DVsLhASA0FB-iPKaXqbJVq2Hs,8637
33
+ AeroViz/plot/meteorology/__init__.py,sha256=hhGfQE3IUzS3Eaju_nO7LomPPHJnd-zAAZZweXOXs2M,27
34
+ AeroViz/plot/meteorology/meteorology.py,sha256=1hWoD3HuWjYH1UOw97dsjUYnl6hdaLCg_Ku5FMjcmn4,11478
35
+ AeroViz/plot/optical/__init__.py,sha256=D3jW2F8OXo8Twe7If6LW99NvllZSRMSOg2ZCQzbwZKA,51
36
+ AeroViz/plot/optical/aethalometer.py,sha256=C-r6ajrywbCF6UhweF6-j9LMYpnNxVIMF_rb5Yxav60,2932
37
+ AeroViz/plot/optical/optical.py,sha256=LOi9xPSfWSF8gJEMhv__i-E17BiPYuFdek9cVioKHlc,12573
38
+ AeroViz/plot/templates/__init__.py,sha256=SBisRIk-6Lkww88JMOFHSFrx3K4BFXVc5zVTYvbTFJ4,248
39
+ AeroViz/plot/templates/contour.py,sha256=DtZRApe-Dn2_cqXWBtgciTEY1-4Vpvl8fB9L0ES_yn4,1585
40
+ AeroViz/plot/templates/corr_matrix.py,sha256=4nKd-GwMVzr5qt94sIu4AGUKMjZrfwPC93nf1qZoeBQ,3574
41
+ AeroViz/plot/templates/diurnal_pattern.py,sha256=Xg9cc0FlnoijnsB46pCp7geCPCbEzk_Cc2sEtEBxfE4,1218
42
+ AeroViz/plot/templates/event_evolution.py,sha256=uzmlxkMyCoI09jBLdZu4hf7dhUbHhVLHf9VjIkD3lxY,2176
43
+ AeroViz/plot/templates/koschmieder.py,sha256=H9STSGNXSQhYba9ZKox9mIDxDIqh3ng2JY1JbgShlW8,5328
44
+ AeroViz/plot/templates/metal_heatmap.py,sha256=-HAe_7x7Qj6VuZGkQB6pgZXeySu2hNSGVVXmcGtm5t8,1834
45
+ AeroViz/plot/templates/regression.py,sha256=ZZF0nm6t32Is0ny7t-1utP071TZdsfrApNNbLH0m2yI,7966
46
+ AeroViz/plot/templates/scatter.py,sha256=-gaT_Wish1lPdPoRPEG1P843wUnZy0IYt2xkapcpA1Q,4309
47
+ AeroViz/plot/templates/templates.py,sha256=j7lOB57zPIwCzi3j1zUk-tc7vT9lQ_YYNomkSz48H-M,13369
48
+ AeroViz/plot/timeseries/__init__.py,sha256=veqmkZy6j_BikD3JxBZp9cptOsaf6oP503xaDK8nn_o,26
49
+ AeroViz/plot/timeseries/timeseries.py,sha256=tCvVd2NEqou5WU98rbA6rwVznBcqs-I4LPsqmAOzTAY,10893
50
+ AeroViz/plot/utils/__init__.py,sha256=o-SqcwfoAOo6U33ASplMHtxSWs3QCnig8GjgW-y1qWQ,85
51
+ AeroViz/plot/utils/_color.py,sha256=x7QJa6xGWCePAWhVkZGO-YO0nzg5hbqAxI8omPfg1rE,2494
52
+ AeroViz/plot/utils/_decorator.py,sha256=mAT2jgH_uNL7wqymDEAFR9RQKPhcLZEKXVRve1-taiI,2231
53
+ AeroViz/plot/utils/_unit.py,sha256=ME6VENiERNDehom4wVKQl_OYeHFiDWRdZ5kfJ_OkXuk,1413
54
+ AeroViz/process/__init__.py,sha256=xI8lvKc3aKk4MIWwOyvTxEclEArcJ2DSpN0rBF63doA,1077
55
+ AeroViz/process/core/DataProc.py,sha256=gpFbKJg1BfRiYDi_GpuVdxUYkN804NLIv87mvqnFtbo,347
56
+ AeroViz/process/core/SizeDist.py,sha256=FR7LJcuc-umrhOFwSACMxAaHiQSDlI_emYq_cuQ51Jc,1797
57
+ AeroViz/process/core/__init__.py,sha256=WmVSFDx97urX0WPA8dtRVoQF04IDaU-IgxHK979-kM8,98
58
+ AeroViz/process/method/PyMieScatt_update.py,sha256=wi0_BUlyvJzfvFJkPx6j2RsCIgXn_o3v9ANJJ_VPPx0,18687
59
+ AeroViz/process/method/__init__.py,sha256=_yxoNAbbI82ORhrVsi-6x8vPnWQNHavjZUXy-ioZ2wg,123
60
+ AeroViz/process/method/mie_theory.py,sha256=aaBcnUC8afe9ur6-T4cXnevY7-I3ZjOzV3VUOgWCViI,7558
61
+ AeroViz/process/method/prop.py,sha256=MLybZCCi0l5p_ft3fGH9lPsC5tyEgmDU9enFTsBT_aM,1623
62
+ AeroViz/process/script/AbstractDistCalc.py,sha256=bPb2cw1VV4kyo3d0opW2Ipia4Pim5Yz6uZPNx1yKWJY,4588
63
+ AeroViz/process/script/Chemical.py,sha256=e3T1hyXpgHRLbCumagHOsBbkK538n-QYDJs0nvD0wfc,5240
64
+ AeroViz/process/script/IMPACT.py,sha256=SN8oaz7a4_Pp2WZE6vieeBLmq7WTrlK9A8do4mhzBj8,1367
65
+ AeroViz/process/script/IMPROVE.py,sha256=TVFpILoTjoC7FgEiOrElhPM-pfAjUGsQz6k5c1VJa70,4986
66
+ AeroViz/process/script/Others.py,sha256=XHCbVMKIGAmHQKVXVTJSY7qE6KLSB4OPJL9q2wb0RNY,1981
67
+ AeroViz/process/script/PSD.py,sha256=TL9dE_4jW4lt8snzVc4dvr3PaDlRbfUt-Tj74Psp0zU,3643
68
+ AeroViz/process/script/PSD_dry.py,sha256=rGYBR-MTvPMysVXuY6Zdsjt5dmYa5rk8LnOpE-ahbYg,2622
69
+ AeroViz/process/script/__init__.py,sha256=QExUHHK79oiwZXvk8u00P8rLwWhGOc1fpZY2Fx8Vkxg,188
70
+ AeroViz/process/script/retrieve_RI.py,sha256=798s_XmgpIsMX9pKHsH49xEK7AAzNMrm-OvOMVSEFuE,2419
71
+ AeroViz/rawDataReader/__init__.py,sha256=olxpsLtDtG7O7Qo94PiGL0up7pBcXung8dz8MgWjXb4,1628
72
+ AeroViz/rawDataReader/core/__init__.py,sha256=nRo-6EU-NVs9q0GHIqAzEmXC1-ybIFuII4ZIOtg5VwI,12667
73
+ AeroViz/rawDataReader/script/AE33.py,sha256=f7X8Prs3tmgDthwuPW0_Qd4Aooq6UWzpPiRK5sLnfnQ,1071
74
+ AeroViz/rawDataReader/script/AE43.py,sha256=EOHQpXcYQtRPIJSmKwQWGjzk_9835PyfTnsEd5amO0k,950
75
+ AeroViz/rawDataReader/script/APS_3321.py,sha256=TM_dEtnljDU_uT74_oGuFUUZdvF_hkPZY9h6Og9fIsU,1498
76
+ AeroViz/rawDataReader/script/Aurora.py,sha256=6hguvYv2ThtJD4s3FIMmciS1cB3oTAONiKXinUSWC38,1120
77
+ AeroViz/rawDataReader/script/BC1054.py,sha256=8Ey1JFT8mex0qRBoCgylYXx4ZFFpMtkkf2e8-GONQtk,1420
78
+ AeroViz/rawDataReader/script/EPA_vertical.py,sha256=TkgX1QYE1WL-RlHGAqZgBwaGX0_vVbo2_VsI1sZW1ss,574
79
+ AeroViz/rawDataReader/script/GRIMM.py,sha256=DGEubuRFh4OozOAX4K15xU753pJwGK4qC5xo4BSrIZ0,1056
80
+ AeroViz/rawDataReader/script/IGAC_TH.py,sha256=4GQAArMCyxT6YY9KcuxRkv_NxfMICFj5Zs8vdqqdJD0,2902
81
+ AeroViz/rawDataReader/script/IGAC_ZM.py,sha256=DnrbzsHRv8fXmK3ZKMBcMoWvcQzfV3VEHvV8SiiAT4o,2569
82
+ AeroViz/rawDataReader/script/MA350.py,sha256=fdrkLLcKDaBHCpZR0cZxEwRtHcCdni2q3Zox-BAhdcA,1404
83
+ AeroViz/rawDataReader/script/NEPH.py,sha256=zUT-Z1HO0zZI9dpGtgplwyNvqYOP5lWq9HMZrUCMT_8,1691
84
+ AeroViz/rawDataReader/script/OCEC_LCRES.py,sha256=4_dG4yi9Ovu29MG_Hcyye3K5HZeJ-JVOs8v0Ix7MwGM,1098
85
+ AeroViz/rawDataReader/script/OCEC_RES.py,sha256=Aqxlk0Thb-ndGJiTfftq2RJ0GsVuyJB1tGs_pnvslyk,701
86
+ AeroViz/rawDataReader/script/SMPS_TH.py,sha256=GGlDHm6DK_S_YZLcOWOrPLys_M1OVMkUe8Z4xrUwmKQ,1309
87
+ AeroViz/rawDataReader/script/SMPS_aim11.py,sha256=idqTvgqnAfYPRAwlMjmbgWG5fmM22mJFRAPejZ4544Q,1397
88
+ AeroViz/rawDataReader/script/SMPS_genr.py,sha256=PRLZ1rFPhJQX4ddPgGTKrUjJmcIFtjlCbfhgR5WjSDo,1383
89
+ AeroViz/rawDataReader/script/TEOM.py,sha256=-WM4YXQMdhB_XZexMT40w5I_zMHm8YHgm5PRh5G-7fs,1445
90
+ AeroViz/rawDataReader/script/Table.py,sha256=4JEL4KEL3w_32rjUrhJg9vn4whLCowSxegHPs6gB0dg,721
91
+ AeroViz/rawDataReader/script/VOC_TH.py,sha256=auw0UGYwxWFHF6k7k6iOgRJKgkMgee60iY-exTgx_wU,1052
92
+ AeroViz/rawDataReader/script/VOC_ZM.py,sha256=EgpeLBFMqGKPSPADrxJciojfhUPWNi7bfGaGGYJZMoE,1509
93
+ AeroViz/rawDataReader/script/__init__.py,sha256=ZX-X-5gV9oTiZlYA_ti3yrUA8JE9kH1n7rGSMuk_Ytc,246
94
+ AeroViz/tools/__init__.py,sha256=tPUmCI9Fi1LgE-QSVnzan5jRdYQBIENH9PRDXB_DhTw,109
95
+ AeroViz/tools/database.py,sha256=2UShRiW3EPGKSzPZvwRC3ckKEQ_yfmloa-YX92fE-dQ,3050
96
+ AeroViz/tools/dataclassifier.py,sha256=_98OR87qZbYnM3INAollX1ikYkZj9Nfe8q_xE-KSx0s,3766
97
+ AeroViz/tools/datareader.py,sha256=-Ng_3qU8jPvkSMn-sHZV2u9DSP2vAaDo2TY5D_mi6sg,1746
98
+ AeroViz-0.1.0.dist-info/LICENSE,sha256=E-679GpGGkp3irmtuJXiT7R4cNUA4cmsH6Q7QUgPf5U,1069
99
+ AeroViz-0.1.0.dist-info/METADATA,sha256=nz6eOdu3vZO9AmdJ3B6eDiK7odEcod0DP1KWDhATDdU,7040
100
+ AeroViz-0.1.0.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
101
+ AeroViz-0.1.0.dist-info/top_level.txt,sha256=BYsmTst_o4FZOKRP1XIvIMlN6mMTTXNfnSToL2_nVbQ,8
102
+ AeroViz-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (72.2.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ AeroViz