pyadps 0.1.0b0__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.
Files changed (50) hide show
  1. pyadps/Home_Page.py +11 -5
  2. pyadps/pages/01_Read_File.py +191 -16
  3. pyadps/pages/02_View_Raw_Data.py +69 -33
  4. pyadps/pages/03_Download_Raw_File.py +161 -60
  5. pyadps/pages/04_Sensor_Health.py +905 -0
  6. pyadps/pages/05_QC_Test.py +476 -0
  7. pyadps/pages/06_Profile_Test.py +971 -0
  8. pyadps/pages/07_Velocity_Test.py +600 -0
  9. pyadps/pages/08_Write_File.py +587 -0
  10. pyadps/pages/09_Auto_process.py +64 -0
  11. pyadps/pages/__pycache__/__init__.cpython-312.pyc +0 -0
  12. pyadps/utils/__init__.py +3 -3
  13. pyadps/utils/__pycache__/__init__.cpython-312.pyc +0 -0
  14. pyadps/utils/__pycache__/autoprocess.cpython-312.pyc +0 -0
  15. pyadps/utils/__pycache__/cutbin.cpython-312.pyc +0 -0
  16. pyadps/utils/__pycache__/plotgen.cpython-312.pyc +0 -0
  17. pyadps/utils/__pycache__/profile_test.cpython-312.pyc +0 -0
  18. pyadps/utils/__pycache__/pyreadrdi.cpython-312.pyc +0 -0
  19. pyadps/utils/__pycache__/readrdi.cpython-312.pyc +0 -0
  20. pyadps/utils/__pycache__/regrid.cpython-312.pyc +0 -0
  21. pyadps/utils/__pycache__/script.cpython-312.pyc +0 -0
  22. pyadps/utils/__pycache__/sensor_health.cpython-312.pyc +0 -0
  23. pyadps/utils/__pycache__/signal_quality.cpython-312.pyc +0 -0
  24. pyadps/utils/__pycache__/velocity_test.cpython-312.pyc +0 -0
  25. pyadps/utils/__pycache__/writenc.cpython-312.pyc +0 -0
  26. pyadps/utils/autoprocess.py +548 -0
  27. pyadps/utils/metadata/config.ini +99 -0
  28. pyadps/utils/metadata/demo.000 +0 -0
  29. pyadps/utils/plotgen.py +505 -3
  30. pyadps/utils/profile_test.py +526 -145
  31. pyadps/utils/pyreadrdi.py +27 -17
  32. pyadps/utils/readrdi.py +167 -20
  33. pyadps/utils/script.py +197 -147
  34. pyadps/utils/sensor_health.py +120 -0
  35. pyadps/utils/signal_quality.py +344 -24
  36. pyadps/utils/velocity_test.py +103 -20
  37. pyadps/utils/writenc.py +223 -27
  38. {pyadps-0.1.0b0.dist-info → pyadps-0.1.1.dist-info}/METADATA +56 -24
  39. pyadps-0.1.1.dist-info/RECORD +47 -0
  40. {pyadps-0.1.0b0.dist-info → pyadps-0.1.1.dist-info}/WHEEL +1 -1
  41. pyadps-0.1.1.dist-info/entry_points.txt +5 -0
  42. pyadps/pages/04_QC_Test.py +0 -283
  43. pyadps/pages/05_Profile_Test.py +0 -389
  44. pyadps/pages/06_Velocity_Test.py +0 -293
  45. pyadps/pages/07_Write_File.py +0 -367
  46. pyadps/utils/cutbin.py +0 -413
  47. pyadps/utils/regrid.py +0 -122
  48. pyadps-0.1.0b0.dist-info/RECORD +0 -29
  49. pyadps-0.1.0b0.dist-info/entry_points.txt +0 -3
  50. {pyadps-0.1.0b0.dist-info → pyadps-0.1.1.dist-info}/LICENSE +0 -0
pyadps/utils/plotgen.py CHANGED
@@ -1,6 +1,509 @@
1
- import matplotlib.pyplot as plt
2
1
  import numpy as np
