AeroViz 0.1.3__py3-none-any.whl → 0.1.4__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 (121) hide show
  1. AeroViz/__init__.py +7 -5
  2. AeroViz/{config → data}/DEFAULT_DATA.csv +1 -1
  3. AeroViz/dataProcess/Chemistry/__init__.py +40 -40
  4. AeroViz/dataProcess/Chemistry/_calculate.py +15 -15
  5. AeroViz/dataProcess/Chemistry/_isoropia.py +72 -68
  6. AeroViz/dataProcess/Chemistry/_mass_volume.py +158 -161
  7. AeroViz/dataProcess/Chemistry/_ocec.py +109 -109
  8. AeroViz/dataProcess/Chemistry/_partition.py +19 -18
  9. AeroViz/dataProcess/Chemistry/_teom.py +9 -11
  10. AeroViz/dataProcess/Chemistry/isrpia.cnf +21 -0
  11. AeroViz/dataProcess/Optical/Angstrom_exponent.py +20 -0
  12. AeroViz/dataProcess/Optical/_IMPROVE.py +40 -41
  13. AeroViz/dataProcess/Optical/__init__.py +29 -44
  14. AeroViz/dataProcess/Optical/_absorption.py +21 -47
  15. AeroViz/dataProcess/Optical/_extinction.py +31 -25
  16. AeroViz/dataProcess/Optical/_mie.py +5 -7
  17. AeroViz/dataProcess/Optical/_mie_sd.py +89 -90
  18. AeroViz/dataProcess/Optical/_scattering.py +19 -20
  19. AeroViz/dataProcess/SizeDistr/__init__.py +39 -39
  20. AeroViz/dataProcess/SizeDistr/__merge.py +159 -158
  21. AeroViz/dataProcess/SizeDistr/_merge.py +155 -154
  22. AeroViz/dataProcess/SizeDistr/_merge_v1.py +162 -161
  23. AeroViz/dataProcess/SizeDistr/_merge_v2.py +153 -152
  24. AeroViz/dataProcess/SizeDistr/_merge_v3.py +327 -327
  25. AeroViz/dataProcess/SizeDistr/_merge_v4.py +273 -275
  26. AeroViz/dataProcess/SizeDistr/_size_distr.py +51 -51
  27. AeroViz/dataProcess/VOC/__init__.py +9 -9
  28. AeroViz/dataProcess/VOC/_potential_par.py +53 -55
  29. AeroViz/dataProcess/__init__.py +28 -6
  30. AeroViz/dataProcess/core/__init__.py +59 -65
  31. AeroViz/plot/__init__.py +7 -2
  32. AeroViz/plot/bar.py +126 -0
  33. AeroViz/plot/box.py +69 -0
  34. AeroViz/plot/distribution/distribution.py +421 -427
  35. AeroViz/plot/meteorology/meteorology.py +240 -292
  36. AeroViz/plot/optical/__init__.py +0 -1
  37. AeroViz/plot/optical/optical.py +230 -230
  38. AeroViz/plot/pie.py +198 -0
  39. AeroViz/plot/regression.py +196 -0
  40. AeroViz/plot/scatter.py +165 -0
  41. AeroViz/plot/templates/__init__.py +2 -4
  42. AeroViz/plot/templates/ammonium_rich.py +34 -0
  43. AeroViz/plot/templates/contour.py +25 -25
  44. AeroViz/plot/templates/corr_matrix.py +86 -93
  45. AeroViz/plot/templates/diurnal_pattern.py +28 -26
  46. AeroViz/plot/templates/koschmieder.py +59 -123
  47. AeroViz/plot/templates/metal_heatmap.py +135 -37
  48. AeroViz/plot/timeseries/__init__.py +1 -0
  49. AeroViz/plot/timeseries/template.py +47 -0
  50. AeroViz/plot/timeseries/timeseries.py +324 -264
  51. AeroViz/plot/utils/__init__.py +2 -1
  52. AeroViz/plot/utils/_color.py +57 -57
  53. AeroViz/plot/utils/_unit.py +48 -48
  54. AeroViz/plot/utils/plt_utils.py +92 -0
  55. AeroViz/plot/utils/sklearn_utils.py +49 -0
  56. AeroViz/plot/utils/units.json +5 -0
  57. AeroViz/plot/violin.py +80 -0
  58. AeroViz/process/__init__.py +17 -17
  59. AeroViz/process/core/DataProc.py +9 -9
  60. AeroViz/process/core/SizeDist.py +81 -81
  61. AeroViz/process/method/PyMieScatt_update.py +488 -488
  62. AeroViz/process/method/mie_theory.py +231 -229
  63. AeroViz/process/method/prop.py +40 -40
  64. AeroViz/process/script/AbstractDistCalc.py +103 -103
  65. AeroViz/process/script/Chemical.py +168 -167
  66. AeroViz/process/script/IMPACT.py +40 -40
  67. AeroViz/process/script/IMPROVE.py +152 -152
  68. AeroViz/process/script/Others.py +45 -45
  69. AeroViz/process/script/PSD.py +26 -26
  70. AeroViz/process/script/PSD_dry.py +69 -70
  71. AeroViz/process/script/retrieve_RI.py +50 -51
  72. AeroViz/rawDataReader/__init__.py +53 -58
  73. AeroViz/rawDataReader/config/supported_instruments.py +155 -0
  74. AeroViz/rawDataReader/core/__init__.py +233 -356
  75. AeroViz/rawDataReader/script/AE33.py +17 -18
  76. AeroViz/rawDataReader/script/AE43.py +18 -21
  77. AeroViz/rawDataReader/script/APS_3321.py +30 -30
  78. AeroViz/rawDataReader/script/Aurora.py +23 -24
  79. AeroViz/rawDataReader/script/BC1054.py +36 -40
  80. AeroViz/rawDataReader/script/EPA_vertical.py +37 -9
  81. AeroViz/rawDataReader/script/GRIMM.py +16 -23
  82. AeroViz/rawDataReader/script/IGAC.py +90 -0
  83. AeroViz/rawDataReader/script/MA350.py +32 -39
  84. AeroViz/rawDataReader/script/Minion.py +103 -0
  85. AeroViz/rawDataReader/script/NEPH.py +69 -74
  86. AeroViz/rawDataReader/script/SMPS_TH.py +25 -25
  87. AeroViz/rawDataReader/script/SMPS_aim11.py +32 -32
  88. AeroViz/rawDataReader/script/SMPS_genr.py +31 -31
  89. AeroViz/rawDataReader/script/Sunset_OCEC.py +60 -0
  90. AeroViz/rawDataReader/script/TEOM.py +30 -28
  91. AeroViz/rawDataReader/script/Table.py +13 -14
  92. AeroViz/rawDataReader/script/VOC.py +26 -0
  93. AeroViz/rawDataReader/script/__init__.py +18 -20
  94. AeroViz/tools/database.py +64 -66
  95. AeroViz/tools/dataclassifier.py +106 -106
  96. AeroViz/tools/dataprinter.py +51 -51
  97. AeroViz/tools/datareader.py +38 -38
  98. {AeroViz-0.1.3.dist-info → AeroViz-0.1.4.dist-info}/METADATA +5 -4
  99. AeroViz-0.1.4.dist-info/RECORD +112 -0
  100. AeroViz/plot/improve/__init__.py +0 -1
  101. AeroViz/plot/improve/improve.py +0 -240
  102. AeroViz/plot/optical/aethalometer.py +0 -77
  103. AeroViz/plot/templates/event_evolution.py +0 -65
  104. AeroViz/plot/templates/regression.py +0 -256
  105. AeroViz/plot/templates/scatter.py +0 -130
  106. AeroViz/plot/templates/templates.py +0 -398
  107. AeroViz/plot/utils/_decorator.py +0 -74
  108. AeroViz/rawDataReader/script/IGAC_TH.py +0 -104
  109. AeroViz/rawDataReader/script/IGAC_ZM.py +0 -90
  110. AeroViz/rawDataReader/script/OCEC_LCRES.py +0 -34
  111. AeroViz/rawDataReader/script/OCEC_RES.py +0 -28
  112. AeroViz/rawDataReader/script/VOC_TH.py +0 -30
  113. AeroViz/rawDataReader/script/VOC_ZM.py +0 -37
  114. AeroViz/rawDataReader/utils/__init__.py +0 -0
  115. AeroViz/rawDataReader/utils/config.py +0 -169
  116. AeroViz-0.1.3.dist-info/RECORD +0 -111
  117. /AeroViz/{config → data}/DEFAULT_PNSD_DATA.csv +0 -0
  118. /AeroViz/{config → rawDataReader/config}/__init__.py +0 -0
  119. {AeroViz-0.1.3.dist-info → AeroViz-0.1.4.dist-info}/LICENSE +0 -0
  120. {AeroViz-0.1.3.dist-info → AeroViz-0.1.4.dist-info}/WHEEL +0 -0
  121. {AeroViz-0.1.3.dist-info → AeroViz-0.1.4.dist-info}/top_level.txt +0 -0
