AeroViz 0.1.0__py3-none-any.whl → 0.1.1__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.

.DS_Store ADDED
Binary file
AeroViz/__init__.py CHANGED
@@ -1,15 +1,12 @@
1
- # This file is used to import all the modules in the DataPlot package
1
+ # This file is used to import all the modules in the AeroViz package
2
2
  from AeroViz import plot
3
3
  from AeroViz.dataProcess import Optical, SizeDistr, Chemistry, VOC
4
- from AeroViz.plot import Color, Unit, set_figure
5
- from AeroViz.process import DataProcess
6
4
  from AeroViz.rawDataReader import RawDataReader
7
5
  from AeroViz.tools import DataBase, DataReader, DataClassifier
8
6
 
9
7
  __all__ = [
10
8
  'plot',
11
- 'Color', 'Unit', 'set_figure',
12
9
  'RawDataReader',
13
10
  'Optical', 'SizeDistr', 'Chemistry', 'VOC',
14
- 'DataProcess', 'DataBase', 'DataReader', 'DataClassifier',
11
+ 'DataBase', 'DataReader', 'DataClassifier'
15
12
  ]
@@ -57,8 +57,6 @@ def _scatter(ax, df, _y, _c, scatter_kws, cbar_kws, inset_kws):
57
57
  else:
58
58
  print("No mappable objects found.")
59
59
 
60
- # plt.colorbar(mappable=ax.get_children()[0], cax=cax, **cbar_kws)
61
-
62
60
 
63
61
  def _bar(ax, df, _y, _c, bar_kws, cbar_kws, inset_kws):
64
62
  scalar_map, colors = Color.color_maker(df[_c].values, cmap=bar_kws.pop('cmap'))
