IBB-Helper 0.4.8.dev23__tar.gz → 0.4.8.dev24__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 (24) hide show
  1. {ibb_helper-0.4.8.dev23/src/IBB_Helper.egg-info → ibb_helper-0.4.8.dev24}/PKG-INFO +1 -1
  2. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/pyproject.toml +1 -1
  3. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/src/IBB_Helper/combine_plots.py +95 -82
  4. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24/src/IBB_Helper.egg-info}/PKG-INFO +1 -1
  5. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/LICENSE +0 -0
  6. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/README.md +0 -0
  7. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/setup.cfg +0 -0
  8. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/setup.py +0 -0
  9. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/src/IBB_Helper/__init__.py +0 -0
  10. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/src/IBB_Helper/animate.py +0 -0
  11. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/src/IBB_Helper/display.py +0 -0
  12. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/src/IBB_Helper/display_eigen.py +0 -0
  13. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/src/IBB_Helper/display_matrix.py +0 -0
  14. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/src/IBB_Helper/extend_plot.py +0 -0
  15. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/src/IBB_Helper/minimize.py +0 -0
  16. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/src/IBB_Helper/num_int.py +0 -0
  17. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/src/IBB_Helper/plot_2d.py +0 -0
  18. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/src/IBB_Helper/plot_3d.py +0 -0
  19. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/src/IBB_Helper/plot_param_grid.py +0 -0
  20. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/src/IBB_Helper/symbolic_BSpline.py +0 -0
  21. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/src/IBB_Helper.egg-info/SOURCES.txt +0 -0
  22. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/src/IBB_Helper.egg-info/dependency_links.txt +0 -0
  23. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/src/IBB_Helper.egg-info/requires.txt +0 -0
  24. {ibb_helper-0.4.8.dev23 → ibb_helper-0.4.8.dev24}/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.dev23
3
+ Version: 0.4.8.dev24
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.dev23"
7
+ version = "0.4.8.dev24"
8
8
  description = "Helper functions for symbolic math, matrix visualization, and plotting"
9
9
  readme = "README.md"
10
10
  license = "BSD-3-Clause"
@@ -1,10 +1,11 @@
1
1
  import matplotlib.pyplot as plt
2
2
  import plotly.graph_objects as go
3
3
  import copy
4
+ import numpy as np
4
5
 
5
6
  def combine_plots(plot_list, labels=None, line_styles=None, colors=None,
6
- swap_axes=False, show=True, grid=False,
7
- xlim=None, ylim=None, title=None, xlabel=None, ylabel=None,width=800, height=700):
7
+ swap_axes=False, show=True, grid=False,
8
+ xlim=None, ylim=None, title=None, xlabel=None, ylabel=None, width=800, height=700):
8
9
  """
9
10
  Combines multiple Matplotlib Axes or Plotly Figures into a single plot while preserving styles.
10
11
 
@@ -21,69 +22,80 @@ def combine_plots(plot_list, labels=None, line_styles=None, colors=None,
21
22
  title : Plot title (default=None)
22
23
  xlabel : X-axis label (default=None)
23
24
  ylabel : Y-axis label (default=None)
25
+ width : width of the Plotly (default=800)
26
+ height : height of the Plotly (default=700)
24
27
 
25
28
  Returns:
26
29
  matplotlib Axes or plotly.graph_objects.Figure
27
30
  The combined plot object, matching the input plot type
28
31
  """
29
-
30
-
31
- if not plot_list:
32
- raise ValueError("plot_list cannot be empty")
33
-
34
- first_plot = plot_list[0]
35
32
 
36
- # Define marker symbols for internal check (same list used in plot_2d)
37
- marker_symbols = ['o', 's', '^', 'x', '*', 'D', 'p', '+', 'v', '<', '>', '1', '2', '3', '4']
33
+ # Apply Padding (Matplotlib)
34
+ def _apply_padding(ax, all_x, all_y):
35
+ if not all_x or not all_y:
36
+ return
37
+
38
+ # Concatenate all arrays to find global min/max
39
+ flat_x = np.concatenate([np.atleast_1d(a) for a in all_x])
40
+ flat_y = np.concatenate([np.atleast_1d(a) for a in all_y])
41
+
42
+ # Use nanmin/nanmax to ignore NaNs
43
+ min_x, max_x = np.nanmin(flat_x), np.nanmax(flat_x)
44
+ min_y, max_y = np.nanmin(flat_y), np.nanmax(flat_y)
38
45
 
