AeroViz 0.1.0__tar.gz → 0.1.1__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.

Files changed (113) hide show
  1. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/__init__.py +2 -5
  2. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/timeseries/timeseries.py +10 -25
  3. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/core/__init__.py +4 -1
  4. aeroviz-0.1.1/AeroViz/rawDataReader/script/NEPH.py +80 -0
  5. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/tools/database.py +16 -13
  6. aeroviz-0.1.1/AeroViz/tools/dataprinter.py +58 -0
  7. aeroviz-0.1.1/AeroViz.egg-info/PKG-INFO +123 -0
  8. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz.egg-info/SOURCES.txt +1 -0
  9. aeroviz-0.1.1/PKG-INFO +123 -0
  10. aeroviz-0.1.1/README.md +101 -0
  11. {aeroviz-0.1.0 → aeroviz-0.1.1}/setup.py +1 -1
  12. aeroviz-0.1.0/AeroViz/rawDataReader/script/NEPH.py +0 -57
  13. aeroviz-0.1.0/AeroViz.egg-info/PKG-INFO +0 -117
  14. aeroviz-0.1.0/PKG-INFO +0 -117
  15. aeroviz-0.1.0/README.md +0 -95
  16. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/Chemistry/__init__.py +0 -0
  17. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/Chemistry/_calculate.py +0 -0
  18. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/Chemistry/_isoropia.py +0 -0
  19. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/Chemistry/_mass_volume.py +0 -0
  20. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/Chemistry/_ocec.py +0 -0
  21. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/Chemistry/_partition.py +0 -0
  22. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/Chemistry/_teom.py +0 -0
  23. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/Optical/_IMPROVE.py +0 -0
  24. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/Optical/__init__.py +0 -0
  25. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/Optical/_absorption.py +0 -0
  26. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/Optical/_extinction.py +0 -0
  27. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/Optical/_mie.py +0 -0
  28. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/Optical/_mie_sd.py +0 -0
  29. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/Optical/_scattering.py +0 -0
  30. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/SizeDistr/__init__.py +0 -0
  31. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/SizeDistr/__merge.py +0 -0
  32. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/SizeDistr/_merge.py +0 -0
  33. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/SizeDistr/_merge_v1.py +0 -0
  34. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/SizeDistr/_merge_v2.py +0 -0
  35. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/SizeDistr/_merge_v3.py +0 -0
  36. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/SizeDistr/_merge_v4.py +0 -0
  37. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/SizeDistr/_size_distr.py +0 -0
  38. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/VOC/__init__.py +0 -0
  39. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/VOC/_potential_par.py +0 -0
  40. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/__init__.py +0 -0
  41. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/dataProcess/core/__init__.py +0 -0
  42. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/__init__.py +0 -0
  43. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/distribution/__init__.py +0 -0
  44. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/distribution/distribution.py +0 -0
  45. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/improve/__init__.py +0 -0
  46. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/improve/improve.py +0 -0
  47. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/meteorology/__init__.py +0 -0
  48. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/meteorology/meteorology.py +0 -0
  49. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/optical/__init__.py +0 -0
  50. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/optical/aethalometer.py +0 -0
  51. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/optical/optical.py +0 -0
  52. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/templates/__init__.py +0 -0
  53. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/templates/contour.py +0 -0
  54. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/templates/corr_matrix.py +0 -0
  55. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/templates/diurnal_pattern.py +0 -0
  56. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/templates/event_evolution.py +0 -0
  57. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/templates/koschmieder.py +0 -0
  58. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/templates/metal_heatmap.py +0 -0
  59. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/templates/regression.py +0 -0
  60. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/templates/scatter.py +0 -0
  61. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/templates/templates.py +0 -0
  62. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/timeseries/__init__.py +0 -0
  63. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/utils/__init__.py +0 -0
  64. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/utils/_color.py +0 -0
  65. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/utils/_decorator.py +0 -0
  66. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/plot/utils/_unit.py +0 -0
  67. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/process/__init__.py +0 -0
  68. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/process/core/DataProc.py +0 -0
  69. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/process/core/SizeDist.py +0 -0
  70. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/process/core/__init__.py +0 -0
  71. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/process/method/PyMieScatt_update.py +0 -0
  72. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/process/method/__init__.py +0 -0
  73. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/process/method/mie_theory.py +0 -0
  74. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/process/method/prop.py +0 -0
  75. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/process/script/AbstractDistCalc.py +0 -0
  76. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/process/script/Chemical.py +0 -0
  77. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/process/script/IMPACT.py +0 -0
  78. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/process/script/IMPROVE.py +0 -0
  79. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/process/script/Others.py +0 -0
  80. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/process/script/PSD.py +0 -0
  81. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/process/script/PSD_dry.py +0 -0
  82. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/process/script/__init__.py +0 -0
  83. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/process/script/retrieve_RI.py +0 -0
  84. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/__init__.py +0 -0
  85. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/AE33.py +0 -0
  86. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/AE43.py +0 -0
  87. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/APS_3321.py +0 -0
  88. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/Aurora.py +0 -0
  89. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/BC1054.py +0 -0
  90. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/EPA_vertical.py +0 -0
  91. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/GRIMM.py +0 -0
  92. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/IGAC_TH.py +0 -0
  93. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/IGAC_ZM.py +0 -0
  94. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/MA350.py +0 -0
  95. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/OCEC_LCRES.py +0 -0
  96. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/OCEC_RES.py +0 -0
  97. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/SMPS_TH.py +0 -0
  98. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/SMPS_aim11.py +0 -0
  99. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/SMPS_genr.py +0 -0
  100. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/TEOM.py +0 -0
  101. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/Table.py +0 -0
  102. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/VOC_TH.py +0 -0
  103. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/VOC_ZM.py +0 -0
  104. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/rawDataReader/script/__init__.py +0 -0
  105. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/tools/__init__.py +0 -0
  106. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/tools/dataclassifier.py +0 -0
  107. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz/tools/datareader.py +0 -0
  108. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz.egg-info/dependency_links.txt +0 -0
  109. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz.egg-info/requires.txt +0 -0
  110. {aeroviz-0.1.0 → aeroviz-0.1.1}/AeroViz.egg-info/top_level.txt +0 -0
  111. {aeroviz-0.1.0 → aeroviz-0.1.1}/LICENSE +0 -0
  112. {aeroviz-0.1.0 → aeroviz-0.1.1}/setup.cfg +0 -0
  113. {aeroviz-0.1.0 → aeroviz-0.1.1}/tests/test_plot.py +0 -0
