weac 2.6.0__py3-none-any.whl → 2.6.2__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.
weac/plot.py CHANGED
@@ -3,8 +3,8 @@
3
3
  # pylint: disable=too-many-arguments,too-many-statements
4
4
 
5
5
  # Standard library imports
6
- import os
7
6
  import colorsys
7
+ import os
8
8
 
9
9
  # Third party imports
10
10
  import matplotlib.colors as mc
@@ -19,28 +19,32 @@ from weac.tools import isnotebook
19
19
 
20
20
  def set_plotstyles():
21
21
  """Define styles plot markers, labels and colors."""
22
- labelstyle = { # Text style of plot labels
23
- 'backgroundcolor': 'w',
24
- 'horizontalalignment': 'center',
25
- 'verticalalignment': 'center'}
22
+ labelstyle = { # Text style of plot labels
23
+ "backgroundcolor": "w",
24
+ "horizontalalignment": "center",
25
+ "verticalalignment": "center",
26
+ }
26
27
  # markerstyle = { # Style of plot markers
27
28
  # 'marker': 'o',
28
29
  # 'markersize': 5,
29
30
  # 'markerfacecolor': 'w',
30
31
  # 'zorder': 3}
31
- colors = np.array([ # TUD color palette
32
- ['#DCDCDC', '#B5B5B5', '#898989', '#535353'], # gray
33
- ['#5D85C3', '#005AA9', '#004E8A', '#243572'], # blue
34
- ['#009CDA', '#0083CC', '#00689D', '#004E73'], # ocean
35
- ['#50B695', '#009D81', '#008877', '#00715E'], # teal
36
- ['#AFCC50', '#99C000', '#7FAB16', '#6A8B22'], # green
37
- ['#DDDF48', '#C9D400', '#B1BD00', '#99A604'], # lime
38
- ['#FFE05C', '#FDCA00', '#D7AC00', '#AE8E00'], # yellow
39
- ['#F8BA3C', '#F5A300', '#D28700', '#BE6F00'], # sand
40
- ['#EE7A34', '#EC6500', '#CC4C03', '#A94913'], # orange
41
- ['#E9503E', '#E6001A', '#B90F22', '#961C26'], # red
42
- ['#C9308E', '#A60084', '#951169', '#732054'], # magenta
43
- ['#804597', '#721085', '#611C73', '#4C226A']]) # puple
32
+ colors = np.array(
33
+ [ # TUD color palette
34
+ ["#DCDCDC", "#B5B5B5", "#898989", "#535353"], # gray
35
+ ["#5D85C3", "#005AA9", "#004E8A", "#243572"], # blue
36
+ ["#009CDA", "#0083CC", "#00689D", "#004E73"], # ocean
37
+ ["#50B695", "#009D81", "#008877", "#00715E"], # teal
38
+ ["#AFCC50", "#99C000", "#7FAB16", "#6A8B22"], # green
39
+ ["#DDDF48", "#C9D400", "#B1BD00", "#99A604"], # lime
40
+ ["#FFE05C", "#FDCA00", "#D7AC00", "#AE8E00"], # yellow
41
+ ["#F8BA3C", "#F5A300", "#D28700", "#BE6F00"], # sand
42
+ ["#EE7A34", "#EC6500", "#CC4C03", "#A94913"], # orange
43
+ ["#E9503E", "#E6001A", "#B90F22", "#961C26"], # red
44
+ ["#C9308E", "#A60084", "#951169", "#732054"], # magenta
45
+ ["#804597", "#721085", "#611C73", "#4C226A"], # purple
46
+ ]
47
+ )
44
48
  return labelstyle, colors
45
49
 
46
50
 
@@ -57,13 +61,19 @@ class MidpointNormalize(mc.Normalize):
57
61
 
58
62
  def __call__(self, value, clip=None):
59
63
  """Make instances callable as functions."""
60
- normalized_min = max(0, 0.5*(1 - abs(
61
- (self.midpoint - self.vmin)/(self.midpoint - self.vmax))))
62
- normalized_max = min(1, 0.5*(1 + abs(
63
- (self.vmax - self.midpoint)/(self.midpoint - self.vmin))))
64
+ normalized_min = max(
65
+ 0,
66
+ 0.5 * (1 - abs((self.midpoint - self.vmin) / (self.midpoint - self.vmax))),
67
+ )
68
+ normalized_max = min(
69
+ 1,
70
+ 0.5 * (1 + abs((self.vmax - self.midpoint) / (self.midpoint - self.vmin))),
71
+ )
64
72
  normalized_mid = 0.5
65
- x, y = [self.vmin, self.midpoint, self.vmax], [
66
- normalized_min, normalized_mid, normalized_max]
73
+ x, y = (
74
+ [self.vmin, self.midpoint, self.vmax],
75
+ [normalized_min, normalized_mid, normalized_max],
76
+ )
67
77
  return np.ma.masked_array(np.interp(value, x, y))
68
78
 
69
79
 