3
- from matplotlib.widgets import Button, Slider, TextBox
2
+ import matplotlib as mpl
3
+ import matplotlib.pyplot as plt
4
+ from matplotlib.widgets import Button, RadioButtons, Slider, TextBox
5
+ from matplotlib.widgets import RectangleSelector
6
+
7
+ mpl.use("TkAgg")
8
+
9
+
10
+ class CutBins:
11
+ def __init__(
12
+ self, data, mask, newmask=False, t1=0, t2=200, tinc=500, z1=0, z2=-1, zinc=0
13
+ ):
14
+ # DATA SETUP
15
+ self.orig_data = np.uint16(data)
16
+ self.orig_shape = np.shape(self.orig_data)
17
+ self.fill = 999
18
+ self.maskarray = mask
19
+ if not newmask:
20
+ self.orig_data[self.maskarray == 1] = self.fill
21
+
22
+ self.t1, self.t2, self.tinc = t1, t2, tinc
23
+ self.z1, self.z2, self.zinc = z1, z2, zinc
24
+ if z2 == -1:
25
+ self.z2 = self.orig_shape[0]
26
+
27
+ self.data = self.orig_data[self.z1 : self.z2, self.t1 : self.t2]
28
+ self.orig_subset = self.orig_data[self.z1 : self.z2, self.t1 : self.t2]
29
+ self.datacopy = np.copy(self.orig_data)
30
+ self.datamin = np.min(self.orig_data)
31
+ self.datamax = np.max(self.orig_data)
32
+ self.shape = np.shape(self.data)
33
+
34
+ # PLOT SETUP
35
+ self.t = np.arange(self.t1, self.t2)
36
+ self.z = np.arange(self.z1, self.z2)
37
+ self.tickinterval = int((self.t2 - self.t1) / 5)
38
+ self.xticks = np.arange(self.t1, self.t2, self.tickinterval)
39
+ self.X, self.Y = np.meshgrid(self.t, self.z)
40
+ self.fig, self.axs = plt.subplot_mosaic(
41
+ [["a", "b"], ["c", "b"]],
42
+ figsize=(12, 10),
43
+ width_ratios=[2, 1],
44
+ height_ratios=[1.75, 1],
45
+ )
46
+ self.fig.set_facecolor("darkgrey")
47
+ plt.subplots_adjust(top=0.82, right=0.95)
48
+
49
+ # ADDING WIDGET AXES
50
+ self.ax_clear_button = self.fig.add_axes(rect=(0.125, 0.90, 0.08, 0.025))
51
+ self.ax_delete_button = self.fig.add_axes(rect=(0.225, 0.90, 0.08, 0.025))
52
+ self.ax_refill_button = self.fig.add_axes(rect=(0.325, 0.90, 0.08, 0.025))
53
+ self.ax_next_button = self.fig.add_axes(rect=(0.630, 0.65, 0.02, 0.050))
54
+ self.ax_previous_button = self.fig.add_axes(rect=(0.075, 0.65, 0.02, 0.050))
55
+ self.ax_radio_button = self.fig.add_axes(rect=(0.725, 0.87, 0.10, 0.10))
56
+ self.ax_exit_button = self.fig.add_axes(rect=(0.825, 0.025, 0.08, 0.035))
57
+ self.ax_hslider = self.fig.add_axes(rect=(0.125, 0.85, 0.50, 0.03))
58
+ self.ax_vslider = self.fig.add_axes(rect=(0.04, 0.25, 0.03, 0.50))
59
+
60
+ self.ax_delete_button.set_visible(False)
61
+ self.ax_refill_button.set_visible(False)
62
+
63
+ # --- Slider settings ---
64
+ # Initial slider settings
65
+ self.hevent = 0
66
+ self.vevent = 0
67
+
68
+ # Slider options
69
+ self.hslider = Slider(
70
+ ax=self.ax_hslider,
71
+ label="Ensemble",
72
+ valmin=self.t1,
73
+ valmax=self.t2,
74
+ valinit=self.hevent,
75
+ valfmt="%i",
76
+ valstep=1,
77
+ )
78
+
79
+ self.vslider = Slider(
80
+ ax=self.ax_vslider,
81
+ label="Bins",
82
+ valmin=self.z1,
83
+ valmax=self.z2,
84
+ valinit=self.vevent,
85
+ valfmt="%i",
86
+ valstep=1,
87
+ orientation="vertical",
88
+ )
89
+
90
+ # Button Labels
91
+ self.clear_button = Button(self.ax_clear_button, "Clear")
92
+ self.delete_button = Button(self.ax_delete_button, "Delete")
93
+ self.refill_button = Button(self.ax_refill_button, "Refill")
94
+ self.previous_button = Button(self.ax_previous_button, "<")
95
+ self.next_button = Button(self.ax_next_button, ">")
96
+ self.exit_button = Button(self.ax_exit_button, "Save & Exit")
97
+ # self.cell_button = Button(self.ax_cell_button, "Cell")
98
+ # self.ensemble_button = Button(self.ax_ensemble_button, "Ensemble")
99
+ self.radio_button = RadioButtons(
100
+ self.ax_radio_button, ("Bin", "Ensemble", "Cell", "Region")
101
+ )
102
+
103
+ # --------------PLOTS---------------------
104
+
105
+ # Settings colorbar extreme to black
106
+ cmap = mpl.cm.turbo.with_extremes(over="k")
107
+ # FILL PLOT
108
+ self.mesh = self.axs["a"].pcolormesh(
109
+ self.X, self.Y, self.data, cmap=cmap, picker=True, vmin=0, vmax=255
110
+ )
111
+ plt.colorbar(self.mesh, orientation="horizontal")
112
+ self.axs["a"].set_xlim([self.t1, self.t2])
113
+ self.axs["a"].set_ylim([self.z1, self.z2])
114
+ # Draw vertical and horizontal lines
115
+ (self.vline,) = self.axs["a"].plot(
116
+ [self.t1, self.t1], [self.z1, self.z2], color="r", linewidth=2.5
117
+ )
118
+ (self.hline,) = self.axs["a"].plot(
119
+ [self.t1, self.t2], [self.z1, self.z1], color="r", linewidth=2.5
120
+ )
121
+
122
+ # PROFILE
123
+ (self.profile,) = self.axs["b"].plot(
124
+ self.data[self.z1 : self.z2, self.t1 + self.hevent], range(self.z1, self.z2)
125
+ )
126
+
127
+ self.axs["b"].set_xlim([self.datamin, self.datamax])
128
+ self.profile_text = self.axs["b"].text(
129
+ 0.95,
130
+ 0.95,
131
+ f"Ensemble No.: {self.t1 + self.hevent}",
132
+ verticalalignment="bottom",
133
+ horizontalalignment="right",
134
+ transform=self.axs["b"].transAxes,
135
+ color="k",
136
+ fontsize=12,
137
+ )
138
+
139
+ # TIME SERIES
140
+ (self.tseries,) = self.axs["c"].plot(
141
+ range(self.t1, self.t2), self.data[self.z1 + self.vevent, self.t1 : self.t2]
142
+ )
143
+ self.axs["c"].set_ylim([self.datamin, self.datamax])
144
+ self.tseries_text = self.axs["c"].text(
145
+ 0.90,
146
+ 0.90,
147
+ f"Bin No.: {self.z1 + self.vevent}",
148
+ verticalalignment="bottom",
149
+ horizontalalignment="right",
150
+ transform=self.axs["c"].transAxes,
151
+ color="k",
152
+ fontsize=12,
153
+ )
154
+ # --------------END PLOTS---------------------
155
+
156
+ # EVENTS
157
+ self.onclick = self.onclick_bin
158
+ self.hslider.on_changed(self.hupdate)
159
+ self.vslider.on_changed(self.vupdate)
160
+ self.clear_button.on_clicked(self.clear)
161
+ self.radio_button.on_clicked(self.radio)
162
+ self.cid = self.fig.canvas.mpl_connect("pick_event", self.onclick)
163
+
164
+ self.delete_button.on_clicked(self.boxdelete)
165
+ self.refill_button.on_clicked(self.boxrefill)
166
+ self.next_button.on_clicked(self.next)
167
+ self.previous_button.on_clicked(self.previous)
168
+ self.exit_button.on_clicked(self.exit)
169
+
170
+ def next(self, event):
171
+ if self.t2 <= self.orig_shape[1]:
172
+ # Next works till the last subset. The if statement checks for last subset.
173
+ self.t1 = self.t1 + self.tinc
174
+ self.t2 = self.t2 + self.tinc
175
+ if self.t2 > (self.orig_shape[1]):
176
+ # If in last subset create a dummy data set with missing value.
177
+ self.data = self.datacopy[
178
+ self.z1 : self.z2, self.t1 : self.orig_shape[1]
179
+ ]
180
+ self.orig_subset = self.orig_data[
181
+ self.z1 : self.z2, self.t1 : self.orig_shape[1]
182
+ ]
183
+ self.missing = (
184
+ np.ones((self.z2 - self.z1, self.t2 - self.orig_shape[1]))
185
+ * self.fill
186
+ )
187
+ # self.data consist of data along with flagged value
188
+ self.data = np.append(self.data, self.missing, axis=1)
189
+ # self.orig_subset contains only the subset of the original data
190
+ # Useful for plotting time series and profiles
191
+ self.orig_subset = np.append(self.orig_subset, self.missing, axis=1)
192
+ else:
193
+ self.data = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
194
+ self.orig_subset = self.orig_data[self.z1 : self.z2, self.t1 : self.t2]
195
+
196
+ self.mesh.set_array(self.data)
197
+ self.tick = np.arange(self.t1, self.t2, self.tickinterval)
198
+ self.axs["a"].set_xticks(self.xticks, self.tick)
199
+
200
+ self.profile.set_xdata(self.orig_subset[:, self.hevent])
201
+ self.profile_text.set_text(f"Ensemble No.: {self.t1 + self.hevent}")
202
+ self.vline.set_xdata([self.hevent, self.hevent])
203
+
204
+ self.tseries.set_ydata(self.orig_subset[self.vevent, :])
205
+ self.tseries_text.set_text(f"Bin No.: {self.z1 + self.vevent}")
206
+ self.hline.set_ydata([self.vevent, self.vevent])
207
+
208
+ self.fig.canvas.draw()
209
+
210
+ def previous(self, event):
211
+ if self.t1 >= self.tinc:
212
+ self.t1 = self.t1 - self.tinc
213
+ self.t2 = self.t2 - self.tinc
214
+ self.tick = np.arange(self.t1, self.t2, self.tickinterval)
215
+ self.data = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
216
+ self.axs["a"].set_xticks(self.xticks, self.tick)
217
+ self.mesh.set_array(self.data)
218
+
219
+ # Reset sliders
220
+ self.profile.set_xdata(self.orig_data[self.z1 : self.z2, self.hevent])
221
+ self.profile_text.set_text(f"Ensemble No.: {self.hevent}")
222
+ self.vline.set_xdata([self.hevent, self.hevent])
223
+
224
+ self.tseries.set_ydata(self.orig_data[self.vevent, self.t1 : self.t2])
225
+ self.tseries_text.set_text(f"Bin No.: {self.z1 + self.vevent}")
226
+ self.hline.set_ydata([self.vevent, self.vevent])
227
+
228
+ self.fig.canvas.draw()
229
+
230
+ def radio(self, event):
231
+ self.fig.canvas.mpl_disconnect(self.cid)
232
+ if event == "Bin":
233
+ self.cid = self.fig.canvas.mpl_connect("pick_event", self.onclick_bin)
234
+ elif event == "Ensemble":
235
+ self.cid = self.fig.canvas.mpl_connect("pick_event", self.onclick_ens)
236
+ elif event == "Cell":
237
+ self.cid = self.fig.canvas.mpl_connect("pick_event", self.onclick_cell)
238
+ else:
239
+ self.rid = RectangleSelector(
240
+ self.axs["a"],
241
+ self.onclick_box,
242
+ useblit=True,
243
+ minspanx=2,
244
+ minspany=2,
245
+ interactive=True,
246
+ )
247
+
248
+ def clear(self, event):
249
+ if event.button == 1:
250
+ self.datacopy = np.copy(self.orig_data)
251
+ if self.t2 >= (self.orig_shape[1]):
252
+ test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
253
+ test = np.append(test, self.missing, axis=1)
254
+ else:
255
+ test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
256
+
257
+ # self.mesh.set_array(self.datacopy[self.z1 : self.z2, self.t1 : self.t2])
258
+ self.mesh.set_array(test)
259
+ self.fig.canvas.draw()
260
+
261
+ def hupdate(self, event):
262
+ self.hevent = event
263
+ self.profile.set_xdata(self.orig_subset[:, self.hevent])
264
+ self.profile_text.set_text(f"Ensemble No.: {self.t1 + self.hevent}")
265
+ self.vline.set_xdata([self.hevent, self.hevent])
266
+
267
+ def vupdate(self, event):
268
+ self.vevent = event
269
+ self.tseries.set_ydata(self.orig_subset[self.vevent, :])
270
+ self.tseries_text.set_text(f"Bin No.: {self.z1 + self.vevent}")
271
+ self.hline.set_ydata([self.vevent, self.vevent])
272
+
273
+ def onclick_bin(self, event):
274
+ ind = event.ind
275
+ x = ind // (self.t[-1] + 1)
276
+ # y = ind % (self.t[-1] + 1)
277
+ xx = self.z1 + x
278
+ # yy = self.t1 + y
279
+ if np.all(self.datacopy[xx, :] == self.fill):
280
+ self.datacopy[xx, :] = np.copy(self.orig_data[xx, :])
281
+
282
+ else:
283
+ self.datacopy[xx, :] = self.fill
284
+
285
+ if self.t2 >= (self.orig_shape[1]):
286
+ test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
287
+ test = np.append(test, self.missing, axis=1)
288
+ else:
289
+ test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
290
+
291
+ # self.mesh.set_array(self.datacopy[self.z1 : self.z2, self.t1 : self.t2])
292
+ self.mesh.set_array(test)
293
+ self.hline.set_ydata([x, x])
294
+ self.vslider.set_val(x[0])
295
+ self.fig.canvas.draw()
296
+
297
+ def onclick_ens(self, event):
298
+ ind = event.ind
299
+ if np.size(ind) != 1:
300
+ return
301
+ # x = ind // (self.t[-1] + 1)
302
+ y = ind % (self.t[-1] + 1)
303
+ yy = self.t1 + y
304
+
305
+ if yy < self.orig_shape[1]:
306
+ if np.all(self.datacopy[:, yy] == self.fill):
307
+ self.datacopy[:, yy] = np.copy(self.orig_data[:, yy])
308
+ else:
309
+ self.datacopy[:, yy] = self.fill
310
+
311
+ if self.t2 >= (self.orig_shape[1]):
312
+ test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
313
+ test = np.append(test, self.missing, axis=1)
314
+ else:
315
+ test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
316
+ # self.mesh.set_array(self.datacopy[self.z1 : self.z2, self.t1 : self.t2])
317
+ self.mesh.set_array(test)
318
+ self.hline.set_xdata([y, y])
319
+ self.hslider.set_val(y[0])
320
+ self.fig.canvas.draw()
321
+
322
+ def onclick_cell(self, event):
323
+ ind = event.ind
324
+ if np.size(ind) != 1:
325
+ return
326
+ x = ind // (self.t[-1] + 1)
327
+ y = ind % (self.t[-1] + 1)
328
+ xx = self.z1 + x
329
+ yy = self.t1 + y
330
+
331
+ if yy < self.orig_shape[1]:
332
+ if self.datacopy[xx, yy] == self.fill:
333
+ self.datacopy[xx, yy] = np.copy(self.orig_data[x, y])
334
+ else:
335
+ self.datacopy[xx, yy] = self.fill
336
+
337
+ if self.t2 > (self.orig_shape[1]):
338
+ test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
339
+ test = np.append(test, self.missing, axis=1)
340
+ else:
341
+ test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
342
+
343
+ # self.mesh.set_array(self.datacopy[self.z1 : self.z2, self.t1 : self.t2])
344
+ self.mesh.set_array(test)
345
+ self.vline.set_xdata([y, y])
346
+ self.hline.set_ydata([x, x])
347
+ self.hslider.set_val(y[0])
348
+ self.vslider.set_val(x[0])
349
+ self.fig.canvas.draw()
350
+
351
+ def onclick_box(self, eclick, erelease):
352
+ self.ax_delete_button.set_visible(True)
353
+ self.ax_refill_button.set_visible(True)
354
+ plt.gcf().canvas.draw()
355
+ self.x11, self.y11 = int(eclick.xdata), int(eclick.ydata)
356
+ self.x22, self.y22 = int(erelease.xdata) + 1, int(erelease.ydata) + 1
357
+
358
+ print(
359
+ f"({self.x11:3.2f}, {self.y11:3.2f}) --> ({self.x22:3.2f}, {self.y22:3.2f})"
360
+ )
361
+ print(f" The buttons you used were: {eclick.button} {erelease.button}")
362
+
363
+ def boxdelete(self, event):
364
+ z1 = self.z1 + self.y11 + 1
365
+ z2 = self.z1 + self.y22
366
+ t1 = self.t1 + self.x11 + 1
367
+ t2 = self.t1 + self.x22
368
+ self.datacopy[z1:z2, t1:t2] = self.fill
369
+
370
+ if self.t2 > (self.orig_shape[1]):
371
+ test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
372
+ test = np.append(test, self.missing, axis=1)
373
+ else:
374
+ test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
375
+
376
+ # self.mesh.set_array(self.datacopy[self.z1 : self.z2, self.t1 : self.t2])
377
+ self.mesh.set_array(test)
378
+ self.fig.canvas.draw()
379
+
380
+ def boxrefill(self, event):
381
+ z1 = self.z1 + self.y11 + 1
382
+ z2 = self.z1 + self.y22
383
+ t1 = self.t1 + self.x11 + 1
384
+ t2 = self.t1 + self.x22
385
+ self.datacopy[z1:z2, t1:t2] = self.orig_data[z1:z2, t1:t2]
386
+
387
+ if self.t2 > (self.orig_shape[1]):
388
+ test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
389
+ test = np.append(test, self.missing, axis=1)
390
+ else:
391
+ test = self.datacopy[self.z1 : self.z2, self.t1 : self.t2]
392
+ # self.mesh.set_array(self.datacopy[self.z1 : self.z2, self.t1 : self.t2])
393
+ self.mesh.set_array(test)
394
+ self.fig.canvas.draw()
395
+
396
+ def exit(self, event):
397
+ plt.close()
398
+
399
+ def mask(self):
400
+ self.maskarray[self.datacopy == self.fill] = 1
401
+ return self.maskarray
402
+
403
+
404
+ class PlotEnds:
405
+ def __init__(self, pressure, delta=10):
406
+ self.dep = pressure / 980
407
+
408
+ self.n = np.size(self.dep)
409
+ self.delta = delta
410
+ self.nmin = 0
411
+ self.nmax = self.nmin + self.delta
412
+ self.mmax = 0
413
+ self.mmin = self.mmax - self.delta
414
+
415
+ self.x = np.arange(0, self.n)
416
+
417
+ self.start_ens = 0
418
+ self.end_ens = 0
419
+
420
+ self.fig, self.axs = plt.subplots(1, 2, figsize=(12, 8))
421
+ self.fig.set_facecolor("darkgrey")
422
+ plt.subplots_adjust(bottom=0.28, right=0.72)
423
+
424
+ self.ax_end = self.fig.add_axes(rect=(0.25, 0.08, 0.47, 0.03))
425
+ self.ax_start = self.fig.add_axes(rect=(0.25, 0.15, 0.47, 0.03))
426
+ self.ax_button = self.fig.add_axes(rect=(0.81, 0.05, 0.15, 0.075))
427
+ # self.ax_depmaxbutton = self.fig.add_axes(rect=(0.68, 0.13, 0.04, 0.02))
428
+ # self.ax_depminbutton = self.fig.add_axes(rect=(0.25, 0.13, 0.04, 0.02))
429
+ # self.ax_recmaxbutton = self.fig.add_axes(rect=(0.68, 0.06, 0.04, 0.02))
430
+ # self.ax_recminbutton = self.fig.add_axes(rect=(0.25, 0.06, 0.04, 0.02))
431
+
432
+ # Plot
433
+ self.axs[0].scatter(self.x, self.dep, color="k")
434
+ self.axs[1].scatter(self.x, self.dep, color="k")
435
+
436
+ # Figure Labels
437
+ for i in range(2):
438
+ self.axs[i].set_xlabel("Ensemble")
439
+ self.axs[0].set_xlim([self.nmin - 1, self.nmax])
440
+ self.axs[1].set_xlim([self.n - self.delta, self.n])
441
+ self.axs[0].set_ylabel("Depth (m)")
442
+ self.fig.suptitle("Trim Ends")
443
+
444
+ # Display statistics
445
+ self.axs[0].text(0.82, 0.60, "Statistics", transform=plt.gcf().transFigure)
446
+ self.max = np.round(np.max(self.dep), decimals=2)
447
+ self.min = np.round(np.min(self.dep), decimals=2)
448
+ self.median = np.round(np.median(self.dep), decimals=2)
449
+ self.mean = np.round(np.mean(self.dep), decimals=2)
450
+ self.t1 = self.axs[0].text(
451
+ 0.75,
452
+ 0.50,
453
+ f"Dep. Max = {self.max} \nDep. Min = {self.min} \nDep. Median = {self.median}",
454
+ transform=plt.gcf().transFigure,
455
+ )
456
+
457
+ self.sl_start = Slider(
458
+ ax=self.ax_start,
459
+ label="Dep. Ensemble",
460
+ valmin=self.nmin,
461
+ valmax=self.nmax,
462
+ valinit=0,
463
+ valfmt="%i",
464
+ valstep=1,
465
+ )
466
+
467
+ self.sl_end = Slider(
468
+ ax=self.ax_end,
469
+ label="Rec. Ensemble",
470
+ valmin=self.mmin,
471
+ valmax=self.mmax,
472
+ valinit=0,
473
+ valfmt="%i",
474
+ valstep=1,
475
+ )
476
+
477
+ self.sl_start.on_changed(self.update1)
478
+ self.sl_end.on_changed(self.update2)
479
+ self.button = Button(self.ax_button, "Save & Exit")
480
+ # self.depminbutton = Button(self.ax_depminbutton, "<<")
481
+ # self.depmaxbutton = Button(self.ax_depmaxbutton, ">>")
482
+ # self.recminbutton = Button(self.ax_recminbutton, "<<")
483
+ # self.recmaxbutton = Button(self.ax_recmaxbutton, ">>")
484
+
485
+ self.button.on_clicked(self.exitwin)
486
+
487
+ def update1(self, value):
488
+ self.axs[0].scatter(self.x, self.dep, color="k")
489
+ self.axs[0].scatter(self.x[0:value], self.dep[0:value], color="r")
490
+ self.start_ens = value
491
+
492
+ def update2(self, value):
493
+ self.axs[1].scatter(self.x, self.dep, color="k")
494
+ if value < 0:
495
+ self.axs[1].scatter(
496
+ self.x[self.n + value : self.n],
497
+ self.dep[self.n + value : self.n],
498
+ color="r",
499
+ )
500
+ self.end_ens = value
501
+
502
+ def show(self):
503
+ plt.show()
504
+
505
+ def exitwin(self, event):
506
+ plt.close()
4
507
 
5
508
 
6
509
  class PlotNoise:
@@ -187,7 +690,6 @@ def plotmask(mask1, mask2):
187
690
 
188
691
 
189
692
  def plotvar(var, name, mask=None, alpha=True):
190
-
191
693
  shape = np.shape(var)
192
694
  cpal = "turbo"
193
695
  fig, axs = plt.subplots(2, 2, figsize=(12, 8), sharex=True, sharey=True)