@@ -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']:
@@ -0,0 +1,80 @@
1
+ from pandas import to_datetime, read_csv, DataFrame
2
+
3
+ from AeroViz.rawDataReader.core import AbstractReader
4
+
5
+
6
+ class Reader(AbstractReader):
7
+ nam = 'NEPH'
8
+
9
+ def _raw_reader(self, _file):
10
+ with _file.open('r', encoding='utf-8', errors='ignore') as f:
11
+ _df = read_csv(f, header=None, names=range(11))
12
+
13
+ _df_grp = _df.groupby(0)
14
+
15
+ # T : time
16
+ _df_tm = _df_grp.get_group('T')[[1, 2, 3, 4, 5, 6]].astype(int)
17
+
18
+ for _k in [2, 3, 4, 5, 6]:
19
+ _df_tm[_k] = _df_tm[_k].astype(int).map('{:02d}'.format).copy()
20
+ _df_tm = _df_tm.astype(str)
21
+
22
+ _idx_tm = to_datetime((_df_tm[1] + _df_tm[2] + _df_tm[3] + _df_tm[4] + _df_tm[5] + _df_tm[6]),
23
+ format='%Y%m%d%H%M%S')
24
+
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
67
+ def _QC(self, _df):
68
+ # remove negative value
69
+ _df = _df.mask((_df <= 0).copy())
70
+
71
+ # call by _QC function
72
+ # QC data in 1 hr
73
+ def _QC_func(_df_1hr):
74
+ _df_ave = _df_1hr.mean()
75
+ _df_std = _df_1hr.std()
76
+ _df_lowb, _df_highb = _df_1hr < (_df_ave - _df_std * 1.5), _df_1hr > (_df_ave + _df_std * 1.5)
77
+
78
+ return _df_1hr.mask(_df_lowb | _df_highb).copy()
79
+
80
+ return _df.resample('1h', group_keys=False).apply(_QC_func)
@@ -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>
@@ -102,5 +102,6 @@ AeroViz/rawDataReader/script/__init__.py
102
102
  AeroViz/tools/__init__.py
103
103
  AeroViz/tools/database.py
104
104
  AeroViz/tools/dataclassifier.py
105
+ AeroViz/tools/dataprinter.py
105
106
  AeroViz/tools/datareader.py
106
107
  tests/test_plot.py
