IBB-Helper 0.4.8.dev21__tar.gz → 0.4.8.dev22__tar.gz

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 (25) hide show
  1. {ibb_helper-0.4.8.dev21/src/IBB_Helper.egg-info → ibb_helper-0.4.8.dev22}/PKG-INFO +1 -1
  2. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/pyproject.toml +1 -1
  3. ibb_helper-0.4.8.dev22/src/IBB_Helper/plot_2d.py +239 -0
  4. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22/src/IBB_Helper.egg-info}/PKG-INFO +1 -1
  5. ibb_helper-0.4.8.dev21/src/IBB_Helper/plot_2d.py +0 -243
  6. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/LICENSE +0 -0
  7. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/README.md +0 -0
  8. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/setup.cfg +0 -0
  9. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/setup.py +0 -0
  10. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/src/IBB_Helper/__init__.py +0 -0
  11. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/src/IBB_Helper/animate.py +0 -0
  12. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/src/IBB_Helper/combine_plots.py +0 -0
  13. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/src/IBB_Helper/display.py +0 -0
  14. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/src/IBB_Helper/display_eigen.py +0 -0
  15. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/src/IBB_Helper/display_matrix.py +0 -0
  16. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/src/IBB_Helper/extend_plot.py +0 -0
  17. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/src/IBB_Helper/minimize.py +0 -0
  18. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/src/IBB_Helper/num_int.py +0 -0
  19. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/src/IBB_Helper/plot_3d.py +0 -0
  20. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/src/IBB_Helper/plot_param_grid.py +0 -0
  21. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/src/IBB_Helper/symbolic_BSpline.py +0 -0
  22. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/src/IBB_Helper.egg-info/SOURCES.txt +0 -0
  23. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/src/IBB_Helper.egg-info/dependency_links.txt +0 -0
  24. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/src/IBB_Helper.egg-info/requires.txt +0 -0
  25. {ibb_helper-0.4.8.dev21 → ibb_helper-0.4.8.dev22}/src/IBB_Helper.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: IBB_Helper
3
- Version: 0.4.8.dev21
3
+ Version: 0.4.8.dev22
4
4
  Summary: Helper functions for symbolic math, matrix visualization, and plotting
5
5
  Author-email: "University of Stuttgart, Institute for Structural Mechanics (IBB)" <mvs@ibb.uni-stuttgart.de>
6
6
  License-Expression: BSD-3-Clause
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "IBB_Helper"
7
- version = "0.4.8.dev21"
7
+ version = "0.4.8.dev22"
8
8
  description = "Helper functions for symbolic math, matrix visualization, and plotting"
9
9
  readme = "README.md"
10
10
  license = "BSD-3-Clause"