@@ -85,7 +83,7 @@ def timeseries(df: DataFrame,
85
83
  c: list[str] | str = None,
86
84
  # color: list[str] | str = None,
87
85
  rolling: str | int | None = None,
88
- times: tuple[datetime | Timestamp | str, datetime | Timestamp | str] = None,
86
+ times: list[datetime | Timestamp | str] = None,
89
87
  freq: str = '1MS',
90
88
  style: list[Literal['scatter', 'bar', 'line']] | str | None = None,
91
89
  ax: Axes | None = None,
@@ -149,7 +147,14 @@ def timeseries(df: DataFrame,
149
147
  >>> timeseries(df, y='WS', c='WD', scatter_kws=dict(cmap='hsv'), cbar_kws=dict(ticks=[0, 90, 180, 270, 360]), ylim=[0, None])
150
148
  """
151
149
  # Set the time
152
- st_tm, fn_tm = (df.index[0], df.index[-1]) if times is None else map(Timestamp, times)
150
+
151
+ if times is not None:
152
+ st_tm, fn_tm = map(Timestamp, times)
153
+ else:
154
+ try:
155
+ st_tm, fn_tm = df.index[0], df.index[-1]
156
+ except IndexError:
157
+ raise IndexError("The DataFrame is empty. Please provide a valid DataFrame.")
153
158
 
154
159
  # Apply rolling window if specified
155
160
  df = df.loc[st_tm:fn_tm] if rolling is None else (
@@ -277,7 +282,7 @@ def timeseries_template(df: DataFrame) -> tuple[Figure, Axes]:
277
282
  ax=ax2,
278
283
  ax_plot_kws=dict(color='r'),
279
284
  ax2_plot_kws=dict(color='b'),
280
- ylim=[10, 40],
285
+ ylim=[10, 30],
281
286
  ylim2=[20, 100],
282
287
  set_xaxis_visible=False,
283
288
  legend_ncol=2,
@@ -295,23 +300,3 @@ def timeseries_template(df: DataFrame) -> tuple[Figure, Axes]:
295
300
  plt.show()
296
301
 
297
302
  return fig, ax
298
-
299
-
300
- if __name__ == '__main__':
301
- from AeroViz import *
302
-
303
- df = DataBase('/Users/chanchihyu/NTU/2020能見度計畫/data/All_data.csv')
304
-
305
- plot.timeseries.timeseries(df,
306
- y=['Extinction', 'Scattering', 'Absorption'],
307
- y2=['PBLH'],
308
- c=['PM25', None, None, None],
309
- style=['scatter', 'line', 'line', 'line'],
310
- times=('2020-10-01', '2020-11-30'), ylim=[0, None], ylim2=[0, None], rolling=50,
311
- inset_kws=dict(bbox_to_anchor=(1.12, 0, 1.2, 1)),
312
- legend_ncol=4)
313
-
314
- # timeseries(df, y='WS', c='WD', style='scatter', times=('2020-10-01', '2020-11-30'), scatter_kws=dict(cmap='hsv'), cbar_kws=dict(ticks=[0, 90, 180, 270, 360]),
315
- # ylim=[0, None])
316
-
317
- # timeseries_template(df.loc['2020-09-01':'2020-12-31'])
@@ -2,6 +2,7 @@ import json as jsn
2
2
  import pickle as pkl
3
3
  from abc import ABC, abstractmethod
4
4
  from datetime import datetime as dtm, timedelta as dtmdt
5
+ from itertools import chain
5
6
  from pathlib import Path
6
7
 
7
8
  import numpy as np
@@ -229,7 +230,9 @@ class AbstractReader(ABC):
229
230
 
230
231
  # read raw data
231
232
  def _read_raw(self, ):
232
- _df_con, _f_list = None, list(self.path.glob(self.meta['pattern']))
233
+ pattern = self.meta['pattern']
234
+ patterns = {pattern, pattern.lower(), pattern.upper()}
235
+ _df_con, _f_list = None, list(chain.from_iterable(self.path.glob(p) for p in patterns))
233
236
 
234
237
  for file in _f_list:
235
238
  if file.name in [self.csv_out, self.csv_nam, self.csv_nam_raw, f'{self.nam}.log']:
@@ -1,4 +1,4 @@
1
- from pandas import to_datetime, read_csv
1
+ from pandas import to_datetime, read_csv, DataFrame
2
2
 
3
3
  from AeroViz.rawDataReader.core import AbstractReader
4
4
 
@@ -7,12 +7,12 @@ class Reader(AbstractReader):
7
7
  nam = 'NEPH'
8
8
 
9
9
  def _raw_reader(self, _file):
10
- with (_file).open('r', encoding='utf-8', errors='ignore') as f:
10
+ with _file.open('r', encoding='utf-8', errors='ignore') as f:
11
11
  _df = read_csv(f, header=None, names=range(11))
12
12
 
13
13
  _df_grp = _df.groupby(0)
14
14
 
15
- ## T : time
15
+ # T : time
16
16
  _df_tm = _df_grp.get_group('T')[[1, 2, 3, 4, 5, 6]].astype(int)
17
17
 
18
18
  for _k in [2, 3, 4, 5, 6]:
@@ -22,31 +22,54 @@ class Reader(AbstractReader):
22
22
  _idx_tm = to_datetime((_df_tm[1] + _df_tm[2] + _df_tm[3] + _df_tm[4] + _df_tm[5] + _df_tm[6]),
23
23
  format='%Y%m%d%H%M%S')
24
24
 
25
- ## D : data
26
- ## col : 3~8 B G R BB BG BR
27
- ## 1e6
28
- _df_dt = _df_grp.get_group('D')[[1, 2, 3, 4, 5, 6, 7, 8]].set_index(_idx_tm)
29
- _df_out = (_df_dt.groupby(1).get_group('NBXX')[[3, 4, 5, 6, 7, 8]] * 1e6).reindex(_idx_tm)
30
- _df_out.columns = ['B', 'G', 'R', 'BB', 'BG', 'BR']
31
- _df_out.index.name = 'Time'
32
-
33
- ## Y : state
34
- ## col : 5 RH
35
- _df_st = _df_grp.get_group('Y')
36
- _df_out['RH'] = _df_st[5].values
37
- _df_out['status'] = _df_st[9].values
38
-
39
- _df_out.mask(_df_out['status'] != 0) ## 0000 -> numeric to 0
40
-
41
- return _df_out[['B', 'G', 'R', 'BB', 'BG', 'BR', 'RH']]
42
-
43
- ## QC data
25
+ # D : data
26
+ # col : 3~8 B G R BB BG BR
27
+ # 1e6
28
+ try:
29
+ _df_dt = _df_grp.get_group('D')[[1, 2, 3, 4, 5, 6, 7, 8]].set_index(_idx_tm)
30
+ _df_out = (_df_dt.groupby(1).get_group('NBXX')[[3, 4, 5, 6, 7, 8]] * 1e6).reindex(_idx_tm)
31
+ _df_out.columns = ['B', 'G', 'R', 'BB', 'BG', 'BR']
32
+ _df_out.index.name = 'Time'
33
+
34
+ # Y : state
35
+ # col : 5 RH
36
+ _df_st = _df_grp.get_group('Y')
37
+ _df_out['RH'] = _df_st[5].values
38
+ _df_out['status'] = _df_st[9].values
39
+
40
+ _df_out.mask(_df_out['status'] != 0) # 0000 -> numeric to 0
41
+
42
+ return _df_out[['B', 'G', 'R', 'BB', 'BG', 'BR', 'RH']]
43
+
44
+ except ValueError:
45
+ group_sizes = _df_grp.size()
46
+ print(group_sizes)
47
+ # Define the valid groups
48
+ valid_groups = {'B', 'G', 'R', 'D', 'T', 'Y', 'Z'}
49
+
50
+ # Find the rows where the value in the first column is not in valid_groups
51
+ invalid_indices = _df[~_df[0].isin(valid_groups)].index
52
+
53
+ # Print the invalid indices and their corresponding values
54
+ invalid_values = _df.loc[invalid_indices, 0]
55
+ print("Invalid values and their indices:")
56
+ for idx, value in zip(invalid_indices, invalid_values):
57
+ print(f"Index: {idx}, Value: {value}")
58
+
59
+ # If there's a length mismatch, return an empty DataFrame with the same index and column names
60
+ columns = ['B', 'G', 'R', 'BB', 'BG', 'BR', 'RH']
61
+ _df_out = DataFrame(index=_idx_tm, columns=columns)
62
+ _df_out.index.name = 'Time'
63
+ print(f'\n\t\t\t Length mismatch in {_file} data. Returning an empty DataFrame.')
64
+ return _df_out
65
+
66
+ # QC data
44
67
  def _QC(self, _df):
45
- ## remove negative value
68
+ # remove negative value
46
69
  _df = _df.mask((_df <= 0).copy())
47
70
 
48
- ## call by _QC function
49
- ## QC data in 1 hr
71
+ # call by _QC function
72
+ # QC data in 1 hr
50
73
  def _QC_func(_df_1hr):
51
74
  _df_ave = _df_1hr.mean()
52
75
  _df_std = _df_1hr.std()
AeroViz/tools/database.py CHANGED
@@ -52,13 +52,14 @@ def load_dataset_by_url(dataset_name: Literal["Tunghai", "Taipei"] = "Tunghai")
52
52
  return DataFrame() # Return an empty DataFrame in case of failure
53
53
 
54
54
 
55
- def load_dataset_local(dataset_name: Literal["Tunghai", "Taipei"] = "Tunghai") -> DataFrame:
55
+ def load_dataset_local(dataset_name: Literal["Tunghai", "Taipei", "PNSD"] = "Tunghai") -> DataFrame:
56
56
  base_dir = Path(__file__).resolve().parent.parent
57
57
  config_dir = base_dir / 'config'
58
58
 
59
59
  dataset_paths = {
60
60
  "Tunghai": config_dir / 'DEFAULT_DATA.csv',
61
61
  "Taipei": config_dir / 'DEFAULT_DATA.csv',
62
+ "PNSD": config_dir / 'DEFAULT_PNSD_DATA.csv'
62
63
  }
63
64
 
64
65
  if dataset_name not in dataset_paths:
@@ -73,21 +74,23 @@ def load_dataset_local(dataset_name: Literal["Tunghai", "Taipei"] = "Tunghai") -
73
74
 
74
75
 
75
76
  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
-
77
+ def __new__(cls, file_path: Path | str = None, load_data: bool = False, load_PSD: bool = False):
79
78
  print(f'\t\t \033[96m --- Loading Data --- \033[0m')
79
+ if file_path is not None:
80
+ file_path = Path(file_path)
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
+
85
+ if load_data ^ load_PSD:
86
+ if load_data:
87
+ return load_dataset_local("Tunghai")
88
+
89
+ elif load_PSD:
90
+ return load_dataset_local("PNSD")
80
91
 
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
92
  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.")
93
+ raise ValueError("Exactly one of 'load_data' or 'load_PSD' must be True.")
91
94
 
92
95
 
93
96
  if __name__ == '__main__':
@@ -0,0 +1,58 @@
1
+ from datetime import datetime
2
+
3
+ from pandas import DataFrame, Timestamp
4
+ from tabulate import tabulate
5
+
6
+
7
+ def data_table(df: DataFrame,
8
+ items: list[str] | str = None,
9
+ times: list[datetime | Timestamp | str] = None,
10
+ ):
11
+ """
12
+ This function cuts the DataFrame based on the given time periods and calculates the mean and standard deviation
13
+ of the specified items for each period.
14
+
15
+ Parameters
16
+ ----------
17
+ df : pd.DataFrame
18
+ The DataFrame to be processed. It should have a DateTime index.
19
+ items : list[str] | str, optional
20
+ The columns of the DataFrame to be processed. It can be a list of column names or a single column name.
21
+ By default, it is ['NO', 'NO2', 'NOx'].
22
+ times : list[str] | str, optional
23
+ The time periods to cut the DataFrame. It can be a list of time strings or a single time string.
24
+ Each time string should be in the format of 'YYYY-MM-DD'. By default, it is ['2024-03-21', '2024-04-30'].
25
+
26
+ Returns
27
+ -------
28
+ None
29
+ This function doesn't return any value. It prints out a table showing the mean and standard deviation
30
+ of the specified items for each time period.
31
+ """
32
+ items = [items] if isinstance(items, str) else items
33
+ times = [times] if isinstance(times, str) else times
34
+ times = list(map(Timestamp, times))
35
+
36
+ times.sort()
37
+
38
+ results = []
39
+ periods = []
40
+ for i in range(len(times) + 1):
41
+ if i == 0:
42
+ df_period = df.loc[df.index <= times[i], items]
43
+ period_label = f'Before {times[i].date()}'
44
+ elif i == len(times):
45
+ df_period = df.loc[df.index > times[i - 1], items]
46
+ period_label = f'After {times[i - 1].date()}'
47
+ else:
48
+ df_period = df.loc[(df.index > times[i - 1]) & (df.index <= times[i]), items]
49
+ period_label = f'{times[i - 1].date()} to {times[i].date()}'
50
+
51
+ mean, std = df_period.mean().round(2).to_numpy(), df_period.std().round(2).to_numpy()
52
+
53
+ results.append([f'{m} ± {s}' for m, s in zip(mean, std)])
54
+ periods.append(period_label)
55
+
56
+ result = DataFrame(results, columns=items, index=periods)
57
+
58
+ print(tabulate(result, headers='keys', tablefmt='fancy_grid'))
@@ -0,0 +1,123 @@
1
+ Metadata-Version: 2.1
2
+ Name: AeroViz
3
+ Version: 0.1.1
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 Visualization</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/AeroViz/blob/main/assets/media/logo-social-github.png?raw=true" width="3%" alt="Alex870521 GitHub"></a>
37
+ <img src="https://github.com/Alex870521/AeroViz/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/AeroViz/blob/main/assets/media/logo-social-linkedin.png?raw=true" width="3%" alt="Alex870521 LinkedIn"></a>
39
+ <img src="https://github.com/Alex870521/AeroViz/blob/main/assets/media/logo-transparent.png?raw=true" width="3%">
40
+ <a href="https://medium.com/@alex870521"><img src="https://github.com/Alex870521/AeroViz/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">Installation</div>
46
+
47
+ ```bash
48
+ pip install AeroViz # ensure the python version is >= 3.12
49
+ ```
50
+
51
+ ## <div align="center">Usage</div>
52
+
53
+ ```python
54
+ import AeroViz
55
+ ```
56
+
57
+ ## <div align="center">RawDataReader Supported Instruments</div>
58
+
59
+ > [!NOTE]\
60
+ > We are continuously working to support more instruments. Please check back for updates or contribute to our project on
61
+ > GitHub.
62
+
63
+ The AeroViz project currently supports data from the following instruments:
64
+
65
+ - **SMPS (Scanning Mobility Particle Sizer)**
66
+ - **APS (Aerodynamic Particle Sizer)**
67
+ - **GRIMM (GRIMM Aerosol Technik)**
68
+ - **TEOM (Continuous Ambient Particulate Monitor)**
69
+ - **NEPH (Nephelometer)**
70
+ - **Aurora (Nephelometer)**
71
+ - **AE33 (Aethalometer Model 33)**
72
+ - **AE43 (Aethalometer Model 43)**
73
+ - **BC1054 (Black Carbon Monitor 1054)**
74
+ - **MA350 (MicroAeth MA350)**
75
+ - **OCEC (Organic Carbon Elemental Carbon Analyzer)**
76
+ - **IGAC (In-situ Gas and Aerosol Compositions monitor)**
77
+ - **VOC (Volatile Organic Compounds Monitor)**
78
+
79
+ ## <div align="center">DataProcess Supported Method</div>
80
+
81
+ The AeroViz project currently supports the following processing methods:
82
+
83
+ - **Chemistry**
84
+ - **Optical**
85
+ - **SizeDistr**
86
+ - **VOC**
87
+
88
+ ## <div align="center">Documentation</div>
89
+
90
+ For detailed documentation, please refer to the `docs` folder, which includes:
91
+
92
+ <div align="center">
93
+
94
+ | Documentation | Description |
95
+ |--------------------------------------------|----------------------------|
96
+ | [User Guide](docs/user_guide.md) | Basic usage instructions |
97
+ | [Developer Guide](docs/developer_guide.md) | Developer guidelines |
98
+ | [API Reference](docs/api_reference.md) | API documentation |
99
+ | [FAQ](docs/faq.md) | Frequently Asked Questions |
100
+ | [Changelog](docs/changelog.md) | List of changes |
101
+
102
+ </div>
103
+
104
+ ## <div align="center">Related Dependencies</div>
105
+
106
+ * #### [PyMieScatt](https://github.com/bsumlin/PyMieScatt.git)
107
+ * #### [py-smps](https://github.com/quant-aq/py-smps.git)
108
+ * #### [ContainerHandle](https://github.com/yrr-Su/ContainerHandle.git)
109
+
110
+ ## <div align="center">Contact</div>
111
+
112
+ For bug reports and feature requests please visit [GitHub Issues](https://github.com/Alex870521/DataPlot/issues).
113
+
114
+ <div align="center">
115
+
116
+ <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>
117
+ <img src="https://github.com/Alex870521/assets_repo/blob/main/assets/media/logo-transparent.png?raw=true" width="3%">
118
+ <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>
119
+ <img src="https://github.com/Alex870521/assets_repo/blob/main/assets/media/logo-transparent.png?raw=true" width="3%">
120
+ <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>
121
+
122
+
123
+ </div>
@@ -1,4 +1,5 @@
1
- AeroViz/__init__.py,sha256=5tu5vBrdHbLt152jaEmq2fgRBV6G7_KteIGysZH6lZ4,541
1
+ .DS_Store,sha256=CgT6bF_mGdTuoqwTB0X00GxsMDWz9a0Hlzt7Xo_QjiE,6148
2
+ AeroViz/__init__.py,sha256=lY7E-ZWNFPYOrpDSpWase_4-rUezRbeYOHDVJLU45VM,403
2
3
  AeroViz/dataProcess/__init__.py,sha256=6y-sYreiqlI6WIm7rkDCZJdM3JQhK3hsDySS1GpqKOY,179
3
4
  AeroViz/dataProcess/Chemistry/__init__.py,sha256=2YZYRcYjREEhDcheC4vH8GfbjA-0gc5hSbJJyymg5jE,1768
4
5
  AeroViz/dataProcess/Chemistry/_calculate.py,sha256=LiqJ8mpQLMwg-QuhT7A6zNLojnmOMX4lz6PD5wbqhOw,568
@@ -46,7 +47,7 @@ AeroViz/plot/templates/regression.py,sha256=ZZF0nm6t32Is0ny7t-1utP071TZdsfrApNNb
46
47
  AeroViz/plot/templates/scatter.py,sha256=-gaT_Wish1lPdPoRPEG1P843wUnZy0IYt2xkapcpA1Q,4309
47
48
  AeroViz/plot/templates/templates.py,sha256=j7lOB57zPIwCzi3j1zUk-tc7vT9lQ_YYNomkSz48H-M,13369
48
49
  AeroViz/plot/timeseries/__init__.py,sha256=veqmkZy6j_BikD3JxBZp9cptOsaf6oP503xaDK8nn_o,26
49
- AeroViz/plot/timeseries/timeseries.py,sha256=tCvVd2NEqou5WU98rbA6rwVznBcqs-I4LPsqmAOzTAY,10893
50
+ AeroViz/plot/timeseries/timeseries.py,sha256=PqGKuicNRQuaTVZ_Mi6BBHITVmznGyG7qTDGarWg9QI,10165
50
51
  AeroViz/plot/utils/__init__.py,sha256=o-SqcwfoAOo6U33ASplMHtxSWs3QCnig8GjgW-y1qWQ,85
51
52
  AeroViz/plot/utils/_color.py,sha256=x7QJa6xGWCePAWhVkZGO-YO0nzg5hbqAxI8omPfg1rE,2494
52
53
  AeroViz/plot/utils/_decorator.py,sha256=mAT2jgH_uNL7wqymDEAFR9RQKPhcLZEKXVRve1-taiI,2231
@@ -69,7 +70,7 @@ AeroViz/process/script/PSD_dry.py,sha256=rGYBR-MTvPMysVXuY6Zdsjt5dmYa5rk8LnOpE-a
69
70
  AeroViz/process/script/__init__.py,sha256=QExUHHK79oiwZXvk8u00P8rLwWhGOc1fpZY2Fx8Vkxg,188
70
71
  AeroViz/process/script/retrieve_RI.py,sha256=798s_XmgpIsMX9pKHsH49xEK7AAzNMrm-OvOMVSEFuE,2419
71
72
  AeroViz/rawDataReader/__init__.py,sha256=olxpsLtDtG7O7Qo94PiGL0up7pBcXung8dz8MgWjXb4,1628
72
- AeroViz/rawDataReader/core/__init__.py,sha256=nRo-6EU-NVs9q0GHIqAzEmXC1-ybIFuII4ZIOtg5VwI,12667
73
+ AeroViz/rawDataReader/core/__init__.py,sha256=iPeed3mlmzV3vcKUwJx2-gggFCzJeHnd7VPg0niCFoA,12805
73
74
  AeroViz/rawDataReader/script/AE33.py,sha256=f7X8Prs3tmgDthwuPW0_Qd4Aooq6UWzpPiRK5sLnfnQ,1071
74
75
  AeroViz/rawDataReader/script/AE43.py,sha256=EOHQpXcYQtRPIJSmKwQWGjzk_9835PyfTnsEd5amO0k,950
75
76
  AeroViz/rawDataReader/script/APS_3321.py,sha256=TM_dEtnljDU_uT74_oGuFUUZdvF_hkPZY9h6Og9fIsU,1498
@@ -80,7 +81,7 @@ AeroViz/rawDataReader/script/GRIMM.py,sha256=DGEubuRFh4OozOAX4K15xU753pJwGK4qC5x
80
81
  AeroViz/rawDataReader/script/IGAC_TH.py,sha256=4GQAArMCyxT6YY9KcuxRkv_NxfMICFj5Zs8vdqqdJD0,2902
81
82
  AeroViz/rawDataReader/script/IGAC_ZM.py,sha256=DnrbzsHRv8fXmK3ZKMBcMoWvcQzfV3VEHvV8SiiAT4o,2569
82
83
  AeroViz/rawDataReader/script/MA350.py,sha256=fdrkLLcKDaBHCpZR0cZxEwRtHcCdni2q3Zox-BAhdcA,1404
83
- AeroViz/rawDataReader/script/NEPH.py,sha256=zUT-Z1HO0zZI9dpGtgplwyNvqYOP5lWq9HMZrUCMT_8,1691
84
+ AeroViz/rawDataReader/script/NEPH.py,sha256=NWkyBv0sb6oS1HJp2W2KMEOIo4YyvDUsWJjEQQK_7Q4,2624
84
85
  AeroViz/rawDataReader/script/OCEC_LCRES.py,sha256=4_dG4yi9Ovu29MG_Hcyye3K5HZeJ-JVOs8v0Ix7MwGM,1098
85
86
  AeroViz/rawDataReader/script/OCEC_RES.py,sha256=Aqxlk0Thb-ndGJiTfftq2RJ0GsVuyJB1tGs_pnvslyk,701
86
87
  AeroViz/rawDataReader/script/SMPS_TH.py,sha256=GGlDHm6DK_S_YZLcOWOrPLys_M1OVMkUe8Z4xrUwmKQ,1309
@@ -92,11 +93,12 @@ AeroViz/rawDataReader/script/VOC_TH.py,sha256=auw0UGYwxWFHF6k7k6iOgRJKgkMgee60iY
92
93
  AeroViz/rawDataReader/script/VOC_ZM.py,sha256=EgpeLBFMqGKPSPADrxJciojfhUPWNi7bfGaGGYJZMoE,1509
93
94
  AeroViz/rawDataReader/script/__init__.py,sha256=ZX-X-5gV9oTiZlYA_ti3yrUA8JE9kH1n7rGSMuk_Ytc,246
94
95
  AeroViz/tools/__init__.py,sha256=tPUmCI9Fi1LgE-QSVnzan5jRdYQBIENH9PRDXB_DhTw,109
95
- AeroViz/tools/database.py,sha256=2UShRiW3EPGKSzPZvwRC3ckKEQ_yfmloa-YX92fE-dQ,3050
96
+ AeroViz/tools/database.py,sha256=4YoKa_pCy7PY2H1uM2HV-GDre29nIsFfdhqYczTZnt8,3064
96
97
  AeroViz/tools/dataclassifier.py,sha256=_98OR87qZbYnM3INAollX1ikYkZj9Nfe8q_xE-KSx0s,3766
98
+ AeroViz/tools/dataprinter.py,sha256=OXi4s8y6Jo_OF6K0dzUU2sGWYCXTbfDZCNY6oJq_RWQ,2027
97
99
  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,,
100
+ AeroViz-0.1.1.dist-info/LICENSE,sha256=E-679GpGGkp3irmtuJXiT7R4cNUA4cmsH6Q7QUgPf5U,1069
101
+ AeroViz-0.1.1.dist-info/METADATA,sha256=IbJvcXKu6lC4iZQzcBQ7ALoSgm1HZoDHPEhLtv2SdQQ,4987
102
+ AeroViz-0.1.1.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
103
+ AeroViz-0.1.1.dist-info/top_level.txt,sha256=BYsmTst_o4FZOKRP1XIvIMlN6mMTTXNfnSToL2_nVbQ,8
104
+ AeroViz-0.1.1.dist-info/RECORD,,
@@ -1,117 +0,0 @@
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>