@@ -2,56 +2,154 @@ import matplotlib.pyplot as plt
2
2
  import numpy as np
3
3
  import seaborn as sns
4
4
  from matplotlib.pyplot import Figure, Axes
5
- from pandas import DataFrame, date_range
5
+ from pandas import DataFrame, date_range, concat
6
6
  from sklearn.preprocessing import StandardScaler
7
7
 
8
8
  from AeroViz.plot.utils import *
9
9
 
10
+ __all__ = ['metal_heatmaps', 'process_data_with_two_df']
10
11
 
11
- def process_data(df):
12
- # detected_limit = 0.0001
13
- df = df.where(df >= 0.0001, np.nan)
14
- # Normalize the data
15
- df = DataFrame(StandardScaler().fit_transform(df), index=df.index, columns=df.columns)
16
- # Remove outliers
17
- df = df[(np.abs(df) < 6)]
18
- # Interpolate the missing values
19
- df = df.interpolate(method='linear')
20
- # Smooth the data
21
- df = df.rolling(window=3, min_periods=1).mean()
22
12
 
23
- return df
13
+ def process_data(df, detected_limit=True, outlier_threshold=5, smoothing_window=6, fill_method='MDL'):
14
+ # Fill missing values based on the specified method
15
+ df = fill_missing_values(df.copy(), method=fill_method)
16
+
17
+ # Normalize the data
18
+ df = normalize_data(df)
19
+
20
+ # Remove outliers
21
+ df = remove_outliers(df, threshold=outlier_threshold)
22
+
23
+ # Interpolate missing values
24
+ df = df.interpolate(method='linear')
25
+
26
+ # Smooth the data
27
+ df = smooth_data(df, window=smoothing_window)
28
+
29
+ return df
30
+
31
+
32
+ def process_data_with_two_df(df, df2, outlier_threshold=5, smoothing_window=6, fill_method='MDL'):
33
+ # Shift the first DataFrame by 30 minutes
34
+ df = df.shift(freq='30min')
35
+
36
+ # Fill missing values for both DataFrames
37
+ df = fill_missing_values(df.copy(), method=fill_method)
38
+ df2 = fill_missing_values(df2.copy(), method=fill_method)
39
+
40
+ # Normalize both DataFrames together
41
+ df, df2 = normalize_and_split(df, df2)
42
+
43
+ # Shift the first DataFrame back by 30 minutes
44
+ df = df.shift(freq='-30min')
45
+
46
+ # Remove outliers for both DataFrames
47
+ df = remove_outliers(df, threshold=outlier_threshold)
48
+ df2 = remove_outliers(df2, threshold=outlier_threshold)
49
+
50
+ # Interpolate missing values
51
+ df = df.interpolate(method='linear')
52
+ df2 = df2.interpolate(method='linear')
53
+
54
+ # Smooth the data
55
+ df = smooth_data(df, window=smoothing_window)
56
+ df2 = smooth_data(df2, window=smoothing_window)
57
+
58
+ return df, df2
59
+
60
+
61
+ def fill_missing_values(df, method='MDL'):
62
+ if method == 'interpolate':
63
+ return df.interpolate(method='linear')
64
+ else:
65
+ return fill_with_mdl(df)
66
+
67
+
68
+ def fill_with_mdl(df):
69
+ # Minimum detection limit (MDL) dictionary
70
+ MDL = {
71
+ 'Al': 100, 'Si': 18, 'P': 5.2, 'S': 3.2,
72
+ 'Cl': 1.7, 'K': 1.2, 'Ca': 0.3, 'Ti': 1.6,
73
+ 'V': 0.12, 'Cr': 0.12, 'Mn': 0.14, 'Fe': 0.17,
74
+ 'Co': 0.14, 'Ni': 0.096, 'Cu': 0.079, 'Zn': 0.067,
75
+ 'Ga': 0.059, 'Ge': 0.056, 'As': 0.063, 'Se': 0.081,
76
+ 'Br': 0.1, 'Rb': 0.19, 'Sr': 0.22, 'Y': 0.28,
77
+ 'Zr': 0.33, 'Nb': 0.41, 'Mo': 0.48, 'Pd': 2.2,
78
+ 'Ag': 1.9, 'Cd': 2.5, 'In': 3.1, 'Sn': 4.1,
79
+ 'Sb': 5.2, 'Te': 0.6, 'I': 0.49, 'Cs': 0.37,
80
+ 'Ba': 0.39, 'La': 0.36, 'Ce': 0.3, 'Pt': 0.12,
81
+ 'Au': 0.1, 'Hg': 0.12, 'Tl': 0.12, 'Pb': 0.13,
82
+ 'Bi': 0.13
83
+ }
84
+
85
+ # Replace values below MDL with 5/6 * MDL
86
+ for element, threshold in MDL.items():
87
+ if element in df.columns:
88
+ df.loc[:, element] = df[element].where(df[element] >= threshold, 5 / 6 * threshold)
89
+
90
+ return df
91
+
92
+
93
+ def normalize_data(df):
94
+ # Standardize the data (z-score normalization)
95
+ return DataFrame(StandardScaler().fit_transform(df), index=df.index, columns=df.columns)
96
+
97
+
98
+ def remove_outliers(df, threshold=5):
99
+ # Remove rows where any column value exceeds the threshold
100
+ return df[(np.abs(df) < threshold)]
101
+
102
+
103
+ def smooth_data(df, window=6):
104
+ # Apply rolling mean to smooth the data
105
+ return df.rolling(window=window, min_periods=1).mean()
106
+
107
+
108
+ def normalize_and_split(df, df2):
109
+ # Concatenate DataFrames for combined normalization
110
+ combined_df = concat([df, df2])
111
+ normalized_combined_df = normalize_data(combined_df)
112
+
113
+ # Split the normalized DataFrame back into df and df2
114
+ df = normalized_combined_df.loc[df.index]
115
+ df2 = normalized_combined_df.loc[df2.index]
116
+
117
+ return df, df2
24
118
 
