wawi 0.0.16__py3-none-any.whl → 0.0.17__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.
- wawi/__init__.py +1 -1
- wawi/fe.py +259 -12
- wawi/general.py +538 -70
- wawi/identification.py +33 -11
- wawi/io.py +206 -3
- wawi/modal.py +384 -6
- wawi/model/_model.py +1 -1
- wawi/plot.py +379 -99
- wawi/prob.py +28 -0
- wawi/random.py +218 -2
- wawi/signal.py +111 -3
- wawi/structural.py +317 -59
- wawi/time_domain.py +122 -1
- wawi/tools.py +23 -0
- wawi/wave.py +662 -121
- wawi/wind.py +776 -32
- wawi/wind_code.py +26 -0
- {wawi-0.0.16.dist-info → wawi-0.0.17.dist-info}/METADATA +1 -1
- wawi-0.0.17.dist-info/RECORD +38 -0
- {wawi-0.0.16.dist-info → wawi-0.0.17.dist-info}/WHEEL +1 -1
- wawi-0.0.16.dist-info/RECORD +0 -38
- {wawi-0.0.16.dist-info → wawi-0.0.17.dist-info}/licenses/LICENSE +0 -0
- {wawi-0.0.16.dist-info → wawi-0.0.17.dist-info}/top_level.txt +0 -0
wawi/plot.py
CHANGED
@@ -8,7 +8,42 @@ from scipy.interpolate import RectBivariateSpline, interp1d
|
|
8
8
|
|
9
9
|
|
10
10
|
def plot_ads(ad_dict, v, terms='stiffness', num=None, test_v=dict(), test_ad=dict(), zasso_type=False, ranges=None):
|
11
|
-
|
11
|
+
"""
|
12
|
+
Plot aerodynamic derivative (AD) curves for multiple terms and test data.
|
13
|
+
|
14
|
+
Parameters
|
15
|
+
----------
|
16
|
+
ad_dict : dict
|
17
|
+
Dictionary mapping term names (e.g., 'P4', 'H6', etc.) to functions that compute aerodynamic derivative values for a given `v`.
|
18
|
+
v : array-like
|
19
|
+
Array of reduced velocity (or reduced frequency) at which to evaluate the aerodynamic derivative functions.
|
20
|
+
terms : str or list of list of str, optional
|
21
|
+
Specifies which terms to plot. If 'stiffness' or 'damping', uses predefined groupings. Otherwise, expects a nested list of term names.
|
22
|
+
num : int or None, optional
|
23
|
+
Figure number for matplotlib. If None, a new figure is created.
|
24
|
+
test_v : dict, optional
|
25
|
+
Dictionary mapping term names to arrays of test reduced velocity values for overlaying test data.
|
26
|
+
test_ad : dict, optional
|
27
|
+
Dictionary mapping term names to arrays of test aerodynamic derivative data corresponding to `test_v`.
|
28
|
+
zasso_type : bool, optional
|
29
|
+
If True, applies special formatting and scaling for Zasso-type plots.
|
30
|
+
ranges : dict or None, optional
|
31
|
+
Dictionary mapping term names to (min, max) tuples, specifying valid ranges for plotting. Values outside the range are clipped.
|
32
|
+
|
33
|
+
Returns
|
34
|
+
-------
|
35
|
+
fig : matplotlib.figure.Figure
|
36
|
+
The matplotlib Figure object containing the plots.
|
37
|
+
ax : numpy.ndarray of matplotlib.axes.Axes
|
38
|
+
Array of Axes objects for each subplot.
|
39
|
+
|
40
|
+
Notes
|
41
|
+
-----
|
42
|
+
- The function arranges subplots in a grid according to the structure of `terms`.
|
43
|
+
- Each subplot shows the fitted aerodynamic derivative curve and, if provided, test data points.
|
44
|
+
- Axis labels and scaling are adjusted depending on `zasso_type` and the term type.
|
45
|
+
"""
|
46
|
+
|
12
47
|
if terms == 'stiffness':
|
13
48
|
terms = [['P4', 'P6', 'P3'], ['H6', 'H4', 'H3'], ['A6', 'A4', 'A3']]
|
14
49
|
elif terms == 'damping':
|
@@ -68,6 +103,22 @@ def plot_ads(ad_dict, v, terms='stiffness', num=None, test_v=dict(), test_ad=dic
|
|
68
103
|
return fig, ax
|
69
104
|
|
70
105
|
def save_plot(pl, path, w=None, h=None):
|
106
|
+
'''
|
107
|
+
Saves pyvista plotter screenshot to file.
|
108
|
+
|
109
|
+
Parameters
|
110
|
+
----------
|
111
|
+
pl : pyvista.Plotter
|
112
|
+
PyVista plotter object.
|
113
|
+
path : str
|
114
|
+
Path to save the screenshot.
|
115
|
+
w : int, optional
|
116
|
+
Width of the screenshot. If None, uses the width of the plotter window.
|
117
|
+
h : int, optional
|
118
|
+
Height of the screenshot. If None, uses the height of the plotter window.
|
119
|
+
|
120
|
+
|
121
|
+
'''
|
71
122
|
ws = pl.window_size
|
72
123
|
if w is not None and h is None:
|
73
124
|
w = int(np.round(w))
|
@@ -86,9 +137,46 @@ def save_plot(pl, path, w=None, h=None):
|
|
86
137
|
def plot_dir_and_crests(theta0, Tp, arrow_length=100, origin=np.array([0,0]),
|
87
138
|
ax=None, n_repeats=2, crest_length=1000,
|
88
139
|
alpha_crests=0.2, arrow_options={}):
|
140
|
+
|
141
|
+
"""
|
142
|
+
Plot wave direction arrow and wave crests on a matplotlib axis.
|
143
|
+
|
144
|
+
Parameters
|
145
|
+
----------
|
146
|
+
theta0 : float
|
147
|
+
Wave direction in degrees (0 degrees is along the x-axis).
|
148
|
+
Tp : float
|
149
|
+
Peak wave period in seconds.
|
150
|
+
arrow_length : float, optional
|
151
|
+
Length of the direction arrow (default is 100).
|
152
|
+
origin : np.ndarray, optional
|
153
|
+
2D coordinates of the arrow origin (default is np.array([0, 0])).
|
154
|
+
ax : matplotlib.axes.Axes, optional
|
155
|
+
Axis to plot on. If None, uses current axis (default is None).
|
156
|
+
n_repeats : int, optional
|
157
|
+
Number of wave crests to plot (default is 2).
|
158
|
+
crest_length : float, optional
|
159
|
+
Length of each wave crest line (default is 1000).
|
160
|
+
alpha_crests : float, optional
|
161
|
+
Transparency (alpha) for the crest lines (default is 0.2).
|
162
|
+
arrow_options : dict, optional
|
163
|
+
Additional keyword arguments for the arrow (default is {}).
|
164
|
+
|
165
|
+
Returns
|
166
|
+
-------
|
167
|
+
ax : matplotlib.axes.Axes
|
168
|
+
The axis with the plotted wave direction and crests.
|
169
|
+
|
170
|
+
Notes
|
171
|
+
-----
|
172
|
+
- Requires `matplotlib.pyplot` as `plt` and `numpy` as `np` to be imported.
|
173
|
+
- The function also requires a `get_kappa` function to compute the wavenumber.
|
174
|
+
|
175
|
+
Docstring generated by GitHub Copilot.
|
176
|
+
"""
|
89
177
|
arr_opts = {'head_width': 4, 'width':2, 'edgecolor':'none'}
|
90
178
|
arr_opts.update(**arrow_options)
|
91
|
-
|
179
|
+
|
92
180
|
if ax is None:
|
93
181
|
ax = plt.gca()
|
94
182
|
|
@@ -112,6 +200,41 @@ def plot_dir_and_crests(theta0, Tp, arrow_length=100, origin=np.array([0,0]),
|
|
112
200
|
return ax
|
113
201
|
|
114
202
|
def rotate_image_about_pivot(Z, x, y, angle, x0=0, y0=0):
|
203
|
+
"""
|
204
|
+
Rotate an image array about a specified pivot point.
|
205
|
+
This function rotates a 2D image array `Z` by a given angle (in degrees) about a pivot point (`x0`, `y0`),
|
206
|
+
where the image axes are defined by the coordinate arrays `x` and `y`. The rotation is performed in the
|
207
|
+
coordinate space defined by `x` and `y`, not necessarily pixel indices.
|
208
|
+
|
209
|
+
Parameters
|
210
|
+
----------
|
211
|
+
Z : ndarray
|
212
|
+
2D array representing the image to be rotated.
|
213
|
+
x : array_like
|
214
|
+
1D array of x-coordinates corresponding to the columns of `Z`.
|
215
|
+
y : array_like
|
216
|
+
1D array of y-coordinates corresponding to the rows of `Z`.
|
217
|
+
angle : float
|
218
|
+
Rotation angle in degrees. Positive values correspond to counter-clockwise rotation.
|
219
|
+
x0 : float, optional
|
220
|
+
X-coordinate of the pivot point about which to rotate. Default is 0.
|
221
|
+
y0 : float, optional
|
222
|
+
Y-coordinate of the pivot point about which to rotate. Default is 0.
|
223
|
+
|
224
|
+
Returns
|
225
|
+
-------
|
226
|
+
rotated_Z : ndarray
|
227
|
+
The rotated image array, with the same shape as `Z`.
|
228
|
+
|
229
|
+
Notes
|
230
|
+
-----
|
231
|
+
- The function uses interpolation to map between coordinate space and pixel indices.
|
232
|
+
- The rotation is performed about the specified pivot point (`x0`, `y0`) in the coordinate system defined by `x` and `y`.
|
233
|
+
- Requires `numpy`, `scipy.ndimage.shift`, `scipy.ndimage.rotate`, and `scipy.interpolate.interp1d`.
|
234
|
+
|
235
|
+
Docstring generated by GitHub Copilot.
|
236
|
+
"""
|
237
|
+
|
115
238
|
xc = np.mean(x)
|
116
239
|
yc = np.mean(y)
|
117
240
|
|
@@ -130,6 +253,45 @@ def rotate_image_about_pivot(Z, x, y, angle, x0=0, y0=0):
|
|
130
253
|
return shift(rotate(shift(Z, ds[::-1]), angle), -ds_rot[::-1])
|
131
254
|
|
132
255
|
def combine_eta(eta_fine, eta_course, x_fine, y_fine, x_course, y_course, x=None, y=None):
|
256
|
+
"""
|
257
|
+
Combine two 2D fields (fine and coarse) into a single field, using the fine field where available.
|
258
|
+
|
259
|
+
Parameters
|
260
|
+
----------
|
261
|
+
eta_fine : ndarray
|
262
|
+
2D array of the fine-resolution field values.
|
263
|
+
eta_course : ndarray
|
264
|
+
2D array of the coarse-resolution field values.
|
265
|
+
x_fine : ndarray
|
266
|
+
1D array of x-coordinates for the fine field.
|
267
|
+
y_fine : ndarray
|
268
|
+
1D array of y-coordinates for the fine field.
|
269
|
+
x_course : ndarray
|
270
|
+
1D array of x-coordinates for the coarse field.
|
271
|
+
y_course : ndarray
|
272
|
+
1D array of y-coordinates for the coarse field.
|
273
|
+
x : ndarray, optional
|
274
|
+
1D array of x-coordinates for the output grid. If None, generated from coarse grid.
|
275
|
+
y : ndarray, optional
|
276
|
+
1D array of y-coordinates for the output grid. If None, generated from coarse grid.
|
277
|
+
|
278
|
+
Returns
|
279
|
+
-------
|
280
|
+
eta_combined : ndarray
|
281
|
+
2D array of the combined field, using fine field values where available and coarse elsewhere.
|
282
|
+
x : ndarray
|
283
|
+
1D array of x-coordinates for the combined field.
|
284
|
+
y : ndarray
|
285
|
+
1D array of y-coordinates for the combined field.
|
286
|
+
|
287
|
+
Notes
|
288
|
+
-----
|
289
|
+
The function interpolates both input fields onto a common grid. The fine field overwrites the coarse field
|
290
|
+
in the region where it is defined.
|
291
|
+
|
292
|
+
Docstring generated by GitHub Copilot.
|
293
|
+
"""
|
294
|
+
|
133
295
|
dx_fine = x_fine[1]-x_fine[0]
|
134
296
|
dy_fine = y_fine[1]-y_fine[0]
|
135
297
|
|
@@ -156,7 +318,47 @@ def combine_eta(eta_fine, eta_course, x_fine, y_fine, x_course, y_course, x=None
|
|
156
318
|
def animate_surface(eta, x, y, t, filename=None, fps=None,
|
157
319
|
speed_ratio=1.0, figsize=None, writer='ffmpeg',
|
158
320
|
ax=None, surface=None):
|
159
|
-
|
321
|
+
"""
|
322
|
+
Animates a time-evolving eta (sea surface).
|
323
|
+
|
324
|
+
Parameters
|
325
|
+
----------
|
326
|
+
eta : ndarray
|
327
|
+
3D array of surface values with shape (nx, ny, nt), where nt is the number of time steps.
|
328
|
+
x : ndarray
|
329
|
+
1D or 2D array representing the x-coordinates of the surface grid.
|
330
|
+
y : ndarray
|
331
|
+
1D or 2D array representing the y-coordinates of the surface grid.
|
332
|
+
t : ndarray
|
333
|
+
1D array of time points corresponding to the third dimension of `eta`.
|
334
|
+
filename : str or None, optional
|
335
|
+
If provided, the animation is saved to this file. If None, the animation is displayed interactively.
|
336
|
+
fps : float or None, optional
|
337
|
+
Frames per second for the animation. If None, it is computed from the time step and `speed_ratio`.
|
338
|
+
speed_ratio : float, optional
|
339
|
+
Ratio to speed up or slow down the animation relative to real time. Default is 1.0.
|
340
|
+
figsize : tuple or None, optional
|
341
|
+
Size of the figure in inches. Passed to `plt.subplots` if a new figure is created.
|
342
|
+
writer : str, optional
|
343
|
+
Writer to use for saving the animation (e.g., 'ffmpeg'). Default is 'ffmpeg'.
|
344
|
+
ax : matplotlib.axes.Axes or None, optional
|
345
|
+
Axes object to plot on. If None, a new figure and axes are created.
|
346
|
+
surface : matplotlib.image.AxesImage or None, optional
|
347
|
+
Existing surface image to update. If None, a new surface is created.
|
348
|
+
|
349
|
+
Returns
|
350
|
+
-------
|
351
|
+
None
|
352
|
+
The function either displays the animation or saves it to a file.
|
353
|
+
|
354
|
+
Notes
|
355
|
+
-----
|
356
|
+
- Requires matplotlib and numpy.
|
357
|
+
- The function uses `matplotlib.animation.FuncAnimation` for animation.
|
358
|
+
- If `filename` is provided, the animation is saved and not displayed interactively.
|
359
|
+
|
360
|
+
Docstring generated by GitHub Copilot.
|
361
|
+
"""
|
160
362
|
|
161
363
|
if surface is None:
|
162
364
|
if ax is None:
|
@@ -195,6 +397,31 @@ def animate_surface(eta, x, y, t, filename=None, fps=None,
|
|
195
397
|
plt.show()
|
196
398
|
|
197
399
|
def xy_to_latlon(latlon0, coors, rot=0):
|
400
|
+
"""
|
401
|
+
Convert local Cartesian (x, y) coordinates to latitude and longitude using geodesic calculations.
|
402
|
+
|
403
|
+
Parameters
|
404
|
+
----------
|
405
|
+
latlon0 : array-like, shape (2,)
|
406
|
+
The reference latitude and longitude (in degrees) as a 2-element array or list [lat, lon].
|
407
|
+
coors : array-like, shape (N, 2)
|
408
|
+
Array of local Cartesian coordinates (x, y) to be converted, where each row is a point.
|
409
|
+
rot : float, optional
|
410
|
+
Rotation angle in degrees to be subtracted from the computed azimuth, default is 0.
|
411
|
+
|
412
|
+
Returns
|
413
|
+
-------
|
414
|
+
latlon : ndarray, shape (N, 2)
|
415
|
+
Array of latitude and longitude pairs (in degrees) corresponding to the input coordinates.
|
416
|
+
|
417
|
+
Notes
|
418
|
+
-----
|
419
|
+
Uses Cartopy's geodesic calculations to convert local (x, y) displacements from a reference point
|
420
|
+
(latlon0) to geographic coordinates, accounting for Earth's curvature.
|
421
|
+
|
422
|
+
Docstring generated by GitHub Copilot.
|
423
|
+
"""
|
424
|
+
|
198
425
|
import cartopy.crs as ccrs, cartopy.geodesic as cgds
|
199
426
|
dist = np.linalg.norm(coors, axis=1)
|
200
427
|
azi = np.arctan2(coors[:,0], coors[:,1])*180/np.pi - rot # atan2(x,y) to get azimuth (relative to N-vector)
|
@@ -208,6 +435,56 @@ def plot_surface_in_map(eta, x, y, eta_geo0, extent,
|
|
208
435
|
wms_url='https://openwms.statkart.no/skwms1/wms.terrengmodell?request=GetCapabilities&service=WMS',
|
209
436
|
wms_layers=['relieff'], ax=None,
|
210
437
|
cm='Blues_r', colorbar=True, figsize=None, eta_rot=0, labels=False):
|
438
|
+
"""
|
439
|
+
Plot a 2D surface (e.g., elevation or other field) on a map with optional scatter points and WMS background.
|
440
|
+
|
441
|
+
Parameters
|
442
|
+
----------
|
443
|
+
eta : ndarray or None
|
444
|
+
2D array representing the surface to plot (e.g., elevation values). If None, only scatter and WMS are shown.
|
445
|
+
x : ndarray
|
446
|
+
1D or 2D array of x-coordinates corresponding to `eta`.
|
447
|
+
y : ndarray
|
448
|
+
1D or 2D array of y-coordinates corresponding to `eta`.
|
449
|
+
eta_geo0 : array-like
|
450
|
+
Reference geographic coordinates (e.g., origin for coordinate transformation).
|
451
|
+
extent : array-like
|
452
|
+
Map extent in the format [xmin, xmax, ymin, ymax] (in longitude and latitude).
|
453
|
+
eta_scatter : ndarray or None, optional
|
454
|
+
Array of points to scatter on the map, shape (N, 2). Default is None.
|
455
|
+
wms_url : str, optional
|
456
|
+
URL to the WMS service for background map. Default is Statkart's terrain model.
|
457
|
+
wms_layers : list of str, optional
|
458
|
+
List of WMS layer names to display. Default is ['relieff'].
|
459
|
+
ax : matplotlib.axes.Axes or None, optional
|
460
|
+
Existing axes to plot on. If None, a new axes with Mercator projection is created.
|
461
|
+
cm : str or Colormap, optional
|
462
|
+
Colormap for the surface plot. Default is 'Blues_r'.
|
463
|
+
colorbar : bool, optional
|
464
|
+
If True, display a colorbar for the surface. Default is True.
|
465
|
+
figsize : tuple or None, optional
|
466
|
+
Figure size. Not used if `ax` is provided. Default is None.
|
467
|
+
eta_rot : float, optional
|
468
|
+
Rotation angle (degrees) to apply to `eta` and scatter points. Default is 0.
|
469
|
+
labels : bool, optional
|
470
|
+
If True, draw gridlines with labels. Default is False.
|
471
|
+
|
472
|
+
Returns
|
473
|
+
-------
|
474
|
+
ax : matplotlib.axes.Axes
|
475
|
+
The axes with the plotted map.
|
476
|
+
scatter : matplotlib.collections.PathCollection or None
|
477
|
+
The scatter plot object, or None if `eta_scatter` is None.
|
478
|
+
surface : matplotlib.image.AxesImage or None
|
479
|
+
The surface plot object, or None if `eta` is None.
|
480
|
+
|
481
|
+
Notes
|
482
|
+
-----
|
483
|
+
- Requires cartopy and matplotlib.
|
484
|
+
- Assumes existence of `xy_to_latlon` and `rotate` helper functions.
|
485
|
+
|
486
|
+
Docstring generated by GitHub Copilot.
|
487
|
+
"""
|
211
488
|
|
212
489
|
import cartopy.crs as ccrs, cartopy.geodesic as cgds
|
213
490
|
|
@@ -270,6 +547,42 @@ def plot_surface_in_map(eta, x, y, eta_geo0, extent,
|
|
270
547
|
def plot_surface(eta, x, y, ax=None,
|
271
548
|
cm='Blues_r', colorbar=True,
|
272
549
|
labels=True, figsize=None, interpolation='none'):
|
550
|
+
"""
|
551
|
+
Plot a 2D surface using imshow.
|
552
|
+
|
553
|
+
Parameters
|
554
|
+
----------
|
555
|
+
eta : ndarray
|
556
|
+
2D array representing the surface to plot (e.g., elevation values).
|
557
|
+
x : ndarray
|
558
|
+
1D or 2D array of x-coordinates corresponding to `eta`.
|
559
|
+
y : ndarray
|
560
|
+
1D or 2D array of y-coordinates corresponding to `eta`.
|
561
|
+
ax : matplotlib.axes.Axes or None, optional
|
562
|
+
Existing axes to plot on. If None, a new axes is created.
|
563
|
+
cm : str or Colormap, optional
|
564
|
+
Colormap for the surface plot. Default is 'Blues_r'.
|
565
|
+
colorbar : bool, optional
|
566
|
+
If True, display a colorbar for the surface. Default is True.
|
567
|
+
labels : bool, optional
|
568
|
+
If True, draw gridlines with labels. Default is True.
|
569
|
+
figsize : tuple or None, optional
|
570
|
+
Figure size. Not used if `ax` is provided. Default is None.
|
571
|
+
interpolation : str, optional
|
572
|
+
Interpolation method for the surface plot. Default is 'none'.
|
573
|
+
|
574
|
+
Returns
|
575
|
+
-------
|
576
|
+
surface : matplotlib.image.AxesImage
|
577
|
+
The surface plot object.
|
578
|
+
ax : matplotlib.axes.Axes
|
579
|
+
The axes with the plotted surface.
|
580
|
+
|
581
|
+
Notes
|
582
|
+
-----
|
583
|
+
Docstring generated by GitHub Copilot.
|
584
|
+
|
585
|
+
"""
|
273
586
|
|
274
587
|
if ax is None:
|
275
588
|
fig, ax = plt.subplots(figsize=figsize)
|
@@ -295,7 +608,6 @@ def plot_surface(eta, x, y, ax=None,
|
|
295
608
|
|
296
609
|
|
297
610
|
def set_axes_equal(ax: plt.Axes):
|
298
|
-
import matplotlib.pyplot as plt
|
299
611
|
"""Set 3D plot axes to equal scale.
|
300
612
|
|
301
613
|
Make axes of 3D plot have equal scale so that spheres appear as
|
@@ -375,103 +687,38 @@ def plot_transformation_mats(x,y,z,T,figno=None, ax=None, scaling='auto'):
|
|
375
687
|
equal_3d(ax)
|
376
688
|
return ax,h
|
377
689
|
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
element_handles = [None]*len(element_matrix[:,0])
|
410
|
-
|
411
|
-
if plot_elements:
|
412
|
-
for element_ix, __ in enumerate(element_matrix[:,0]):
|
413
|
-
node1 = element_matrix[element_ix, 1]
|
414
|
-
node2 = element_matrix[element_ix, 2]
|
415
|
-
nodeix1 = np.where(node_matrix[:,0]==node1)[0]
|
416
|
-
nodeix2 = np.where(node_matrix[:,0]==node2)[0]
|
417
|
-
x01 = node_matrix[nodeix1,1:4]
|
418
|
-
x02 = node_matrix[nodeix2,1:4]
|
419
|
-
x0 = np.vstack([x01,x02])
|
420
|
-
|
421
|
-
if three_d:
|
422
|
-
element_handles[element_ix] = ax.plot(xs=x0[:,0], ys=x0[:,1], zs=x0[:,2], **e_dict)
|
423
|
-
else:
|
424
|
-
element_handles[element_ix] = ax.plot(x0[:,0], x0[:,1], **e_dict)
|
425
|
-
|
426
|
-
if element_labels:
|
427
|
-
xmean = np.mean(x0, axis=0)
|
428
|
-
if three_d:
|
429
|
-
ax.text(xmean[0],xmean[1],xmean[2],'%i' % element_matrix[element_ix,0], **l_elements_dict)
|
430
|
-
else:
|
431
|
-
ax.text(xmean[0],xmean[1],s='%i' % element_matrix[element_ix,0], **l_elements_dict)
|
432
|
-
|
433
|
-
if disp is not None:
|
434
|
-
disp_node1 = disp[nodeix1[0]*6:(nodeix1[0]*6+6)]
|
435
|
-
disp_node2 = disp[nodeix2[0]*6:(nodeix2[0]*6+6)]
|
436
|
-
x1 = x01+disp_node1[0:3]
|
437
|
-
x2 = x02+disp_node2[0:3]
|
438
|
-
x = np.vstack([x1,x2])
|
439
|
-
|
440
|
-
if three_d:
|
441
|
-
ax.plot(xs=x[:,0], ys=x[:,1], zs=x[:,2], **disp_dict)
|
442
|
-
else:
|
443
|
-
ax.plot(x[:,0], x[:,1], **disp_dict)
|
444
|
-
|
445
|
-
if plot_nodes:
|
446
|
-
if three_d:
|
447
|
-
ax.plot(xs=node_matrix[:, 1], ys=node_matrix[:, 2], zs=node_matrix[:, 3], **n_dict)
|
448
|
-
else:
|
449
|
-
ax.plot(node_matrix[:, 1], node_matrix[:, 2], **n_dict)
|
450
|
-
|
451
|
-
if chosen_nodes_ix != []:
|
452
|
-
if three_d:
|
453
|
-
ax.plot(xs=node_matrix[chosen_nodes_ix, 1], ys=node_matrix[chosen_nodes_ix, 2], zs=node_matrix[chosen_nodes_ix, 3], **n_chosen_dict)
|
454
|
-
else:
|
455
|
-
ax.plot(node_matrix[chosen_nodes_ix, 1], node_matrix[chosen_nodes_ix, 2], **n_chosen_dict)
|
456
|
-
|
457
|
-
if node_labels:
|
458
|
-
if three_d:
|
459
|
-
for node_ix in range(0, np.shape(node_matrix)[0]):
|
460
|
-
ax.text(node_matrix[node_ix, 1], node_matrix[node_ix, 2], node_matrix[node_ix, 3], '%i' % node_matrix[node_ix, 0], **l_nodes_dict)
|
461
|
-
else:
|
462
|
-
for node_ix in range(0, np.shape(node_matrix)[0]):
|
463
|
-
ax.text(node_matrix[node_ix, 1], node_matrix[node_ix, 2], '%i' % node_matrix[node_ix, 0], **l_nodes_dict)
|
690
|
+
def plot_2d(S2d, x1, x2, ax=None, levels=80, discrete=False, **kwargs):
|
691
|
+
"""
|
692
|
+
Plot a 2D array as either a filled contour plot or a pseudocolor mesh.
|
693
|
+
|
694
|
+
Parameters
|
695
|
+
----------
|
696
|
+
S2d : array_like
|
697
|
+
2D array of values to plot.
|
698
|
+
x1 : array_like
|
699
|
+
1D array representing the x-coordinates.
|
700
|
+
x2 : array_like
|
701
|
+
1D array representing the y-coordinates.
|
702
|
+
ax : matplotlib.axes.Axes, optional
|
703
|
+
The axes on which to plot. If None, uses the current axes.
|
704
|
+
levels : int, optional
|
705
|
+
Number of contour levels to use for filled contour plot. Default is 80.
|
706
|
+
discrete : bool, optional
|
707
|
+
If True, use `pcolormesh` for a discrete colormap. If False, use `contourf` for a filled contour plot.
|
708
|
+
**kwargs
|
709
|
+
Additional keyword arguments passed to the plotting function (`contourf` or `pcolormesh`).
|
710
|
+
|
711
|
+
Returns
|
712
|
+
-------
|
713
|
+
contour : QuadMesh or QuadContourSet
|
714
|
+
The resulting plot object from `pcolormesh` or `contourf`.
|
715
|
+
|
716
|
+
Notes
|
717
|
+
-----
|
718
|
+
Docstring generated by GitHub Copilot.
|
719
|
+
"""
|
464
720
|
|
465
|
-
if three_d:
|
466
|
-
equal_3d(ax)
|
467
|
-
else:
|
468
|
-
ax.set_aspect('equal', adjustable='box')
|
469
|
-
|
470
|
-
ax.grid('off')
|
471
|
-
return ax, element_handles
|
472
|
-
|
473
721
|
|
474
|
-
def plot_2d(S2d, x1, x2, ax=None, levels=80, discrete=False, **kwargs):
|
475
722
|
if ax is None:
|
476
723
|
ax = plt.gca()
|
477
724
|
|
@@ -484,6 +731,39 @@ def plot_2d(S2d, x1, x2, ax=None, levels=80, discrete=False, **kwargs):
|
|
484
731
|
|
485
732
|
|
486
733
|
def plot_S2d(S, omega, theta, D=None, omega_range=None, theta_range=None):
|
734
|
+
"""
|
735
|
+
Plot a 2D spectral density (S2d) as a contour plot, with optional marginal plots (S and D).
|
736
|
+
|
737
|
+
Parameters
|
738
|
+
----------
|
739
|
+
S : array_like
|
740
|
+
1D array of spectral density values as a function of omega.
|
741
|
+
omega : array_like
|
742
|
+
1D array of frequency values (rad/s).
|
743
|
+
theta : array_like
|
744
|
+
1D array of direction values (rad).
|
745
|
+
D : array_like, optional
|
746
|
+
1D array of directional spreading function values as a function of theta.
|
747
|
+
If provided, marginal plots of S(omega) and D(theta) are shown.
|
748
|
+
omega_range : list or tuple, optional
|
749
|
+
Range [min, max] for the omega axis. If None, uses [0, max(omega)].
|
750
|
+
theta_range : list or tuple, optional
|
751
|
+
Range [min, max] for the theta axis. If None, uses [min(theta), max(theta)].
|
752
|
+
|
753
|
+
Returns
|
754
|
+
-------
|
755
|
+
fig : matplotlib.figure.Figure
|
756
|
+
The matplotlib Figure object containing the plot.
|
757
|
+
|
758
|
+
Notes
|
759
|
+
-----
|
760
|
+
- If `D` is provided, the function plots the 2D spectral density as a contour plot,
|
761
|
+
with marginal line plots for S(omega) and D(theta).
|
762
|
+
- If `D` is not provided, only the contour plot is shown.
|
763
|
+
- The function handles NaN values in the spectral density by setting them to zero.
|
764
|
+
|
765
|
+
Docstring generated by GitHub Copilot.
|
766
|
+
"""
|
487
767
|
|
488
768
|
if theta_range is None:
|
489
769
|
theta_range = [np.min(theta), np.max(theta)]
|
wawi/prob.py
CHANGED
@@ -1,6 +1,34 @@
|
|
1
1
|
import numpy as np
|
2
2
|
|
3
3
|
def gumbel_log(umax):
|
4
|
+
"""
|
5
|
+
Compute the Gumbel reduced variate for a given array of maxima.
|
6
|
+
|
7
|
+
Parameters
|
8
|
+
----------
|
9
|
+
umax : array_like
|
10
|
+
Array of maxima values.
|
11
|
+
|
12
|
+
Returns
|
13
|
+
-------
|
14
|
+
umax_ordered : ndarray
|
15
|
+
The input maxima sorted in descending order.
|
16
|
+
loglogF : ndarray
|
17
|
+
The Gumbel reduced variate corresponding to each sorted maxima.
|
18
|
+
|
19
|
+
Examples
|
20
|
+
--------
|
21
|
+
>>> import numpy as np
|
22
|
+
>>> umax = np.array([2.3, 3.1, 1.8, 2.9])
|
23
|
+
>>> umax_ordered, loglogF = gumbel_log(umax)
|
24
|
+
|
25
|
+
Notes
|
26
|
+
-------
|
27
|
+
This function sorts the input array of maxima in descending order and computes the
|
28
|
+
Gumbel reduced variate (log-log of the empirical cumulative distribution function)
|
29
|
+
for each value.
|
30
|
+
"""
|
31
|
+
|
4
32
|
umax_ordered = np.sort(umax)[::-1]
|
5
33
|
N_stat = len(umax)
|
6
34
|
F = 1-np.arange(1, N_stat+1)/(N_stat+1)
|