@@ -0,0 +1,239 @@
1
+ import numpy as np
2
+ import sympy as sp
3
+ import matplotlib.pyplot as plt
4
+ from sympy import latex, Matrix
5
+
6
+ def plot_2d(exprs, var, labels=None, line_styles=None, colors=None,
7
+ title=None, xlabel=None, ylabel=None,
8
+ xlim=None, ylim=None, resolution=400, show=True, _break_=None,
9
+ fontsize=14, title_size=None, label_size=None,
10
+ tick_size=None, legend_size=None, linewidth=1,
11
+ swap_axes=False, scaling=None):
12
+
13
+ """
14
+ Plots 2D curves from symbolic expressions or numeric datasets using Matplotlib.
15
+
16
+ Parameters:
17
+ exprs : Expression, tuple, or list of expressions to plot
18
+ var : Symbol or tuple defining the variable and range
19
+ labels : Labels for each curve (default=None)
20
+ line_styles : Line styles or markers for each curve (default=None)
21
+ colors : Colors for each curve (default=None)
22
+ title : Plot title (default=None)
23
+ xlabel : X-axis label (default=None)
24
+ ylabel : Y-axis label (default=None)
25
+ xlim : X-axis limits as (min, max) (default=None)
26
+ ylim : Y-axis limits as (min, max) (default=None)
27
+ resolution : Number of points used to evaluate symbolic expressions (default=400)
28
+ show : Whether to display the plot (default=True)
29
+ _break_ : List of expressions for which discontinuities should be visually broken (default=None)
30
+ fontsize : Base font size for plot text (default=14)
31
+ title_size : Font size for the title (default=None → fontsize+2)
32
+ label_size : Font size for axis labels (default=None → fontsize)
33
+ tick_size : Font size for tick labels (default=None → fontsize-2)
34
+ legend_size : Font size for legend text (default=None → tick_size)
35
+ swap_axes : If True, swaps x and y axes (default=False)
36
+ scaling : 'constrained'→ equal axis units(default=None)
37
+
38
+ Returns:
39
+ matplotlib Axes
40
+ The generated 2D plot axes
41
+ """
42
+
43
+ # 1. Helper: Break visual discontinuities
44
+ def _break_kinks(y_data):
45
+ dy = np.abs(np.diff(y_data))
46
+ max_dy = np.nanmax(dy)
47
+ if max_dy == 0 or np.isnan(max_dy): return y_data
48
+ threshold = max_dy * 0.5
49
+ y_data = y_data.copy()
50
+ for idx in np.where(dy > threshold)[0]:
51
+ y_data[idx] = np.nan
52
+ y_data[idx + 1] = np.nan
53
+ return y_data
54
+
55
+ # 2. Helper: Smart Labels
56
+ def _smart_label(lbl):
57
+ if isinstance(lbl, str):
58
+ if any(c in lbl for c in ['_', '^', '\\']): return f"${lbl}$"
59
+ return lbl
60
+ return f"${latex(lbl)}$"
61
+
62
+ # 3. Sub-function: Handle Parametric Logic
63
+ def _get_parametric_data(expr, x_sym, x_vals_sample):
64
+ """
65
+ Handles:
66
+ 1. (x_expr, y_expr, (t, min, max)) -> Custom range
67
+ 2. (x_expr, y_expr) -> Uses global range
68
+ """
69
+ # Case A: Custom Range (x, y, (t, min, max))
70
+ if len(expr) == 3:
71
+ x_e, y_e, range_info = expr
72
+ t_sym, t_min, t_max = range_info
73
+
74
+ t_vals = np.linspace(float(t_min), float(t_max), resolution)
75
+ f_x = sp.lambdify(t_sym, x_e, modules='numpy')
76
+ f_y = sp.lambdify(t_sym, y_e, modules='numpy')
77
+
78
+ x_res = f_x(t_vals)
79
+ y_res = f_y(t_vals)
80
+
81
+ # Broadcast scalars
82
+ if not hasattr(x_res, '__len__'): x_res = np.full_like(t_vals, x_res)
83
+ if not hasattr(y_res, '__len__'): y_res = np.full_like(t_vals, y_res)
84
+
85
+ return np.array(x_res).flatten(), np.array(y_res).flatten()
86
+
87
+ # Case B: Global Range (x, y)
88
+ elif len(expr) == 2:
89
+ x_data, y_data = expr
90
+
91
+ # Check if symbolic
92
+ if isinstance(x_data, sp.Basic) or isinstance(y_data, sp.Basic):
93
+ f_x = sp.lambdify(x_sym, x_data, modules='numpy')
94
+ f_y = sp.lambdify(x_sym, y_data, modules='numpy')
95
+ x_data = f_x(x_vals_sample)
96
+ y_data = f_y(x_vals_sample)
97
+
98
+ if hasattr(x_data, '__len__') and not hasattr(y_data, '__len__'):
99
+ y_data = np.full_like(x_data, y_data)
100
+ elif not hasattr(x_data, '__len__') and hasattr(y_data, '__len__'):
101
+ x_data = np.full_like(y_data, x_data)
102
+
103
+ # Check for breaks
104
+ if expr in _break_:
105
+ y_data = _break_kinks(y_data)
106
+
107
+ return x_data, y_data
108
+
109
+ return None, None
110
+
111
+ # 4. Sub-function: Handle Standard y=f(x) Logic
112
+ def _get_standard_data(expr, x_sym, x_vals_sample):
113
+ original_expr = expr
114
+ expr = sp.sympify(expr)
115
+
116
+ if not expr.has(x_sym):
117
+ y_vals = np.full_like(x_vals_sample, float(expr))
118
+ else:
119
+ f = sp.lambdify(x_sym, expr, modules='numpy')
120
+ y_vals = np.array(f(x_vals_sample)).flatten()
121
+
122
+ if original_expr in _break_:
123
+ y_vals = _break_kinks(y_vals)
124
+
125
+ return x_vals_sample, y_vals
126
+
127
+ # 5. Sub-function: Apply Padding
128
+ def _apply_padding(ax, all_x, all_y):
129
+ if not all_x or not all_y: return
130
+
131
+ flat_x = np.concatenate([np.atleast_1d(a) for a in all_x])
132
+ flat_y = np.concatenate([np.atleast_1d(a) for a in all_y])
133
+
134
+ min_x, max_x = np.nanmin(flat_x), np.nanmax(flat_x)
135
+ min_y, max_y = np.nanmin(flat_y), np.nanmax(flat_y)
136
+
137
+ pad_x = (max_x - min_x) * 0.1 if max_x != min_x else 0.5
138
+ pad_y = (max_y - min_y) * 0.1 if max_y != min_y else 0.5
139
+
140
+ ax.set_xlim(min_x - pad_x, max_x + pad_x)
141
+ ax.set_ylim(min_y - pad_y, max_y + pad_y)
142
+
143
+ # MAIN EXECUTION
144
+
145
+ # Font/Size Config
146
+ title_size = title_size or fontsize + 2
147
+ label_size = label_size or fontsize
148
+ tick_size = tick_size or fontsize - 2
149
+ legend_size = legend_size or tick_size
150
+
151
+ # Input Normalization
152
+ if not isinstance(exprs, list): exprs = [exprs]
153
+ if _break_ is None: _break_ = []
154
+
155
+ if isinstance(var, tuple):
156
+ x_sym, x_range = var
157
+ else:
158
+ x_sym = var
159
+ x_range = (-1, 1)
160
+
161
+ x_vals_sample = np.linspace(float(x_range[0]), float(x_range[1]), resolution)
162
+
163
+ # Setup Plot
164
+ fig, ax = plt.subplots()
165
+ marker_symbols = ['o', 's', '^', 'x', '*', 'D', 'p', '+', 'v', '<', '>', '1', '2', '3', '4']
166
+
167
+ all_plot_x = []
168
+ all_plot_y = []
169
+
170
+ # Iterate Expressions
171
+ for i, expr in enumerate(exprs):
172
+ # Style extraction
173
+ style = line_styles[i] if line_styles and i < len(line_styles) else 'solid'
174
+ color = colors[i] if colors and i < len(colors) else None
175
+ raw_label = labels[i] if labels and i < len(labels) else None
176
+ label = _smart_label(raw_label) if raw_label is not None else None
177
+
178
+ marker = None
179
+ if isinstance(expr, Matrix):
180
+ expr = np.array(expr).astype(np.float64).flatten()
181
+
182
+ # DISPATCH LOGIC
183
+ final_x = None
184
+ final_y = None
185
+
186
+ # A. Parametric (Tuple/List)
187
+ if isinstance(expr, (tuple, list)):
188
+ final_x, final_y = _get_parametric_data(expr, x_sym, x_vals_sample)
189
+
190
+ # B. Standard (Expression)
191
+ else:
192
+ final_x, final_y = _get_standard_data(expr, x_sym, x_vals_sample)
193
+
194
+ # C. Handle Markers vs Lines
195
+ if style in marker_symbols:
196
+ marker = style
197
+ style = ''
198
+
199
+ # D. Plot & Collect
200
+ if final_x is not None and final_y is not None:
201
+ if swap_axes:
202
+ ax.plot(final_y, final_x, label=label, linestyle=style,
203
+ color=color, marker=marker, linewidth=linewidth)
204
+ all_plot_x.append(final_y)
205
+ all_plot_y.append(final_x)
206
+ else:
207
+ ax.plot(final_x, final_y, label=label, linestyle=style,
208
+ color=color, marker=marker, linewidth=linewidth)
209
+ all_plot_x.append(final_x)
210
+ all_plot_y.append(final_y)
211
+
212
+ # Apply Auto-Padding
213
+ _apply_padding(ax, all_plot_x, all_plot_y)
214
+
215
+ # Final Styling
216
+ if title: ax.set_title(_smart_label(title), fontsize=title_size)
217
+
218
+ if swap_axes:
219
+ if ylabel: ax.set_xlabel(_smart_label(ylabel), fontsize=label_size)
220
+ if xlabel: ax.set_ylabel(_smart_label(xlabel), fontsize=label_size)
221
+ # Apply Manual Limits (Override Padding)
222
+ if ylim: ax.set_xlim(ylim)
223
+ if xlim: ax.set_ylim(xlim)
224
+ else:
225
+ if xlabel: ax.set_xlabel(_smart_label(xlabel), fontsize=label_size)
226
+ if ylabel: ax.set_ylabel(_smart_label(ylabel), fontsize=label_size)
227
+ # Apply Manual Limits (Override Padding)
228
+ if xlim: ax.set_xlim(xlim)
229
+ if ylim: ax.set_ylim(ylim)
230
+
231
+ ax.tick_params(axis='both', labelsize=tick_size)
232
+ if scaling == 'constrained': ax.set_aspect('equal', adjustable='box')
233
+ if labels: ax.legend(fontsize=legend_size)
234
+ ax.grid(True)
235
+
236
+ if show: plt.show()
237
+ else: plt.close()
238
+
239
+ return ax
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: IBB_Helper
3
- Version: 0.4.8.dev21
3
+ Version: 0.4.8.dev22
4
4
  Summary: Helper functions for symbolic math, matrix visualization, and plotting