25
119
 
26
120
  @set_figure(figsize=(12, 3), fs=6)
27
- def metal_heatmaps(df, major_freq='24h', minor_freq='12h', ax: Axes | None = None, title=None, **kwargs
28
- ) -> tuple[Figure, Axes]:
29
- items = ['Al', 'Zr', 'Si', 'Ca', 'Ti', 'Mn', 'Fe', 'V', 'Cl', 'K',
30
- 'Sr', 'Ba', 'Bi', 'Pd', 'Sn', 'Cr', 'W', 'Cu', 'Zn',
31
- 'As', 'Co', 'Se', 'Br', 'Cd', 'Sb', 'In', 'Pb', 'Ni']
121
+ def metal_heatmaps(df,
122
+ process=True,
123
+ major_freq='24h',
124
+ minor_freq='12h',
125
+ cmap='jet',
126
+ ax: Axes | None = None,
127
+ **kwargs
128
+ ) -> tuple[Figure, Axes]:
129
+ if process:
130
+ df = process_data(df)
32
131
 
33
- df = df[items]
132
+ fig, ax = plt.subplots(**kwargs.get('fig_kws', {})) if ax is None else (ax.get_figure(), ax)
34
133
 
35
- fig, ax = plt.subplots(**kwargs.get('fig_kws', {})) if ax is None else (ax.get_figure(), ax)
134
+ sns.heatmap(df.T, vmin=None, vmax=3, cmap=cmap, xticklabels=False, yticklabels=True,
135
+ cbar_kws={'label': 'Z score', "pad": 0.02})
136
+ ax.grid(color='gray', linestyle='-', linewidth=0.3)
36
137
 
