xslope 0.1.10__py3-none-any.whl → 0.1.11__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.
xslope/_version.py CHANGED
@@ -1,4 +1,4 @@
1
1
  __all__ = ["__version__"]
2
- __version__ = "0.1.10"
2
+ __version__ = "0.1.11"
3
3
 
4
4
 
xslope/plot.py CHANGED
@@ -717,15 +717,14 @@ def plot_reinforcement_lines(ax, slope_data):
717
717
  tension_points_plotted = True
718
718
 
719
719
 
720
- def plot_inputs(slope_data, title="Slope Geometry and Inputs", width=12, height=6, mat_table=True):
720
+ def plot_inputs(slope_data, title="Slope Geometry and Inputs", figsize=(12, 6), mat_table=True, save_png=False, dpi=300):
721
721
  """
722
722
  Creates a plot showing the slope geometry and input parameters.
723
723
 
724
724
  Parameters:
725
725
  slope_data: Dictionary containing plot data
726
726
  title: Title for the plot
727
- width: Width of the plot in inches
728
- height: Height of the plot in inches
727
+ figsize: Tuple of (width, height) in inches for the plot
729
728
  mat_table: Controls material table display. Can be:
730
729
  - True: Auto-position material table to avoid overlaps
731
730
  - False: Don't show material table
@@ -736,7 +735,7 @@ def plot_inputs(slope_data, title="Slope Geometry and Inputs", width=12, height=
736
735
  Returns:
737
736
  None
738
737
  """
739
- fig, ax = plt.subplots(figsize=(width, height))
738
+ fig, ax = plt.subplots(figsize=figsize)
740
739
 
741
740
  # Plot contents
742
741
  plot_profile_lines(ax, slope_data['profile_lines'])