39
- # === MATPLOTLIB AXES HANDLING ===
40
- if hasattr(first_plot, 'lines'):
46
+ # Calculate padding (handle case where max == min)
47
+ pad_x = (max_x - min_x) * 0.1 if max_x != min_x else 0.5
48
+ pad_y = (max_y - min_y) * 0.1 if max_y != min_y else 0.5
49
+
50
+ # Apply padded limits (These act as defaults, overridden by user limits later)
51
+ ax.set_xlim(min_x - pad_x, max_x + pad_x)
52
+ ax.set_ylim(min_y - pad_y, max_y + pad_y)
53
+
54
+ # Matplotlib Handler
55
+ def _handle_matplotlib(plot_list):
41
56
  fig, ax = plt.subplots()
57
+ marker_symbols = ['o', 's', '^', 'x', '*', 'D', 'p', '+', 'v', '<', '>', '1', '2', '3', '4']
42
58
 
59
+ # Lists to collect data for padding calculation
60
+ all_plot_x = []
61
+ all_plot_y = []
62
+
43
63
  for i, plot_ax in enumerate(plot_list):
44
64
  first_line = True
45
65
 
46
66
  for line in plot_ax.lines:
47
67
  x, y = line.get_data()
48
68
 
49
- # --- 1. Retrieve Existing Properties (Default Transfer) ---
69
+ # Retrieve Existing Properties
50
70
  current_color = line.get_color()
51
71
  current_marker = line.get_marker()
52
72
  current_linestyle = line.get_linestyle()
53
73
  current_markersize = line.get_markersize()
54
74
  current_linewidth = line.get_linewidth()
55
75
 
56
- # Normalize marker: Convert 'None' string to None
57
- if current_marker in ['None', '']:
58
- current_marker = None
59
-
60
- # Normalize linestyle: Matplotlib stores '' for marker-only plots
61
- if current_linestyle in ['None', '']:
62
- current_linestyle = 'None'
63
-
64
- # --- 2. Apply Overrides from append_plots Arguments (Only for First Line) ---
76
+ # Normalize marker/linestyle
77
+ if current_marker in ['None', '']: current_marker = None
78
+ if current_linestyle in ['None', '']: current_linestyle = 'None'
79
+
80
+ # Apply Overrides (Only for First Line of the plot)
65
81
  if first_line:
66
- # Override Line Style / Marker
82
+ # Style Override
67
83
  if line_styles and i < len(line_styles):
68
84
  new_style = line_styles[i]
69
-
70
85
  if new_style in marker_symbols:
71
- # Case A: User forces a marker (e.g., 'o', 'x')
72
86
  current_marker = new_style
73
- current_linestyle = 'None' # Ensure linestyle is off
87
+ current_linestyle = 'None'
74
88
  else:
75
- # Case B: User forces a line style (e.g., '--', 'solid')
76
89
  current_linestyle = new_style
77
- current_marker = None # Clear the marker
90
+ current_marker = None
78
91
 
79
- # Override Color
92
+ # Color Override
80
93
  if colors and i < len(colors):
81
94
  current_color = colors[i]
82
95
 
83
- # Apply label only to the first line of the current plot_ax
84
96
  label_to_use = labels[i] if first_line and labels and i < len(labels) else None
85
97
 
86
- # --- 3. Plot on the New Axes ---
98
+ # Plot on New Axes
87
99
  if swap_axes:
88
100
  ax.plot(y, x,
89
101
  color=current_color,
@@ -92,6 +104,9 @@ def combine_plots(plot_list, labels=None, line_styles=None, colors=None,
92
104
  markersize=current_markersize,
93
105
  linewidth=current_linewidth,
94
106
  label=label_to_use)
107
+ # Collect data for padding (Swapped)
108
+ all_plot_x.append(y)
109
+ all_plot_y.append(x)
95
110
  else:
96
111
  ax.plot(x, y,
97
112
  color=current_color,
@@ -100,92 +115,90 @@ def combine_plots(plot_list, labels=None, line_styles=None, colors=None,
100
115
  markersize=current_markersize,
101
116
  linewidth=current_linewidth,
102
117
  label=label_to_use)
118
+ # Collect data for padding (Standard)
119
+ all_plot_x.append(x)
120
+ all_plot_y.append(y)
103
121
 
104
122
  first_line = False
105
-
106
- # --- 4. Final Axis/Figure Configuration (Matplotlib) ---
107
- if xlim:
108
- ax.set_xlim(xlim)
109
- if ylim:
110
- ax.set_ylim(ylim)
111
- if title:
112
- ax.set_title(title)
113
- if xlabel:
114
- ax.set_xlabel(xlabel)
115
- if ylabel:
116
- ax.set_ylabel(ylabel)
117
- if grid:
118
- ax.grid()
119
- if labels:
120
- ax.legend()
123
+
124
+ # Apply 10% Padding
125
+ _apply_padding(ax, all_plot_x, all_plot_y)
126
+
127
+ # Final Config
128
+ if xlim: ax.set_xlim(xlim)
129
+ if ylim: ax.set_ylim(ylim)
130
+ if title: ax.set_title(title)
131
+ if xlabel: ax.set_xlabel(xlabel)
132
+ if ylabel: ax.set_ylabel(ylabel)
133
+ if grid: ax.grid(True)
134
+ if labels: ax.legend()
135
+
121
136
  if show:
122
137
  plt.show()
123
138
  else:
124
139
  plt.close()
125
-
140
+
126
141
  return ax
127
142
 
128
- # === PLOTLY FIGURE HANDLING ===
129
- elif hasattr(first_plot, 'data'):
143
+ # Plotly Handler
144
+ def _handle_plotly(plot_list):
130
145
  combined_fig = go.Figure()
131
146
 
132
147
  for i, fig in enumerate(plot_list):
133
148
  for trace in fig.data:
134
- # Use deepcopy for safe cloning of the trace
135
149
  new_trace = copy.deepcopy(trace)
136
150
 
137
- # Apply colors if provided and trace supports it
151
+ # Color Override
138
152
  if colors and i < len(colors):
139
- if hasattr(new_trace, 'line'):
140
- new_trace.line.color = colors[i]
141
- if hasattr(new_trace, 'marker'):
142
- new_trace.marker.color = colors[i]
153
+ if hasattr(new_trace, 'line'): new_trace.line.color = colors[i]
154
+ if hasattr(new_trace, 'marker'): new_trace.marker.color = colors[i]
143
155
 
144
- # Apply line styles (dash) if provided
156
+ # Style Override
145
157
  if line_styles and i < len(line_styles):
146
158
  if isinstance(new_trace, go.Scatter) and hasattr(new_trace, 'line'):
147
159
  new_trace.line.dash = line_styles[i]
148
160
 
149
- # Apply labels/name
161
+ # Label Override
150
162
  if labels and i < len(labels):
151
163
  new_trace.name = labels[i]
152
164
 
153
- # Handle Axis Swap (if requested)
165
+ # Swap Axes
154
166
  if swap_axes and hasattr(new_trace, 'x') and hasattr(new_trace, 'y'):
155
167
  new_trace.x, new_trace.y = new_trace.y, new_trace.x
156
168
 
157
169
  combined_fig.add_trace(new_trace)
158
170
 
159
- # Final Layout Configuration (Plotly)
160
- if title:
161
- combined_fig.update_layout(title=title)
162
- if xlabel or ylabel:
163
- combined_fig.update_layout(xaxis_title=xlabel if xlabel else None,
164
- yaxis_title=ylabel if ylabel else None)
165
- if xlim:
166
- combined_fig.update_xaxes(range=xlim)
167
- if ylim:
168
- combined_fig.update_yaxes(range=ylim)
169
- if grid:
170
- combined_fig.update_layout(xaxis_showgrid=True, yaxis_showgrid=True)
171
+ # Final Config
172
+ if title: combined_fig.update_layout(title=title)
173
+ combined_fig.update_layout(
174
+ xaxis_title=xlabel if xlabel else None,
175
+ yaxis_title=ylabel if ylabel else None
176
+ )
177
+ if xlim: combined_fig.update_xaxes(range=xlim)
178
+ if ylim: combined_fig.update_yaxes(range=ylim)
179
+ if grid: combined_fig.update_layout(xaxis_showgrid=True, yaxis_showgrid=True)
171
180
 
172
181
  combined_fig.update_layout(
173
- autosize=False,
174
- width=width,
175
- height=height,
176
- scene=dict(
177
- aspectratio=dict(x=1, y=1, z=1),
178
- camera=dict(eye=dict(x=1.87, y=0.88, z=1.5)),
179
- ),
182
+ autosize=False, width=width, height=height,
183
+ scene=dict(aspectratio=dict(x=1, y=1, z=1), camera=dict(eye=dict(x=1.87, y=0.88, z=1.5))),
180
184
  margin=dict(l=10, r=10, t=50, b=10),
181
185
  legend=dict(x=0, y=1),
182
186
  )
183
-
184
187
 
185
- if show:
186
- combined_fig.show()
188
+ if show: combined_fig.show()
187
189
 
188
190
  return combined_fig
189
191
 
192
+ # Main Execution
193
+ if not plot_list:
194
+ raise ValueError("plot_list cannot be empty")
195
+
196
+ first_plot = plot_list[0]
197
+
198
+ # Dispatch based on type
199
+ if hasattr(first_plot, 'lines'):
200
+ return _handle_matplotlib(plot_list)
201
+ elif hasattr(first_plot, 'data'):
202
+ return _handle_plotly(plot_list)
190
203
  else:
191
- raise TypeError("Unknown plot object type passed to append_plots.")
204
+ raise TypeError("Unknown plot object type passed to combine_plots.")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: IBB_Helper
3
- Version: 0.4.8.dev23
3
+ Version: 0.4.8.dev24
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