@@ -113,8 +123,8 @@ def tight_central_distribution(limit, samples=100, tightness=1.5):
113
123
  ndarray
114
124
  Array of values more tightly spaced around 0.
115
125
  """
116
- stop = limit**(1/tightness)
117
- levels = np.linspace(0, stop, num=int(samples/2), endpoint=True)**tightness
126
+ stop = limit ** (1 / tightness)
127
+ levels = np.linspace(0, stop, num=int(samples / 2), endpoint=True) ** tightness
118
128
  return np.unique(np.hstack([-levels[::-1], levels]))
119
129
 
120
130
 
@@ -141,6 +151,7 @@ def adjust_lightness(color, amount=0.5):
141
151
  c = colorsys.rgb_to_hls(*mc.to_rgb(c))
142
152
  return colorsys.hls_to_rgb(c[0], max(0, min(1, amount * c[1])), c[2])
143
153
 
154
+
144
155
  # === PLOT SLAB PROFILE =======================================================
145
156
 
146
157
 
@@ -148,11 +159,11 @@ def slab_profile(instance):
148
159
  """Create bar chart of slab profile."""
149
160
  # Plot Setup
150
161
  plt.rcdefaults()
151
- plt.rc('font', family='serif', size=10)
152
- plt.rc('mathtext', fontset='cm')
162
+ plt.rc("font", family="serif", size=10)
163
+ plt.rc("mathtext", fontset="cm")
153
164
 
154
165
  # Create figure
155
- fig = plt.figure(figsize=(8/3, 4))
166
+ fig = plt.figure(figsize=(8 / 3, 4))
156
167
  ax1 = fig.gca()
157
168
 
158
169
  # Initialize coordinates
@@ -169,15 +180,15 @@ def slab_profile(instance):
169
180
  y.append(total_heigth)
170
181
 
171
182
  # Set axis labels
172
- ax1.set_xlabel(r'$\longleftarrow$ Density $\rho$ (kg/m$^3$)')
173
- ax1.set_ylabel(r'Height above weak layer (mm) $\longrightarrow$')
183
+ ax1.set_xlabel(r"$\longleftarrow$ Density $\rho$ (kg/m$^3$)")
184
+ ax1.set_ylabel(r"Height above weak layer (mm) $\longrightarrow$")
174
185
 
175
186
  ax1.set_xlim(500, 0)
176
187
 
177
188
  ax1.fill_betweenx(y, 0, x)
178
189
 
179
190
  # Save figure
180
- save_plot(name='profile')
191
+ save_plot(name="profile")
181
192
 
182
193
  # Reset plot styles
183
194
  plt.rcdefaults()
@@ -185,13 +196,27 @@ def slab_profile(instance):
185
196
  # Clear Canvas
186
197
  plt.close()
187
198
 
199
+
188
200
  # === DEFORMATION CONTOUR PLOT ================================================
189
201
 
190
202
 
191
- def deformed(instance, xsl, xwl, z, phi, dz=2, scale=100,
192
- window=np.inf, pad=2, levels=300, aspect=2,
193
- field='principal', normalize=True, dark=False,
194
- filename='cont'):
203
+ def deformed(
204
+ instance,
205
+ xsl,
206
+ xwl,
207
+ z,
208
+ phi,
209
+ dz=2,
210
+ scale=100,
211
+ window=np.inf,
212
+ pad=2,
213
+ levels=300,
214
+ aspect=2,
215
+ field="principal",
216
+ normalize=True,
217
+ dark=False,
218
+ filename="cont",
219
+ ):
195
220
  """
196
221
  Plot 2D deformed solution with displacement or stress fields.
197
222
 