aeroviz-0.1.1/PKG-INFO ADDED
@@ -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>
@@ -0,0 +1,101 @@
1
+ ## <div align="center">AeroViz for Aerosol Science Visualization</div>
2
+
3
+ <p align="center">
4
+
5
+ <img alt="Static Badge" src="https://img.shields.io/badge/python-3.12-blue?logo=python">
6
+ <img alt="Static Badge" src="https://img.shields.io/badge/License-MIT-yellow">
7
+ <img alt="Static Badge" src="https://img.shields.io/badge/github-updating-red?logo=github">
8
+ <img src="https://img.shields.io/badge/testing-green?logo=Pytest&logoColor=blue">
9
+
10
+ </p>
11
+
12
+ <div align="center">
13
+
14
+ <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>
15
+ <img src="https://github.com/Alex870521/AeroViz/blob/main/assets/media/logo-transparent.png?raw=true" width="3%">
16
+ <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>
17
+ <img src="https://github.com/Alex870521/AeroViz/blob/main/assets/media/logo-transparent.png?raw=true" width="3%">
18
+ <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>
19
+
20
+
21
+ </div>
22
+
23
+ ## <div align="center">Installation</div>
24
+
25
+ ```bash
26
+ pip install AeroViz # ensure the python version is >= 3.12
27
+ ```
28
+
29
+ ## <div align="center">Usage</div>
30
+
31
+ ```python
32
+ import AeroViz
33
+ ```
34
+
35
+ ## <div align="center">RawDataReader Supported Instruments</div>
36
+
37
+ > [!NOTE]\
38
+ > We are continuously working to support more instruments. Please check back for updates or contribute to our project on
39
+ > GitHub.
40
+
41
+ The AeroViz project currently supports data from the following instruments:
42
+
43
+ - **SMPS (Scanning Mobility Particle Sizer)**
44
+ - **APS (Aerodynamic Particle Sizer)**
45
+ - **GRIMM (GRIMM Aerosol Technik)**
46
+ - **TEOM (Continuous Ambient Particulate Monitor)**
47
+ - **NEPH (Nephelometer)**
48
+ - **Aurora (Nephelometer)**
49
+ - **AE33 (Aethalometer Model 33)**
50
+ - **AE43 (Aethalometer Model 43)**
51
+ - **BC1054 (Black Carbon Monitor 1054)**
52
+ - **MA350 (MicroAeth MA350)**
53
+ - **OCEC (Organic Carbon Elemental Carbon Analyzer)**
54
+ - **IGAC (In-situ Gas and Aerosol Compositions monitor)**
55
+ - **VOC (Volatile Organic Compounds Monitor)**
56
+
57
+ ## <div align="center">DataProcess Supported Method</div>
58
+
59
+ The AeroViz project currently supports the following processing methods:
60
+
61
+ - **Chemistry**
62
+ - **Optical**
63
+ - **SizeDistr**
64
+ - **VOC**
65
+
66
+ ## <div align="center">Documentation</div>
67
+
68
+ For detailed documentation, please refer to the `docs` folder, which includes:
69
+
70
+ <div align="center">
71
+
72
+ | Documentation | Description |
73
+ |--------------------------------------------|----------------------------|
74
+ | [User Guide](docs/user_guide.md) | Basic usage instructions |
75
+ | [Developer Guide](docs/developer_guide.md) | Developer guidelines |
76
+ | [API Reference](docs/api_reference.md) | API documentation |
77
+ | [FAQ](docs/faq.md) | Frequently Asked Questions |
78
+ | [Changelog](docs/changelog.md) | List of changes |
79
+
80
+ </div>
81
+
82
+ ## <div align="center">Related Dependencies</div>
83
+
84
+ * #### [PyMieScatt](https://github.com/bsumlin/PyMieScatt.git)
85
+ * #### [py-smps](https://github.com/quant-aq/py-smps.git)
86
+ * #### [ContainerHandle](https://github.com/yrr-Su/ContainerHandle.git)
87
+
88
+ ## <div align="center">Contact</div>
89
+
90
+ For bug reports and feature requests please visit [GitHub Issues](https://github.com/Alex870521/DataPlot/issues).
91
+
92
+ <div align="center">
93
+
94
+ <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>
95
+ <img src="https://github.com/Alex870521/assets_repo/blob/main/assets/media/logo-transparent.png?raw=true" width="3%">
96
+ <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>
97
+ <img src="https://github.com/Alex870521/assets_repo/blob/main/assets/media/logo-transparent.png?raw=true" width="3%">
98
+ <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>
99
+
100
+
101
+ </div>
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="AeroViz",
5
- version="0.1.0",
5
+ version="0.1.1",
6
6
  author="alex",
7
7
  author_email="alex870521@gmail.com",
8
8
  description="Aerosol science",