pyadps 0.2.0b0__py3-none-any.whl → 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. pyadps/Home_Page.py +11 -5
  2. pyadps/pages/01_Read_File.py +623 -211
  3. pyadps/pages/02_View_Raw_Data.py +97 -41
  4. pyadps/pages/03_Download_Raw_File.py +200 -67
  5. pyadps/pages/04_Sensor_Health.py +905 -0
  6. pyadps/pages/05_QC_Test.py +493 -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 +623 -0
  10. pyadps/pages/09_Add-Ons.py +168 -0
  11. pyadps/utils/__init__.py +5 -3
  12. pyadps/utils/autoprocess.py +371 -80
  13. pyadps/utils/logging_utils.py +269 -0
  14. pyadps/utils/metadata/config.ini +22 -4
  15. pyadps/utils/metadata/demo.000 +0 -0
  16. pyadps/utils/metadata/flmeta.json +420 -420
  17. pyadps/utils/metadata/vlmeta.json +611 -565
  18. pyadps/utils/multifile.py +292 -0
  19. pyadps/utils/plotgen.py +505 -3
  20. pyadps/utils/profile_test.py +720 -125
  21. pyadps/utils/pyreadrdi.py +164 -92
  22. pyadps/utils/readrdi.py +436 -186
  23. pyadps/utils/script.py +197 -147
  24. pyadps/utils/sensor_health.py +120 -0
  25. pyadps/utils/signal_quality.py +472 -68
  26. pyadps/utils/velocity_test.py +79 -31
  27. pyadps/utils/writenc.py +222 -39
  28. {pyadps-0.2.0b0.dist-info → pyadps-0.3.0.dist-info}/METADATA +63 -33
  29. pyadps-0.3.0.dist-info/RECORD +35 -0
  30. {pyadps-0.2.0b0.dist-info → pyadps-0.3.0.dist-info}/WHEEL +1 -1
  31. {pyadps-0.2.0b0.dist-info → pyadps-0.3.0.dist-info}/entry_points.txt +1 -0
  32. pyadps/pages/04_QC_Test.py +0 -334
  33. pyadps/pages/05_Profile_Test.py +0 -575
  34. pyadps/pages/06_Velocity_Test.py +0 -341
  35. pyadps/pages/07_Write_File.py +0 -452
  36. pyadps/utils/cutbin.py +0 -413
  37. pyadps/utils/regrid.py +0 -279
  38. pyadps-0.2.0b0.dist-info/RECORD +0 -31
  39. {pyadps-0.2.0b0.dist-info → pyadps-0.3.0.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)