37
- sns.heatmap(df.T, vmax=3, cmap="jet", xticklabels=False, yticklabels=True,
38
- cbar_kws={'label': 'Z score'})
39
- ax.grid(color='gray', linestyle='-', linewidth=0.3)
40
- # Set x-tick positions and labels
41
- major_tick = date_range(start=df.index[0], end=df.index[-1], freq=major_freq)
42
- minor_tick = date_range(start=df.index[0], end=df.index[-1], freq=minor_freq)
138
+ # Set x-tick positions and labels
139
+ major_tick = date_range(start=df.index[0], end=df.index[-1], freq=major_freq)
140
+ minor_tick = date_range(start=df.index[0], end=df.index[-1], freq=minor_freq)
43
141
 
44
- # Set the major and minor ticks
45
- ax.set_xticks(ticks=[df.index.get_loc(t) for t in major_tick])
46
- ax.set_xticks(ticks=[df.index.get_loc(t) for t in minor_tick], minor=True)
47
- ax.set_xticklabels(major_tick.strftime('%F'))
48
- ax.tick_params(axis='y', rotation=0)
142
+ # Set the major and minor ticks
143
+ ax.set_xticks(ticks=[df.index.get_loc(t) for t in major_tick])
144
+ ax.set_xticks(ticks=[df.index.get_loc(t) for t in minor_tick], minor=True)
145
+ ax.set_xticklabels(major_tick.strftime('%F'))
146
+ ax.tick_params(axis='y', rotation=0)
49
147
 