@@ -803,11 +802,16 @@ def plot_inputs(slope_data, title="Slope Geometry and Inputs", width=12, height=
803
802
  ax.set_title(title)
804
803
 
805
804
  plt.tight_layout()
805
+
806
+ if save_png:
807
+ filename = 'plot_' + title.lower().replace(' ', '_').replace(':', '').replace(',', '') + '.png'
808
+ plt.savefig(filename, dpi=dpi, bbox_inches='tight')
809
+
806
810
  plt.show()
807
811
 
808
812
  # ========== Main Plotting Function =========
809
813
 
810
- def plot_solution(slope_data, slice_df, failure_surface, results, width=12, height=7, slice_numbers=False):
814
+ def plot_solution(slope_data, slice_df, failure_surface, results, figsize=(12, 7), slice_numbers=False, save_png=False, dpi=300):
811
815
  """
812
816
  Plots the full solution including slices, numbers, thrust line, and base stresses.
813
817
 
@@ -816,13 +820,12 @@ def plot_solution(slope_data, slice_df, failure_surface, results, width=12, heig
816
820
  slice_df: DataFrame containing slice data
817
821
  failure_surface: Failure surface geometry
818
822
  results: Solution results
819
- width: Width of the plot in inches
820
- height: Height of the plot in inches
823
+ figsize: Tuple of (width, height) in inches for the plot
821
824
 
822
825
  Returns:
823
826
  None
824
827
  """
825
- fig, ax = plt.subplots(figsize=(width, height))
828
+ fig, ax = plt.subplots(figsize=figsize)
826
829
  ax.set_xlabel("x")
827
830
  ax.set_ylabel("y")
828
831
  ax.grid(False)
@@ -896,6 +899,11 @@ def plot_solution(slope_data, slice_df, failure_surface, results, width=12, heig
896
899
  ax.set_ylim(ymin, ymax)
897
900
 
898
901
  plt.tight_layout()
902
+
903
+ if save_png:
904
+ filename = 'plot_' + title.lower().replace(' ', '_').replace(':', '').replace(',', '').replace('°', 'deg') + '.png'
905
+ plt.savefig(filename, dpi=dpi, bbox_inches='tight')
906
+
899
907
  plt.show()
900
908
 
901
909
  # ========== Functions for Search Results =========
@@ -956,7 +964,7 @@ def plot_search_path(ax, search_path):
956
964
  ax.arrow(start['x'], start['y'], dx, dy,
957
965
  head_width=1, head_length=2, fc='green', ec='green', length_includes_head=True)
958
966
 
959
- def plot_circular_search_results(slope_data, fs_cache, search_path=None, highlight_fs=True, width=12, height=7):
967
+ def plot_circular_search_results(slope_data, fs_cache, search_path=None, highlight_fs=True, figsize=(12, 7), save_png=False, dpi=300):
960
968
  """
961
969
  Creates a plot showing the results of a circular failure surface search.
962
970
 
@@ -965,13 +973,12 @@ def plot_circular_search_results(slope_data, fs_cache, search_path=None, highlig
965
973
  fs_cache: List of dictionaries containing failure surface data and FS values
966
974
  search_path: List of dictionaries containing search path coordinates
967
975
  highlight_fs: Boolean indicating whether to highlight the critical failure surface
968
- width: Width of the plot in inches
969
- height: Height of the plot in inches
976
+ figsize: Tuple of (width, height) in inches for the plot
970
977
 
971
978
  Returns:
972
979
  None
973
980
  """
974
- fig, ax = plt.subplots(figsize=(width, height))
981
+ fig, ax = plt.subplots(figsize=figsize)
975
982
 
976
983
  plot_profile_lines(ax, slope_data['profile_lines'])
977
984
  plot_max_depth(ax, slope_data['profile_lines'], slope_data['max_depth'])
@@ -995,9 +1002,14 @@ def plot_circular_search_results(slope_data, fs_cache, search_path=None, highlig
995
1002
  ax.set_title(f"Critical Factor of Safety = {critical_fs:.3f}")
996
1003
 
997
1004
  plt.tight_layout()
1005
+
1006
+ if save_png:
1007
+ filename = 'plot_circular_search_results.png'
1008
+ plt.savefig(filename, dpi=dpi, bbox_inches='tight')
1009
+
998
1010
  plt.show()
999
1011
 
1000
- def plot_noncircular_search_results(slope_data, fs_cache, search_path=None, highlight_fs=True, width=12, height=7):
1012
+ def plot_noncircular_search_results(slope_data, fs_cache, search_path=None, highlight_fs=True, figsize=(12, 7), save_png=False, dpi=300):
1001
1013
  """
1002
1014
  Creates a plot showing the results of a non-circular failure surface search.
1003
1015
 
@@ -1006,13 +1018,12 @@ def plot_noncircular_search_results(slope_data, fs_cache, search_path=None, high
1006
1018
  fs_cache: List of dictionaries containing failure surface data and FS values
1007
1019
  search_path: List of dictionaries containing search path coordinates
1008
1020
  highlight_fs: Boolean indicating whether to highlight the critical failure surface
1009
- width: Width of the plot in inches
1010
- height: Height of the plot in inches
1021
+ figsize: Tuple of (width, height) in inches for the plot
1011
1022
 
1012
1023
  Returns:
1013
1024
  None
1014
1025
  """
1015
- fig, ax = plt.subplots(figsize=(width, height))
1026
+ fig, ax = plt.subplots(figsize=figsize)
1016
1027
 
1017
1028
  # Plot basic profile elements
1018
1029
  plot_profile_lines(ax, slope_data['profile_lines'])
@@ -1060,22 +1071,26 @@ def plot_noncircular_search_results(slope_data, fs_cache, search_path=None, high
1060
1071
  ax.set_title(f"Critical Factor of Safety = {critical_fs:.3f}")
1061
1072
 
1062
1073
  plt.tight_layout()
1074
+
1075
+ if save_png:
1076
+ filename = 'plot_noncircular_search_results.png'
1077
+ plt.savefig(filename, dpi=dpi, bbox_inches='tight')
1078
+
1063
1079
  plt.show()
1064
1080
 
1065
- def plot_reliability_results(slope_data, reliability_data, width=12, height=7):
1081
+ def plot_reliability_results(slope_data, reliability_data, figsize=(12, 7), save_png=False, dpi=300):
1066
1082
  """
1067
1083
  Creates a plot showing the results of reliability analysis.
1068
1084
 
1069
1085
  Parameters:
1070
1086
  slope_data: Dictionary containing plot data
1071
1087
  reliability_data: Dictionary containing reliability analysis results
1072
- width: Width of the plot in inches
1073
- height: Height of the plot in inches
1088
+ figsize: Tuple of (width, height) in inches for the plot
1074
1089
 
1075
1090
  Returns:
1076
1091
  None
1077
1092
  """
1078
- fig, ax = plt.subplots(figsize=(width, height))
1093
+ fig, ax = plt.subplots(figsize=figsize)
1079
1094
 
1080
1095
  # Plot basic slope elements (same as other search functions)
1081
1096
  plot_profile_lines(ax, slope_data['profile_lines'])
@@ -1143,9 +1158,14 @@ def plot_reliability_results(slope_data, reliability_data, width=12, height=7):
1143
1158
  f"Reliability = {reliability*100:.2f}%, $P_f$ = {prob_failure*100:.2f}%")
1144
1159
 
1145
1160
  plt.tight_layout()
1161
+
1162
+ if save_png:
1163
+ filename = 'plot_reliability_results.png'
1164
+ plt.savefig(filename, dpi=dpi, bbox_inches='tight')
1165
+
1146
1166
  plt.show()
1147
1167
 
1148
- def plot_mesh(mesh, materials=None, figsize=(14, 6), pad_frac=0.05, show_nodes=True, label_elements=False, label_nodes=False):
1168
+ def plot_mesh(mesh, materials=None, figsize=(14, 6), pad_frac=0.05, show_nodes=True, label_elements=False, label_nodes=False, save_png=False, dpi=300):
1149
1169
  """
1150
1170
  Plot the finite element mesh with material regions.
1151
1171
 
@@ -1332,10 +1352,15 @@ def plot_mesh(mesh, materials=None, figsize=(14, 6), pad_frac=0.05, show_nodes=T
1332
1352
  ax.set_ylim(y_min - y_pad, y_max + y_pad)
1333
1353
 
1334
1354
  plt.tight_layout()
1355
+
1356
+ if save_png:
1357
+ filename = 'plot_mesh.png'
1358
+ plt.savefig(filename, dpi=dpi, bbox_inches='tight')
1359
+
1335
1360
  plt.show()
1336
1361
 
1337
1362
 
1338
- def plot_polygons(polygons, title="Material Zone Polygons"):
1363
+ def plot_polygons(polygons, title="Material Zone Polygons", save_png=False, dpi=300):
1339
1364
  """
1340
1365
  Plot all material zone polygons in a single figure.
1341
1366
 
@@ -1358,10 +1383,15 @@ def plot_polygons(polygons, title="Material Zone Polygons"):
1358
1383
  ax.grid(True, alpha=0.3)
1359
1384
  ax.set_aspect('equal')
1360
1385
  plt.tight_layout()
1386
+
1387
+ if save_png:
1388
+ filename = 'plot_' + title.lower().replace(' ', '_').replace(':', '').replace(',', '') + '.png'
1389
+ plt.savefig(filename, dpi=dpi, bbox_inches='tight')
1390
+
1361
1391
  plt.show()
1362
1392
 
1363
1393
 
1364
- def plot_polygons_separately(polygons, title_prefix='Material Zone'):
1394
+ def plot_polygons_separately(polygons, title_prefix='Material Zone', save_png=False, dpi=300):
1365
1395
  """
1366
1396
  Plot each polygon in a separate matplotlib frame (subplot), with vertices as round dots.
1367
1397
 
@@ -1387,6 +1417,11 @@ def plot_polygons_separately(polygons, title_prefix='Material Zone'):
1387
1417
  ax.set_aspect('equal')
1388
1418
  ax.legend()
1389
1419
  plt.tight_layout()
1420
+
1421
+ if save_png:
1422
+ filename = 'plot_' + title_prefix.lower().replace(' ', '_').replace(':', '').replace(',', '') + '_separate.png'
1423
+ plt.savefig(filename, dpi=dpi, bbox_inches='tight')
1424
+
1390
1425
  plt.show()
1391
1426
 
1392
1427
 
xslope/plot_fem.py CHANGED
@@ -23,7 +23,7 @@ from matplotlib.patches import Polygon
23
23
 
24
24
 
25
25
  def plot_fem_data(fem_data, figsize=(14, 6), show_nodes=False, show_bc=True, material_table=False,
26
- label_elements=False, label_nodes=False, alpha=0.4, bc_symbol_size=0.03):
26
+ label_elements=False, label_nodes=False, alpha=0.4, bc_symbol_size=0.03, save_png=False, dpi=300):
27
27
  """
28
28
  Plots a FEM mesh colored by material zone with boundary conditions displayed.
29
29
 
@@ -251,6 +251,11 @@ def plot_fem_data(fem_data, figsize=(14, 6), show_nodes=False, show_bc=True, mat
251
251
 
252
252
  ax.set_title(title)
253
253
  plt.tight_layout()
254
+
255
+ if save_png:
256
+ filename = 'plot_' + title.lower().replace(' ', '_').replace(':', '').replace(',', '').replace('(', '').replace(')', '') + '.png'
257
+ plt.savefig(filename, dpi=dpi, bbox_inches='tight')
258
+
254
259
  plt.show()
255
260
 
256
261
 
@@ -427,7 +432,7 @@ def _plot_fem_material_table(ax, fem_data, xloc=0.6, yloc=0.7):
427
432
  def plot_fem_results(fem_data, solution, plot_type='displacement', deform_scale=None,
428
433
  show_mesh=True, show_reinforcement=True, figsize=(12, 8), label_elements=False,
429
434
  plot_nodes=False, plot_elements=False, plot_boundary=True, displacement_tolerance=0.5,
430
- scale_vectors=False):
435
+ scale_vectors=False, save_png=False, dpi=300):
431
436
  """
432
437
  Plot FEM results with various visualization options.
433
438
 
@@ -540,6 +545,11 @@ def plot_fem_results(fem_data, solution, plot_type='displacement', deform_scale=
540
545
  ax.set_aspect('equal')
541
546
 
542
547
  plt.tight_layout()
548
+
549
+ if save_png:
550
+ filename = f'plot_fem_results_{plot_type.lower().replace(",", "_").replace(" ", "_")}.png'
551
+ plt.savefig(filename, dpi=dpi, bbox_inches='tight')
552
+
543
553
  plt.show()
544
554
 
545
555
  # Return appropriate values
@@ -1071,7 +1081,7 @@ def plot_reinforcement_forces(ax, fem_data, solution):
1071
1081
  ax.add_collection(lc_failed)
1072
1082
 
1073
1083
 
1074
- def plot_reinforcement_force_profiles(fem_data, solution, figsize=(12, 8)):
1084
+ def plot_reinforcement_force_profiles(fem_data, solution, figsize=(12, 8), save_png=False, dpi=300):
1075
1085
  """
1076
1086
  Plot force profiles along each reinforcement line.
1077
1087
  """
@@ -1170,10 +1180,15 @@ def plot_reinforcement_force_profiles(fem_data, solution, figsize=(12, 8)):
1170
1180
  axes[i].set_visible(False)
1171
1181
 
1172
1182
  plt.tight_layout()
1183
+
1184
+ if save_png:
1185
+ filename = 'plot_reinforcement_force_profiles.png'
1186
+ plt.savefig(filename, dpi=dpi, bbox_inches='tight')
1187
+
1173
1188
  return fig, axes
1174
1189
 
1175
1190
 
1176
- def plot_ssrm_convergence(ssrm_solution, figsize=(10, 6)):
1191
+ def plot_ssrm_convergence(ssrm_solution, figsize=(10, 6), save_png=False, dpi=300):
1177
1192
  """
1178
1193
  Plot SSRM convergence history.
1179
1194
  """
@@ -1214,6 +1229,11 @@ def plot_ssrm_convergence(ssrm_solution, figsize=(10, 6)):
1214
1229
  ax2.grid(True, alpha=0.3)
1215
1230
 
1216
1231
  plt.tight_layout()
1232
+
1233
+ if save_png:
1234
+ filename = 'plot_ssrm_convergence.png'
1235
+ plt.savefig(filename, dpi=dpi, bbox_inches='tight')
1236
+
1217
1237
  return fig, (ax1, ax2)
1218
1238
 
1219
1239
 
xslope/plot_seep.py CHANGED
@@ -4,7 +4,7 @@ from matplotlib.ticker import MaxNLocator
4
4
  import numpy as np
5
5
 
6
6
 
7
- def plot_seep_data(seep_data, figsize=(14, 6), show_nodes=False, show_bc=False, material_table=False, label_elements=False, label_nodes=False, alpha=0.4):
7
+ def plot_seep_data(seep_data, figsize=(14, 6), show_nodes=False, show_bc=False, material_table=False, label_elements=False, label_nodes=False, alpha=0.4, save_png=False, dpi=300):
8
8
  """
9
9
  Plots a mesh colored by material zone.
10
10
  Supports both triangular and quadrilateral elements.
@@ -214,10 +214,15 @@ def plot_seep_data(seep_data, figsize=(14, 6), show_nodes=False, show_bc=False,
214
214
  ax.set_title(title)
215
215
  # plt.subplots_adjust(bottom=0.2) # Add vertical cushion
216
216
  plt.tight_layout()
217
+
218
+ if save_png:
219
+ filename = 'plot_' + title.lower().replace(' ', '_').replace(':', '').replace(',', '').replace('(', '').replace(')', '') + '.png'
220
+ plt.savefig(filename, dpi=dpi, bbox_inches='tight')
221
+
217
222
  plt.show()
218
223
 
219
224
 
220
- def plot_seep_solution(seep_data, solution, figsize=(14, 6), levels=20, base_mat=1, fill_contours=True, phreatic=True, alpha=0.4, pad_frac=0.05, mesh=True, variable="head", vectors=False, vector_scale=0.05, flowlines=True):
225
+ def plot_seep_solution(seep_data, solution, figsize=(14, 6), levels=20, base_mat=1, fill_contours=True, phreatic=True, alpha=0.4, pad_frac=0.05, mesh=True, variable="head", vectors=False, vector_scale=0.05, flowlines=True, save_png=False, dpi=300):
221
226
  """
222
227
  Plot seepage analysis results including head contours, flowlines, and phreatic surface.
223
228
 
@@ -579,6 +584,11 @@ def plot_seep_solution(seep_data, solution, figsize=(14, 6), levels=20, base_mat
579
584
  # Remove tight_layout and subplots_adjust for best constrained layout
580
585
  # plt.tight_layout()
581
586
  # plt.subplots_adjust(top=0.78)
587
+
588
+ if save_png:
589
+ filename = 'plot_' + title.lower().replace(' ', '_').replace(':', '').replace(',', '').replace('—', '').replace('(', '').replace(')', '') + '.png'
590
+ plt.savefig(filename, dpi=dpi, bbox_inches='tight')
591
+
582
592
  plt.show()
583
593
 
584
594
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: xslope
3
- Version: 0.1.10
3
+ Version: 0.1.11
4
4
  Summary: Slope stability analysis (limit equilibrium and FEM) in Python.
5
5
  Author: Norman L. Jones
6
6
  Project-URL: Homepage, https://github.com/njones61/xslope
@@ -1,21 +1,21 @@
1
1
  xslope/__init__.py,sha256=ZygAIkX6Nbjag1czWdQa-yP-GM1mBE_9ss21Xh__JFc,34
2
- xslope/_version.py,sha256=DfeCqc-dgdypmy58WabEWmjpVnqKiY50hCCECclU5_I,51
2
+ xslope/_version.py,sha256=EuS8ourwvf_O1n08GOG1eXlKDKt7dguYQ663MaapOxQ,51
3
3
  xslope/advanced.py,sha256=35k_ekQJ-mQJ1wHnoIHMc5TVfYn-2EPCJyHz827Cpbc,18281
4
4
  xslope/fem.py,sha256=K4_Pq06HFBpRkN3JwtXF2zw_AMnCkXvj0ggrlRFMQQw,115731
5
5
  xslope/fileio.py,sha256=DnFUYmJedjKXOuVPZUfTRxGfTjiIz8KyHkRDK7ddQg0,28840
6
6
  xslope/global_config.py,sha256=Cj8mbPidIuj5Ty-5cZM-c8H12kNvyHsk5_ofNGez-3M,2253
7
7
  xslope/mesh copy.py,sha256=qtMH1yKFgHM4kNuIrxco7tKV86R3Dbf7Nok5j6MtlLY,131013
8
8
  xslope/mesh.py,sha256=qtMH1yKFgHM4kNuIrxco7tKV86R3Dbf7Nok5j6MtlLY,131013
9
- xslope/plot.py,sha256=OW2eZyrT5h3Y95qjNFgGMnC_Am7TurUB2S7b_BgnO6E,54641
10
- xslope/plot_fem.py,sha256=al9zjqjxWKooLl4SAds77Zz-j9cjD4TJGygyU9QK5vo,71111
11
- xslope/plot_seep.py,sha256=Fs8S-0_7bnNJZlj7SnM0ij1mFDZWlNjXGnP6iMDiplY,34647
9
+ xslope/plot.py,sha256=MexmrZJ1CVSnG0ZN3lNz67DyQdDTdO6hLlbTTBYz4Zw,56016
10
+ xslope/plot_fem.py,sha256=WiFFt9cUIRwX1uCiJrPaMtmhz5LfhZnzNVJwhp0fMP8,71902
11
+ xslope/plot_seep.py,sha256=ep9spY2DiMvOJELccBAj77p9HTnBRgoyqQ_brQphWHw,35166
12
12
  xslope/search.py,sha256=dvgKn8JCobuvyD7fClF5lcbeHESCvV8gZ_U_lQnYRok,16867
13
13
  xslope/seep.py,sha256=tLvme-eL0R5SGGTH2Y6z4Rrfe36UuSWWLlL_1kglee8,93030
14
14
  xslope/slice.py,sha256=QHawTk7XPLziHoN_ZS0jrEPYKlhPT62caUc_q-_EGjs,45236
15
15
  xslope/solve.py,sha256=u_sBjtsj1EeZtgSEmo80tEWoRrrMgvRjmi6P0ODO1lU,48645
16
- xslope-0.1.10.dist-info/LICENSE,sha256=NU5J88FUai_4Ixu5DqOQukA-gcXAyX8pXLhIg8OB3AM,10969
17
- xslope-0.1.10.dist-info/METADATA,sha256=-iSQGoUnwIJgNg0sZizK2iZk6JRVarH5mDMpUxsFSgI,2028
18
- xslope-0.1.10.dist-info/NOTICE,sha256=E-sbN0MWwvJC27Z-2_G4VUHIx4IsfvLDTmOstvY4-OQ,530
19
- xslope-0.1.10.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
20
- xslope-0.1.10.dist-info/top_level.txt,sha256=5qHbWJ1R2pdTNIainFyrVtFk8R1tRcwIn0kzTuwuV1Q,7
21
- xslope-0.1.10.dist-info/RECORD,,
16
+ xslope-0.1.11.dist-info/LICENSE,sha256=NU5J88FUai_4Ixu5DqOQukA-gcXAyX8pXLhIg8OB3AM,10969
17
+ xslope-0.1.11.dist-info/METADATA,sha256=ZbDxeZ2g25EwvsZDdbQIhwRB5eOu-LSpeFYmcFn0nUk,2028
18
+ xslope-0.1.11.dist-info/NOTICE,sha256=E-sbN0MWwvJC27Z-2_G4VUHIx4IsfvLDTmOstvY4-OQ,530
19
+ xslope-0.1.11.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
20
+ xslope-0.1.11.dist-info/top_level.txt,sha256=5qHbWJ1R2pdTNIainFyrVtFk8R1tRcwIn0kzTuwuV1Q,7
21
+ xslope-0.1.11.dist-info/RECORD,,