5
5
  Author-email: "University of Stuttgart, Institute for Structural Mechanics (IBB)" <mvs@ibb.uni-stuttgart.de>
6
6
  License-Expression: BSD-3-Clause
@@ -1,243 +0,0 @@
1
- import numpy as np
2
- import sympy as sp
3
- import matplotlib.pyplot as plt
4
- from sympy import latex, Matrix
5
-
6
- def plot_2d(exprs, var, labels=None, line_styles=None, colors=None,
7
- title=None, xlabel=None, ylabel=None,
8
- xlim=None, ylim=None, resolution=400, show=True, _break_=None,
9
- fontsize=14, title_size=None, label_size=None,
10
- tick_size=None, legend_size=None, linewidth=1,
11
- swap_axes=False, scaling=None):
12
-
13
- """
14
- Plots 2D curves from symbolic expressions or numeric datasets using Matplotlib.
15
-
16
- Parameters:
17
- exprs : Expression, tuple, or list of expressions to plot
18
- var : Symbol or tuple defining the variable and range
19
- labels : Labels for each curve (default=None)
20
- line_styles : Line styles or markers for each curve (default=None)
21
- colors : Colors for each curve (default=None)
22
- title : Plot title (default=None)
23
- xlabel : X-axis label (default=None)
24
- ylabel : Y-axis label (default=None)
25
- xlim : X-axis limits as (min, max) (default=None)
26
- ylim : Y-axis limits as (min, max) (default=None)
27
- resolution : Number of points used to evaluate symbolic expressions (default=400)
28
- show : Whether to display the plot (default=True)
29
- _break_ : List of expressions for which discontinuities should be visually broken (default=None)
30
- fontsize : Base font size for plot text (default=14)
31
- title_size : Font size for the title (default=None → fontsize+2)
32
- label_size : Font size for axis labels (default=None → fontsize)
33
- tick_size : Font size for tick labels (default=None → fontsize-2)
34
- legend_size : Font size for legend text (default=None → tick_size)
35
- swap_axes : If True, swaps x and y axes (default=False)
36
- scaling : 'constrained'→ equal axis units(default=None)
37
-
38
- Returns:
39
- matplotlib Axes
40
- The generated 2D plot axes
41
- """
42
-
43
- # Font size defaults
44
- title_size = title_size or fontsize + 2
45
- label_size = label_size or fontsize
46
- tick_size = tick_size or fontsize - 2
47
- legend_size = legend_size or tick_size
48
-
49
- # Helper functions
50
- def _break_kinks(y_data):
51
- dy = np.abs(np.diff(y_data))
52
- max_dy = np.nanmax(dy)
53
- if max_dy == 0 or np.isnan(max_dy):
54
- return y_data
55
-
56
- threshold = max_dy * 0.5
57
- y_data = y_data.copy()
58
- break_indices = np.where(dy > threshold)[0]
59
- for idx in break_indices:
60
- y_data[idx] = np.nan
61
- y_data[idx + 1] = np.nan
62
- return y_data
63
-
64
- def smart_label(lbl):
65
- if isinstance(lbl, str):
66
- if any(c in lbl for c in ['_', '^', '\\']):
67
- return f"${lbl}$"
68
- return lbl
69
- return f"${latex(lbl)}$"
70
-
71
- # Input normalization
72
- if not isinstance(exprs, list):
73
- exprs = [exprs]
74
-
75
- if _break_ is None:
76
- _break_ = []
77
-
78
- if isinstance(var, tuple):
79
- x_sym, x_range = var
80
- else:
81
- x_sym = var
82
- x_range = (-1, 1)
83
-
84
- x_vals_sample = np.linspace(float(x_range[0]), float(x_range[1]), resolution)
85
-
86
- # Plot setup
87
- fig, ax = plt.subplots()
88
-
89
- marker_symbols = [
90
- 'o', 's', '^', 'x', '*', 'D', 'p', '+',
91
- 'v', '<', '>', '1', '2', '3', '4'
92
- ]
93
-
94
- #Initialize lists to collect all plotted data points
95
- all_plot_x = []
96
- all_plot_y = []
97
-
98
- # Plot expressions
99
- for i, expr in enumerate(exprs):
100
- style = line_styles[i] if line_styles and i < len(line_styles) else 'solid'
101
- color = colors[i] if colors and i < len(colors) else None
102
-
103
- raw_label = labels[i] if labels and i < len(labels) else None
104
- label = smart_label(raw_label) if raw_label is not None else None
105
-
106
- marker = None
107
-
108
- if isinstance(expr, Matrix):
109
- expr = np.array(expr).astype(np.float64).flatten()
110
-
111
- # Variable to hold what we actually plot
112
- final_x_data = None
113
- final_y_data = None
114
-
115
- # Parametric or dataset plot
116
- if isinstance(expr, (tuple, list)) and len(expr) == 2:
117
- x_data, y_data = expr
118
-
119
- if isinstance(x_data, sp.Basic) or isinstance(y_data, sp.Basic):
120
- f_x = sp.lambdify(x_sym, x_data, modules='numpy')
121
- f_y = sp.lambdify(x_sym, y_data, modules='numpy')
122
- x_data = f_x(x_vals_sample)
123
- y_data = f_y(x_vals_sample)
124
-
125
- if hasattr(x_data, '__len__') and not hasattr(y_data, '__len__'):
126
- y_data = np.full_like(x_data, y_data)
127
- elif not hasattr(x_data, '__len__') and hasattr(y_data, '__len__'):
128
- x_data = np.full_like(y_data, x_data)
129
-
130
- if expr in _break_:
131
- y_data = _break_kinks(y_data)
132
-
133
- if style in marker_symbols:
134
- marker = style
135
- style = ''
136
-
137
- # Assign to final variables
138
- final_x_data = x_data
139
- final_y_data = y_data
140
-
141
- # Standard y = f(x)
142
- else:
143
- original_expr = expr
144
- expr = sp.sympify(expr)
145
-
146
- if not expr.has(x_sym):
147
- y_vals = np.full_like(x_vals_sample, float(expr))
148
- else:
149
- f = sp.lambdify(x_sym, expr, modules='numpy')
150
- y_vals = np.array(f(x_vals_sample)).flatten()
151
-
152
- if original_expr in _break_:
153
- y_vals = _break_kinks(y_vals)
154
-
155
- # Assign to final variables
156
- final_x_data = x_vals_sample
157
- final_y_data = y_vals
158
-
159
- # Re-check style for markers (in case it wasn't caught above)
160
- if style in marker_symbols:
161
- marker = style
162
- style = ''
163
-
164
- # Execute Plot & Collect Data
165
- if swap_axes:
166
- ax.plot(
167
- final_y_data, final_x_data,
168
- label=label, linestyle=style, color=color,
169
- marker=marker, linewidth=linewidth
170
- )
171
- #Collect data as it appears on screen (Swapped)
172
- all_plot_x.append(final_y_data)
173
- all_plot_y.append(final_x_data)
174
- else:
175
- ax.plot(
176
- final_x_data, final_y_data,
177
- label=label, linestyle=style, color=color,
178
- marker=marker, linewidth=linewidth
179
- )
180
- #Collect data as it appears on screen (Standard)
181
- all_plot_x.append(final_x_data)
182
- all_plot_y.append(final_y_data)
183
-
184
- #Calculate and apply 10% Padding
185
- if all_plot_x and all_plot_y:
186
- # Concatenate all arrays to find global min/max
187
- # np.atleast_1d ensuresconstant functions don't break concatenation
188
- flat_x = np.concatenate([np.atleast_1d(a) for a in all_plot_x])
189
- flat_y = np.concatenate([np.atleast_1d(a) for a in all_plot_y])
190
-
191
- # Use nanmin/nanmax to ignore gaps from _break_kinks
192
- min_x, max_x = np.nanmin(flat_x), np.nanmax(flat_x)
193
- min_y, max_y = np.nanmin(flat_y), np.nanmax(flat_y)
194
-
195
- # Calculate padding (handle case where max == min)
196
- pad_x = (max_x - min_x) * 0.2 if max_x != min_x else 0.5
197
- pad_y = (max_y - min_y) * 0.2 if max_y != min_y else 0.5
198
-
199
- # Apply padded limits
200
- # These act as the "Auto" default. They will be overwritten below
201
- # if the user specifically provided xlim/ylim arguments.
202
- ax.set_xlim(min_x - pad_x, max_x + pad_x)
203
- ax.set_ylim(min_y - pad_y, max_y + pad_y)
204
-
205
- # Styling & Labels
206
- if title is not None:
207
- ax.set_title(smart_label(title), fontsize=title_size)
208
-
209
- if swap_axes:
210
- if ylabel is not None:
211
- ax.set_xlabel(smart_label(ylabel), fontsize=label_size)
212
- if xlabel is not None:
213
- ax.set_ylabel(smart_label(xlabel), fontsize=label_size)
214
- else:
215
- if xlabel is not None:
216
- ax.set_xlabel(smart_label(xlabel), fontsize=label_size)
217
- if ylabel is not None:
218
- ax.set_ylabel(smart_label(ylabel), fontsize=label_size)
219
-
220
- ax.tick_params(axis='both', labelsize=tick_size)
221
-
222
- # Manual Limits Override (Manual > Auto Padding)
223
- if swap_axes:
224
- if ylim: ax.set_xlim(ylim)
225
- if xlim: ax.set_ylim(xlim)
226
- else:
227
- if xlim: ax.set_xlim(xlim)
228
- if ylim: ax.set_ylim(ylim)
229
-
230
- if scaling == 'constrained':
231
- ax.set_aspect('equal', adjustable='box')
232
-
233
- if labels:
234
- ax.legend(fontsize=legend_size)
235
-
236
- ax.grid(True)
237
-
238
- if show:
239
- plt.show()
240
- else:
241
- plt.close()
242
-
243
- return ax