@@ -239,44 +264,44 @@ def deformed(instance, xsl, xwl, z, phi, dz=2, scale=100,
239
264
  """
240
265
  # Plot Setup
241
266
  plt.rcdefaults()
242
- plt.rc('font', family='serif', size=10)
243
- plt.rc('mathtext', fontset='cm')
267
+ plt.rc("font", family="serif", size=10)
268
+ plt.rc("mathtext", fontset="cm")
244
269
 
245
270
  # Set dark figure background if requested
246
271
  if dark:
247
- plt.style.use('dark_background')
272
+ plt.style.use("dark_background")
248
273
  fig = plt.figure()
249
274
  ax = plt.gca()
250
- fig.set_facecolor('#282c34')
251
- ax.set_facecolor('white')
275
+ fig.set_facecolor("#282c34")
276
+ ax.set_facecolor("white")
252
277
 
253
278
  # Calculate top-to-bottom vertical positions (mm) in beam coordinate system
254
279
  zi = instance.get_zmesh(dz=dz)[:, 0]
255
280
  h = instance.h
256
281
 
257
282
  # Compute slab displacements on grid (cm)
258
- Usl = np.vstack([instance.u(z, z0=z0, unit='cm') for z0 in zi])
259
- Wsl = np.vstack([instance.w(z, unit='cm') for _ in zi])
283
+ Usl = np.vstack([instance.u(z, z0=z0, unit="cm") for z0 in zi])
284
+ Wsl = np.vstack([instance.w(z, unit="cm") for _ in zi])
260
285
 
261
286
  # Put coordinate origin at horizontal center
262
- if instance.system in ['skier', 'skiers']:
263
- xsl = xsl - max(xsl)/2
264
- xwl = xwl - max(xwl)/2
287
+ if instance.system in ["skier", "skiers"]:
288
+ xsl = xsl - max(xsl) / 2
289
+ xwl = xwl - max(xwl) / 2
265
290
 
266
291
  # Compute slab grid coordinates with vertical origin at top surface (cm)
267
- Xsl, Zsl = np.meshgrid(1e-1*(xsl), 1e-1*(zi + h/2))
292
+ Xsl, Zsl = np.meshgrid(1e-1 * (xsl), 1e-1 * (zi + h / 2))
268
293
 
269
294
  # Get x-coordinate of maximum deflection w (cm) and derive plot limits
270
- xfocus = xsl[np.max(np.argmax(Wsl, axis=1))]/10
271
- xmax = np.min([np.max([Xsl, Xsl+scale*Usl]) + pad, xfocus + window/2])
272
- xmin = np.max([np.min([Xsl, Xsl+scale*Usl]) - pad, xfocus - window/2])
295
+ xfocus = xsl[np.max(np.argmax(Wsl, axis=1))] / 10
296
+ xmax = np.min([np.max([Xsl, Xsl + scale * Usl]) + pad, xfocus + window / 2])
297
+ xmin = np.max([np.min([Xsl, Xsl + scale * Usl]) - pad, xfocus - window / 2])
273
298
 
274
299
  # Scale shown weak-layer thickness with to max deflection and add padding
275
- zmax = np.max(Zsl + scale*Wsl) + pad
300
+ zmax = np.max(Zsl + scale * Wsl) + pad
276
301
  zmin = np.min(Zsl) - pad
277
302
 
278
303
  # Compute weak-layer grid coordinates (cm)
279
- Xwl, Zwl = np.meshgrid(1e-1*xwl, [1e-1*(zi[-1] + h/2), zmax])
304
+ Xwl, Zwl = np.meshgrid(1e-1 * xwl, [1e-1 * (zi[-1] + h / 2), zmax])
280
305
 
281
306
  # Assemble weak-layer displacement field (top and bottom)
282
307
  Uwl = np.row_stack([Usl[-1, :], np.zeros(xwl.shape[0])])
@@ -285,51 +310,56 @@ def deformed(instance, xsl, xwl, z, phi, dz=2, scale=100,
285
310
  # Compute stress or displacement fields
286
311
  match field:
287
312
  # Horizontal displacements (um)
288
- case 'u':
289
- slab = 1e4*Usl
290
- weak = 1e4*Usl[-1, :]
291
- label = r'$u$ ($\mu$m)'
313
+ case "u":
314
+ slab = 1e4 * Usl
315
+ weak = 1e4 * Usl[-1, :]
316
+ label = r"$u$ ($\mu$m)"
292
317
  # Vertical deflection (um)
293
- case 'w':
294
- slab = 1e4*Wsl
295
- weak = 1e4*Wsl[-1, :]
296
- label = r'$w$ ($\mu$m)'
318
+ case "w":
319
+ slab = 1e4 * Wsl
320
+ weak = 1e4 * Wsl[-1, :]
321
+ label = r"$w$ ($\mu$m)"
297
322
  # Axial normal stresses (kPa)
298
- case 'Sxx':
299
- slab = instance.Sxx(z, phi, dz=dz, unit='kPa')
323
+ case "Sxx":
324
+ slab = instance.Sxx(z, phi, dz=dz, unit="kPa")
300
325
  weak = np.zeros(xwl.shape[0])
301
- label = r'$\sigma_{xx}$ (kPa)'
326
+ label = r"$\sigma_{xx}$ (kPa)"
302
327
  # Shear stresses (kPa)
303
- case 'Txz':
304
- slab = instance.Txz(z, phi, dz=dz, unit='kPa')
305
- weak = instance.get_weaklayer_shearstress(
306
- x=xwl, z=z, unit='kPa')[1]
307
- label = r'$\tau_{xz}$ (kPa)'
328
+ case "Txz":
329
+ slab = instance.Txz(z, phi, dz=dz, unit="kPa")
330
+ weak = instance.get_weaklayer_shearstress(x=xwl, z=z, unit="kPa")[1]
331
+ label = r"$\tau_{xz}$ (kPa)"
308
332
  # Transverse normal stresses (kPa)
309
- case 'Szz':
310
- slab = instance.Szz(z, phi, dz=dz, unit='kPa')
311
- weak = instance.get_weaklayer_normalstress(
312
- x=xwl, z=z, unit='kPa')[1]
313
- label = r'$\sigma_{zz}$ (kPa)'
333
+ case "Szz":
334
+ slab = instance.Szz(z, phi, dz=dz, unit="kPa")
335
+ weak = instance.get_weaklayer_normalstress(x=xwl, z=z, unit="kPa")[1]
336
+ label = r"$\sigma_{zz}$ (kPa)"
314
337
  # Principal stresses
315
- case 'principal':
338
+ case "principal":
316
339
  slab = instance.principal_stress_slab(
317
- z, phi, dz=dz, val='max', unit='kPa', normalize=normalize)
340
+ z, phi, dz=dz, val="max", unit="kPa", normalize=normalize
341
+ )
318
342
  weak = instance.principal_stress_weaklayer(
319
- z, val='min', unit='kPa', normalize=normalize)
343
+ z, val="min", unit="kPa", normalize=normalize
344
+ )
320
345
  if normalize:
321
- label=(r'$\sigma_\mathrm{I}/\sigma_+$ (slab), '
322
- r'$\sigma_\mathrm{I\!I\!I}/\sigma_-$ (weak layer)')
346
+ label = (
347
+ r"$\sigma_\mathrm{I}/\sigma_+$ (slab), "
348
+ r"$\sigma_\mathrm{I\!I\!I}/\sigma_-$ (weak layer)"
349
+ )
323
350
  else:
324
- label=(r'$\sigma_\mathrm{I}$ (kPa, slab), '
325
- r'$\sigma_\mathrm{I\!I\!I}$ (kPa, weak layer)')
351
+ label = (
352
+ r"$\sigma_\mathrm{I}$ (kPa, slab), "
353
+ r"$\sigma_\mathrm{I\!I\!I}$ (kPa, weak layer)"
354
+ )
326
355
  case _:
327
356
  raise ValueError(
328
357
  f"Invalid input '{field}' for field. Valid options are "
329
- "'u', 'w', 'Sxx', 'Txz', 'Szz', or 'principal'")
358
+ "'u', 'w', 'Sxx', 'Txz', 'Szz', or 'principal'"
359
+ )
330
360
 
331
361
  # Complement label
332
- label += r' $\longrightarrow$'
362
+ label += r" $\longrightarrow$"
333
363
 
334
364
  # Assemble weak-layer output on grid
335
365
  weak = np.row_stack([weak, weak])
@@ -337,26 +367,27 @@ def deformed(instance, xsl, xwl, z, phi, dz=2, scale=100,
337
367
  # Normalize colormap
338
368
  absmax = np.nanmax(np.abs([slab.min(), slab.max(), weak.min(), weak.max()]))
339
369
  clim = np.round(absmax, significant_digits(absmax))
340
- levels = np.linspace(-clim, clim, num=levels+1, endpoint=True)
370
+ levels = np.linspace(-clim, clim, num=levels + 1, endpoint=True)
341
371
  # nanmax = np.nanmax([slab.max(), weak.max()])
342
372
  # nanmin = np.nanmin([slab.min(), weak.min()])
343
373
  # norm = MidpointNormalize(vmin=nanmin, vmax=nanmax)
344
374
 
345
375
  # Plot baseline
346
- plt.axhline(zmax, color='k', linewidth=1)
376
+ plt.axhline(zmax, color="k", linewidth=1)
347
377
 
348
378
  # Plot outlines of the undeformed and deformed slab
349
- plt.plot(outline(Xsl), outline(Zsl), 'k--', alpha=0.3, linewidth=1)
350
- plt.plot(outline(Xsl + scale*Usl),
351
- outline(Zsl + scale*Wsl),
352
- 'k', linewidth=1)
379
+ plt.plot(outline(Xsl), outline(Zsl), "k--", alpha=0.3, linewidth=1)
380
+ plt.plot(outline(Xsl + scale * Usl), outline(Zsl + scale * Wsl), "k", linewidth=1)
353
381
 
354
382
  # Plot deformed weak-layer outline
355
- if instance.system in ['-pst', 'pst-', '-vpst', 'vpst-']:
383
+ if instance.system in ["-pst", "pst-", "-vpst", "vpst-"]:
356
384
  nanmask = np.isfinite(xwl)
357
- plt.plot(outline(Xwl[:, nanmask] + scale*Uwl[:, nanmask]),
358
- outline(Zwl[:, nanmask] + scale*Wwl[:, nanmask]),
359
- 'k', linewidth=1)
385
+ plt.plot(
386
+ outline(Xwl[:, nanmask] + scale * Uwl[:, nanmask]),
387
+ outline(Zwl[:, nanmask] + scale * Wwl[:, nanmask]),
388
+ "k",
389
+ linewidth=1,
390
+ )
360
391
 
361
392
  # Colormap
362
393
  cmap = plt.cm.RdBu_r
@@ -364,15 +395,25 @@ def deformed(instance, xsl, xwl, z, phi, dz=2, scale=100,
364
395
  cmap.set_under(adjust_lightness(cmap(0.0), 0.9))
365
396
 
366
397
  # Plot fields
367
- plt.contourf(Xsl + scale*Usl, Zsl + scale*Wsl, slab,
368
- levels=levels, # norm=norm,
369
- cmap=cmap, extend='both')
370
- plt.contourf(Xwl + scale*Uwl, Zwl + scale*Wwl, weak,
371
- levels=levels, # norm=norm,
372
- cmap=cmap, extend='both')
398
+ plt.contourf(
399
+ Xsl + scale * Usl,
400
+ Zsl + scale * Wsl,
401
+ slab,
402
+ levels=levels, # norm=norm,
403
+ cmap=cmap,
404
+ extend="both",
405
+ )
406
+ plt.contourf(
407
+ Xwl + scale * Uwl,
408
+ Zwl + scale * Wwl,
409
+ weak,
410
+ levels=levels, # norm=norm,
411
+ cmap=cmap,
412
+ extend="both",
413
+ )
373
414
 
374
415
  # Plot setup
375
- plt.axis('scaled')
416
+ plt.axis("scaled")
376
417
  plt.xlim([xmin, xmax])
377
418
  plt.ylim([zmin, zmax])
378
419
  plt.gca().set_aspect(aspect)
@@ -380,14 +421,13 @@ def deformed(instance, xsl, xwl, z, phi, dz=2, scale=100,
380
421
  plt.gca().use_sticky_edges = False
381
422
 
382
423
  # Plot labels
383
- plt.gca().set_xlabel(r'lateral position $x$ (cm) $\longrightarrow$')
384
- plt.gca().set_ylabel('depth below surface\n' + r'$\longleftarrow $ $d$ (cm)')
385
- plt.title(fr'${scale}\!\times\!$ scaled deformations (cm)', size=10)
424
+ plt.gca().set_xlabel(r"lateral position $x$ (cm) $\longrightarrow$")
425
+ plt.gca().set_ylabel("depth below surface\n" + r"$\longleftarrow $ $d$ (cm)")
426
+ plt.title(rf"${scale}\!\times\!$ scaled deformations (cm)", size=10)
386
427
 
387
428
  # Show colorbar
388
429
  ticks = np.linspace(levels[0], levels[-1], num=11, endpoint=True)
389
- plt.colorbar(orientation='horizontal', ticks=ticks,
390
- label=label, aspect=35)
430
+ plt.colorbar(orientation="horizontal", ticks=ticks, label=label, aspect=35)
391
431
 
392
432
  # Save figure
393
433
  save_plot(name=filename)
@@ -403,95 +443,104 @@ def deformed(instance, xsl, xwl, z, phi, dz=2, scale=100,
403
443
 
404
444
 
405
445
  def plot_data(
406
- name, ax1data, ax1label,
407
- ax2data=None, ax2label=None,
408
- labelpos=None, vlines=True,
409
- li=False, mi=False, ki=False,
410
- xlabel=r'Horizontal position $x$ (cm)'):
446
+ name,
447
+ ax1data,
448
+ ax1label,
449
+ ax2data=None,
450
+ ax2label=None,
451
+ labelpos=None,
452
+ vlines=True,
453
+ li=False,
454
+ mi=False,
455
+ ki=False,
456
+ xlabel=r"Horizontal position $x$ (cm)",
457
+ ):
411
458
  """Plot data. Base function."""
412
459
  # Figure setup
413
460
  plt.rcdefaults()
414
- plt.rc('font', family='serif', size=10)
415
- plt.rc('mathtext', fontset='cm')
461
+ plt.rc("font", family="serif", size=10)
462
+ plt.rc("mathtext", fontset="cm")
416
463
 
417
464
  # Plot styles
418
465
  labelstyle, colors = set_plotstyles()
419
466
 
420
467
  # Create figure
421
- fig = plt.figure(figsize=(4, 8/3))
468
+ fig = plt.figure(figsize=(4, 8 / 3))
422
469
  ax1 = fig.gca()
423
470
 
424
471
  # Axis limits
425
- ax1.autoscale(axis='x', tight=True)
472
+ ax1.autoscale(axis="x", tight=True)
426
473
 
427
474
  # Set axis labels
428
- ax1.set_xlabel(xlabel + r' $\longrightarrow$')
429
- ax1.set_ylabel(ax1label + r' $\longrightarrow$')
475
+ ax1.set_xlabel(xlabel + r" $\longrightarrow$")
476
+ ax1.set_ylabel(ax1label + r" $\longrightarrow$")
430
477
 
431
478
  # Plot x-axis
432
- ax1.axhline(0, linewidth=0.5, color='gray')
479
+ ax1.axhline(0, linewidth=0.5, color="gray")
433
480
 
434
481
  # Plot vertical separators
435
482
  if vlines:
436
- ax1.axvline(0, linewidth=0.5, color='gray')
483
+ ax1.axvline(0, linewidth=0.5, color="gray")
437
484
  for i, f in enumerate(ki):
438
485
  if not f:
439
- ax1.axvspan(sum(li[:i])/10, sum(li[:i+1])/10,
440
- facecolor='gray', alpha=0.05, zorder=100)
486
+ ax1.axvspan(
487
+ sum(li[:i]) / 10,
488
+ sum(li[: i + 1]) / 10,
489
+ facecolor="gray",
490
+ alpha=0.05,
491
+ zorder=100,
492
+ )
441
493
  for i, m in enumerate(mi, start=1):
442
494
  if m > 0:
443
- ax1.axvline(sum(li[:i])/10, linewidth=0.5, color='gray')
495
+ ax1.axvline(sum(li[:i]) / 10, linewidth=0.5, color="gray")
444
496
  else:
445
- ax1.autoscale(axis='y', tight=True)
497
+ ax1.autoscale(axis="y", tight=True)
446
498
 
447
499
  # Calculate labelposition
448
500
  if not labelpos:
449
501
  x = ax1data[0][0]
450
- labelpos = int(0.95*len(x[~np.isnan(x)]))
502
+ labelpos = int(0.95 * len(x[~np.isnan(x)]))
451
503
 
452
504
  # Fill left y-axis
453
505
  i = 0
454
506
  for x, y, label in ax1data:
455
507
  i += 1
456
- if label == '' or 'FEA' in label:
508
+ if label == "" or "FEA" in label:
457
509
  # line, = ax1.plot(x, y, 'k:', linewidth=1)
458
- ax1.plot(x, y, linewidth=3, color='white')
459
- line, = ax1.plot(x, y, ':', linewidth=1) # , color='black'
510
+ ax1.plot(x, y, linewidth=3, color="white")
511
+ (line,) = ax1.plot(x, y, ":", linewidth=1) # , color='black'
460
512
  thislabelpos = -2
461
513
  x, y = x[~np.isnan(x)], y[~np.isnan(x)]
462
- xtx = (x[thislabelpos - 1] + x[thislabelpos])/2
463
- ytx = (y[thislabelpos - 1] + y[thislabelpos])/2
464
- ax1.text(xtx, ytx, label, color=line.get_color(),
465
- **labelstyle)
514
+ xtx = (x[thislabelpos - 1] + x[thislabelpos]) / 2
515
+ ytx = (y[thislabelpos - 1] + y[thislabelpos]) / 2
516
+ ax1.text(xtx, ytx, label, color=line.get_color(), **labelstyle)
466
517
  else:
467
518
  # Plot line
468
- ax1.plot(x, y, linewidth=3, color='white')
469
- line, = ax1.plot(x, y, linewidth=1)
519
+ ax1.plot(x, y, linewidth=3, color="white")
520
+ (line,) = ax1.plot(x, y, linewidth=1)
470
521
  # Line label
471
522
  x, y = x[~np.isnan(x)], y[~np.isnan(x)]
472
523
  if len(x) > 0:
473
- xtx = (x[labelpos - 10*i - 1] + x[labelpos - 10*i])/2
474
- ytx = (y[labelpos - 10*i - 1] + y[labelpos - 10*i])/2
475
- ax1.text(xtx, ytx, label, color=line.get_color(),
476
- **labelstyle)
524
+ xtx = (x[labelpos - 10 * i - 1] + x[labelpos - 10 * i]) / 2
525
+ ytx = (y[labelpos - 10 * i - 1] + y[labelpos - 10 * i]) / 2
526
+ ax1.text(xtx, ytx, label, color=line.get_color(), **labelstyle)
477
527
 
478
528
  # Fill right y-axis
479
529
  if ax2data:
480
530
  # Create right y-axis
481
531
  ax2 = ax1.twinx()
482
532
  # Set axis label
483
- ax2.set_ylabel(ax2label + r' $\longrightarrow$')
533
+ ax2.set_ylabel(ax2label + r" $\longrightarrow$")
484
534
  # Fill
485
535
  for x, y, label in ax2data:
486
536
  # Plot line
487
- ax2.plot(x, y, linewidth=3, color='white')
488
- line, = ax2.plot(x, y, linewidth=1, color=colors[8, 0])
537
+ ax2.plot(x, y, linewidth=3, color="white")
538
+ (line,) = ax2.plot(x, y, linewidth=1, color=colors[8, 0])
489
539
  # Line label
490
540
  x, y = x[~np.isnan(x)], y[~np.isnan(x)]
491
- xtx = (x[labelpos - 1] + x[labelpos])/2
492
- ytx = (y[labelpos - 1] + y[labelpos])/2
493
- ax2.text(xtx, ytx, label, color=line.get_color(),
494
- **labelstyle)
541
+ xtx = (x[labelpos - 1] + x[labelpos]) / 2
542
+ ytx = (y[labelpos - 1] + y[labelpos]) / 2
543
+ ax2.text(xtx, ytx, label, color=line.get_color(), **labelstyle)
495
544
 
496
545
  # Save figure
497
546
  save_plot(name)
@@ -506,105 +555,104 @@ def plot_data(
506
555
  # === PLOT WRAPPERS ===========================================================
507
556
 
508
557
 
509
- def displacements(instance, x, z, i='', **segments):
558
+ def displacements(instance, x, z, i="", **segments):
510
559
  """Wrap for dispalcements plot."""
511
560
  data = [
512
- [x/10, instance.u(z, z0=0, unit='mm'), r'$u_0\ (\mathrm{mm})$'],
513
- [x/10, -instance.w(z, unit='mm'), r'$-w\ (\mathrm{mm})$'],
514
- [x/10, instance.psi(z, unit='degrees'), r'$\psi\ (^\circ)$ '],
561
+ [x / 10, instance.u(z, z0=0, unit="mm"), r"$u_0\ (\mathrm{mm})$"],
562
+ [x / 10, -instance.w(z, unit="mm"), r"$-w\ (\mathrm{mm})$"],
563
+ [x / 10, instance.psi(z, unit="degrees"), r"$\psi\ (^\circ)$ "],
515
564
  ]
516
- plot_data(ax1label=r'Displacements', ax1data=data,
517
- name='disp' + str(i), **segments)
565
+ plot_data(ax1label=r"Displacements", ax1data=data, name="disp" + str(i), **segments)
518
566
 
519
567
 
520
- def section_forces(instance, x, z, i='', **segments):
568
+ def section_forces(instance, x, z, i="", **segments):
521
569
  """Wrap section forces plot."""
522
570
  data = [
523
- [x/10, instance.N(z), r'$N$'],
524
- [x/10, instance.M(z), r'$M$'],
525
- [x/10, instance.V(z), r'$V$']
571
+ [x / 10, instance.N(z), r"$N$"],
572
+ [x / 10, instance.M(z), r"$M$"],
573
+ [x / 10, instance.V(z), r"$V$"],
526
574
  ]
527
- plot_data(ax1label=r'Section forces', ax1data=data,
528
- name='forc' + str(i), **segments)
575
+ plot_data(ax1label=r"Section forces", ax1data=data, name="forc" + str(i), **segments)
529
576
 
530
577
 
531
- def stresses(instance, x, z, i='', **segments):
578
+ def stresses(instance, x, z, i="", **segments):
532
579
  """Wrap stress plot."""
533
580
  data = [
534
- [x/10, instance.tau(z, unit='kPa'), r'$\tau$'],
535
- [x/10, instance.sig(z, unit='kPa'), r'$\sigma$']
581
+ [x / 10, instance.tau(z, unit="kPa"), r"$\tau$"],
582
+ [x / 10, instance.sig(z, unit="kPa"), r"$\sigma$"],
536
583
  ]
537
- plot_data(ax1label=r'Stress (kPa)', ax1data=data,
538
- name='stress' + str(i), **segments)
584
+ plot_data(ax1label=r"Stress (kPa)", ax1data=data, name="stress" + str(i), **segments)
539
585
 
540
586
 
541
587
  def stress_criteria(x, stress, **segments):
542
588
  """Wrap plot of stress and energy criteria."""
543
- data = [
544
- [x/10, stress, r'$\sigma/\sigma_\mathrm{c}$']
545
- ]
546
- plot_data(ax1label=r'Criteria', ax1data=data,
547
- name='crit', **segments)
589
+ data = [[x / 10, stress, r"$\sigma/\sigma_\mathrm{c}$"]]
590
+ plot_data(ax1label=r"Criteria", ax1data=data, name="crit", **segments)
548
591
 
549
592
 
550
593
  def err_comp(da, Gdif, Ginc, mode=0):
551
594
  """Wrap energy release rate plot."""
552
595
  data = [
553
- [da/10, 1e3*Gdif[mode, :], r'$\mathcal{G}$'],
554
- [da/10, 1e3*Ginc[mode, :], r'$\bar{\mathcal{G}}$']
596
+ [da / 10, 1e3 * Gdif[mode, :], r"$\mathcal{G}$"],
597
+ [da / 10, 1e3 * Ginc[mode, :], r"$\bar{\mathcal{G}}$"],
555
598
  ]
556
599
  plot_data(
557
- xlabel=r'Crack length $\Delta a$ (cm)',
558
- ax1label=r'Energy release rate (J/m$^2$)',
559
- ax1data=data, name='err', vlines=False)
600
+ xlabel=r"Crack length $\Delta a$ (cm)",
601
+ ax1label=r"Energy release rate (J/m$^2$)",
602
+ ax1data=data,
603
+ name="err",
604
+ vlines=False,
605
+ )
560
606
 
561
607
 
562
- def err_modes(da, G, kind='inc'):
608
+ def err_modes(da, G, kind="inc"):
563
609
  """Wrap energy release rate plot."""
564
- label = r'$\bar{\mathcal{G}}$' if kind == 'inc' else r'$\mathcal{G}$'
610
+ label = r"$\bar{\mathcal{G}}$" if kind == "inc" else r"$\mathcal{G}$"
565
611
  data = [
566
- [da/10, 1e3*G[2, :], label + r'$_\mathrm{I\!I}$'],
567
- [da/10, 1e3*G[1, :], label + r'$_\mathrm{I}$'],
568
- [da/10, 1e3*G[0, :], label + r'$_\mathrm{I+I\!I}$']
612
+ [da / 10, 1e3 * G[2, :], label + r"$_\mathrm{I\!I}$"],
613
+ [da / 10, 1e3 * G[1, :], label + r"$_\mathrm{I}$"],
614
+ [da / 10, 1e3 * G[0, :], label + r"$_\mathrm{I+I\!I}$"],
569
615
  ]
570
616
  plot_data(
571
- xlabel=r'Crack length $a$ (cm)',
572
- ax1label=r'Energy release rate (J/m$^2$)',
573
- ax1data=data, name='modes', vlines=False)
617
+ xlabel=r"Crack length $a$ (cm)",
618
+ ax1label=r"Energy release rate (J/m$^2$)",
619
+ ax1data=data,
620
+ name="modes",
621
+ vlines=False,
622
+ )
574
623
 
575
624
 
576
625
  def fea_disp(instance, x, z, fea):
577
626
  """Wrap dispalcements plot."""
578
627
  data = [
579
- [fea[:, 0]/10, -np.flipud(fea[:, 1]), r'FEA $u_0$'],
580
- [fea[:, 0]/10, np.flipud(fea[:, 2]), r'FEA $w_0$'],
628
+ [fea[:, 0] / 10, -np.flipud(fea[:, 1]), r"FEA $u_0$"],
629
+ [fea[:, 0] / 10, np.flipud(fea[:, 2]), r"FEA $w_0$"],
581
630
  # [fea[:, 0]/10, -np.flipud(fea[:, 3]), r'FEA $u(z=-h/2)$'],
582
631
  # [fea[:, 0]/10, np.flipud(fea[:, 4]), r'FEA $w(z=-h/2)$'],
583
- [fea[:, 0]/10,
584
- np.flipud(np.rad2deg(fea[:, 5])), r'FEA $\psi$'],
585
- [x/10, instance.u(z, z0=0), r'$u_0$'],
586
- [x/10, -instance.w(z), r'$-w$'],
587
- [x/10, np.rad2deg(instance.psi(z)), r'$\psi$']
632
+ [fea[:, 0] / 10, np.flipud(np.rad2deg(fea[:, 5])), r"FEA $\psi$"],
633
+ [x / 10, instance.u(z, z0=0), r"$u_0$"],
634
+ [x / 10, -instance.w(z), r"$-w$"],
635
+ [x / 10, np.rad2deg(instance.psi(z)), r"$\psi$"],
588
636
  ]
589
637
  plot_data(
590
- ax1label=r'Displacements (mm)', ax1data=data, name='fea_disp',
591
- labelpos=-50)
638
+ ax1label=r"Displacements (mm)", ax1data=data, name="fea_disp", labelpos=-50
639
+ )
592
640
 
593
641
 
594
642
  def fea_stress(instance, xb, zb, fea):
595
643
  """Wrap stress plot."""
596
644
  data = [
597
- [fea[:, 0]/10, 1e3*np.flipud(fea[:, 2]), r'FEA $\sigma_2$'],
598
- [fea[:, 0]/10, 1e3*np.flipud(fea[:, 3]), r'FEA $\tau_{12}$'],
599
- [xb/10, instance.tau(zb, unit='kPa'), r'$\tau$'],
600
- [xb/10, instance.sig(zb, unit='kPa'), r'$\sigma$']
645
+ [fea[:, 0] / 10, 1e3 * np.flipud(fea[:, 2]), r"FEA $\sigma_2$"],
646
+ [fea[:, 0] / 10, 1e3 * np.flipud(fea[:, 3]), r"FEA $\tau_{12}$"],
647
+ [xb / 10, instance.tau(zb, unit="kPa"), r"$\tau$"],
648
+ [xb / 10, instance.sig(zb, unit="kPa"), r"$\sigma$"],
601
649
  ]
602
- plot_data(ax1label=r'Stress (kPa)', ax1data=data, name='fea_stress',
603
- labelpos=-50)
650
+ plot_data(ax1label=r"Stress (kPa)", ax1data=data, name="fea_stress", labelpos=-50)
604
651
 
605
652
 
606
653
  # === SAVE FUNCTION ===========================================================
607
654
 
655
+
608
656
  def save_plot(name):
609
657
  """
610
658
  Show or save plot depending on interpreter
@@ -614,14 +662,14 @@ def save_plot(name):
614
662
  name : string
615
663
  Name for the figure.
616
664
  """
617
- filename = name + '.png'
665
+ filename = name + ".png"
618
666
  # Show figure if on jupyter notebook
619
667
  if isnotebook():
620
668
  plt.show()
621
669
  # Save figure if on terminal
622
670
  else:
623
671
  # Make directory if not yet existing
624
- if not os.path.isdir(os.path.join(os.getcwd(), 'plots')):
625
- os.mkdir('plots')
626
- plt.savefig('plots/' + filename, bbox_inches='tight')
672
+ if not os.path.isdir(os.path.join(os.getcwd(), "plots")):
673
+ os.mkdir("plots")
674
+ plt.savefig("plots/" + filename, bbox_inches="tight")
627
675
  return