50
- ax.set_title(f"{title}", fontsize=10)
51
- ax.set(xlabel='',
52
- ylabel='',
53
- )
148
+ ax.set(xlabel='',
149
+ ylabel='',
150
+ title=kwargs.get('title', None)
151
+ )
54
152
 
55
- plt.show()
153
+ plt.show()
56
154
 
57
- return fig, ax
155
+ return fig, ax
@@ -1 +1,2 @@
1
+ from .template import *
1
2
  from .timeseries import *
@@ -0,0 +1,47 @@
1
+ import matplotlib.pyplot as plt
2
+ from matplotlib.pyplot import Figure, Axes
3
+ from pandas import DataFrame
4
+
5
+ from AeroViz.plot.timeseries import timeseries
6
+
7
+
8
+ def timeseries_template(df: DataFrame) -> tuple[Figure, Axes]:
9
+ fig, ax = plt.subplots(5, 1, figsize=(len(df.index) * 0.01, 4))
10
+ (ax1, ax2, ax3, ax4, ax5) = ax
11
+
12
+ timeseries(df,
13
+ y=['Extinction', 'Scattering', 'Absorption'],
14
+ rolling=30,
15
+ ax=ax1,
16
+ ylabel='Coefficient',
17
+ ylim=[0., None],
18
+ set_xaxis_visible=False,
19
+ legend_ncol=3,
20
+ )
21
+
22
+ # Temp, RH
23
+ timeseries(df,
24
+ y='AT',
25
+ y2='RH',
26
+ rolling=30,
27
+ ax=ax2,
28
+ ax_plot_kws=dict(color='r'),
29
+ ax2_plot_kws=dict(color='b'),
30
+ ylim=[10, 30],
31
+ ylim2=[20, 100],
32
+ set_xaxis_visible=False,
33
+ legend_ncol=2,
34
+ )
35
+
36
+ timeseries(df, y='WS', color='WD', style='scatter', ax=ax3, scatter_kws=dict(cmap='hsv'),
37
+ cbar_kws=dict(ticks=[0, 90, 180, 270, 360]),
38
+ ylim=[0, None], set_xaxis_visible=False)
39
+
40
+ timeseries(df, y='VC', color='PBLH', style='bar', ax=ax4, bar_kws=dict(cmap='Blues'), set_xaxis_visible=False,
41
+ ylim=[0, 5000])
42
+
43
+ timeseries(df, y='PM25', color='PM1/PM25', style='scatter', ax=ax5, ylim=[0, None])
44
+
45
+ plt.show()
46
+
47
+ return fig, ax