IBB-Helper 0.4.8.dev7__tar.gz → 0.4.8.dev8__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.
- {ibb_helper-0.4.8.dev7/src/IBB_Helper.egg-info → ibb_helper-0.4.8.dev8}/PKG-INFO +1 -1
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/pyproject.toml +1 -1
- ibb_helper-0.4.8.dev8/src/IBB_Helper/extend_plot.py +177 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8/src/IBB_Helper.egg-info}/PKG-INFO +1 -1
- ibb_helper-0.4.8.dev7/src/IBB_Helper/extend_plot.py +0 -240
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/LICENSE +0 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/README.md +0 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/setup.cfg +0 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/setup.py +0 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/src/IBB_Helper/__init__.py +0 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/src/IBB_Helper/animate.py +0 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/src/IBB_Helper/combine_plots.py +0 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/src/IBB_Helper/display.py +0 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/src/IBB_Helper/display_eigen.py +0 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/src/IBB_Helper/display_matrix.py +0 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/src/IBB_Helper/minimize.py +0 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/src/IBB_Helper/num_int.py +0 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/src/IBB_Helper/plot_2d.py +0 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/src/IBB_Helper/plot_3d.py +0 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/src/IBB_Helper/plot_param_grid.py +0 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/src/IBB_Helper/symbolic_BSpline.py +0 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/src/IBB_Helper.egg-info/SOURCES.txt +0 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/src/IBB_Helper.egg-info/dependency_links.txt +0 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/src/IBB_Helper.egg-info/requires.txt +0 -0
- {ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/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.
|
|
3
|
+
Version: 0.4.8.dev8
|
|
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
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import matplotlib.pyplot as plt
|
|
2
|
+
import plotly.graph_objects as go
|
|
3
|
+
import copy
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
def extend_plot(plot_list, dx=0, colors=None, labels=None, line_styles=None,
|
|
7
|
+
show=True, grid=False, xlim=None, ylim=None, title=None,
|
|
8
|
+
xlabel=None, ylabel=None, width=800, height=700,
|
|
9
|
+
stitch=True): # <--- NEW PARAMETER
|
|
10
|
+
"""
|
|
11
|
+
stitched: If True, appends plots horizontally. If False, overlays them using absolute coords.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
if not plot_list:
|
|
15
|
+
raise ValueError("Plot list cannot be empty")
|
|
16
|
+
|
|
17
|
+
first_plot = plot_list[0]
|
|
18
|
+
|
|
19
|
+
# === MATPLOTLIB AXES HANDLING ===
|
|
20
|
+
if hasattr(first_plot, 'lines') or hasattr(first_plot, 'get_lines'):
|
|
21
|
+
fig, ax = plt.subplots()
|
|
22
|
+
agg_xlim = [float('inf'), float('-inf')]
|
|
23
|
+
|
|
24
|
+
if isinstance(colors, str): colors = [colors] * len(plot_list)
|
|
25
|
+
prev_plot_max_x = None
|
|
26
|
+
|
|
27
|
+
for i, p in enumerate(plot_list):
|
|
28
|
+
if hasattr(p, 'lines'): lines = p.lines
|
|
29
|
+
elif hasattr(p, 'get_lines'): lines = p.get_lines()
|
|
30
|
+
else: lines = []
|
|
31
|
+
|
|
32
|
+
# --- 1. Calculate Shift ---
|
|
33
|
+
if stitch:
|
|
34
|
+
plot_min_x = float('inf')
|
|
35
|
+
plot_max_x = float('-inf')
|
|
36
|
+
for line in lines:
|
|
37
|
+
x_orig, _ = line.get_data()
|
|
38
|
+
if len(x_orig) > 0:
|
|
39
|
+
plot_min_x = min(plot_min_x, np.min(x_orig))
|
|
40
|
+
plot_max_x = max(plot_max_x, np.max(x_orig))
|
|
41
|
+
|
|
42
|
+
if i == 0:
|
|
43
|
+
x_shift = 0
|
|
44
|
+
else:
|
|
45
|
+
x_shift = prev_plot_max_x - plot_min_x + dx
|
|
46
|
+
else:
|
|
47
|
+
# OVERLAY MODE: No shifting
|
|
48
|
+
x_shift = 0
|
|
49
|
+
plot_max_x = 0 # Dummy value
|
|
50
|
+
|
|
51
|
+
# --- 2. Plotting ---
|
|
52
|
+
for line_index, line in enumerate(lines):
|
|
53
|
+
x_orig, y_orig = line.get_data()
|
|
54
|
+
x = x_orig + x_shift # Apply shift (0 if stitch=False)
|
|
55
|
+
y = y_orig
|
|
56
|
+
|
|
57
|
+
plot_color = colors[i] if colors and i < len(colors) else line.get_color()
|
|
58
|
+
|
|
59
|
+
orig_linestyle = line.get_linestyle()
|
|
60
|
+
if orig_linestyle in ['None', '']: orig_linestyle = ''
|
|
61
|
+
plot_style = line_styles[i] if line_styles and i < len(line_styles) else orig_linestyle
|
|
62
|
+
|
|
63
|
+
plot_marker = line.get_marker()
|
|
64
|
+
if plot_marker in ['None', '']: plot_marker = ''
|
|
65
|
+
|
|
66
|
+
plot_label = labels[i] if labels and i < len(labels) and line_index == 0 else None
|
|
67
|
+
|
|
68
|
+
ax.plot(x, y, color=plot_color, linestyle=plot_style, marker=plot_marker,
|
|
69
|
+
markersize=line.get_markersize(), linewidth=line.get_linewidth(), label=plot_label)
|
|
70
|
+
|
|
71
|
+
if len(x) > 0:
|
|
72
|
+
agg_xlim[0] = min(agg_xlim[0], np.min(x))
|
|
73
|
+
agg_xlim[1] = max(agg_xlim[1], np.max(x))
|
|
74
|
+
|
|
75
|
+
if stitch and plot_max_x != float('-inf'):
|
|
76
|
+
prev_plot_max_x = plot_max_x + x_shift
|
|
77
|
+
|
|
78
|
+
# Final Config
|
|
79
|
+
final_xlim = xlim if xlim else agg_xlim
|
|
80
|
+
final_ylim = ylim if ylim is not None else (first_plot.get_ylim() if hasattr(first_plot, 'get_ylim') else None)
|
|
81
|
+
|
|
82
|
+
ax.set_xlim(final_xlim)
|
|
83
|
+
if final_ylim: ax.set_ylim(final_ylim)
|
|
84
|
+
|
|
85
|
+
ax.set_title(title if title else (first_plot.get_title() if hasattr(first_plot, 'get_title') else ''))
|
|
86
|
+
ax.set_xlabel(xlabel if xlabel else (first_plot.get_xlabel() if hasattr(first_plot, 'get_xlabel') else ''))
|
|
87
|
+
ax.set_ylabel(ylabel if ylabel else (first_plot.get_ylabel() if hasattr(first_plot, 'get_ylabel') else ''))
|
|
88
|
+
|
|
89
|
+
if grid: ax.grid(True)
|
|
90
|
+
if labels: ax.legend()
|
|
91
|
+
if show: plt.show()
|
|
92
|
+
else: plt.close()
|
|
93
|
+
return ax
|
|
94
|
+
|
|
95
|
+
# === PLOTLY FIGURE HANDLING (YOUR CASE) ===
|
|
96
|
+
elif hasattr(first_plot, 'data'):
|
|
97
|
+
combined_fig = go.Figure()
|
|
98
|
+
prev_plot_max_x = None
|
|
99
|
+
layout_defaults = first_plot.layout
|
|
100
|
+
|
|
101
|
+
for i, fig in enumerate(plot_list):
|
|
102
|
+
|
|
103
|
+
# --- 1. Calculate Shift ---
|
|
104
|
+
if stitch:
|
|
105
|
+
plot_min_x = float('inf')
|
|
106
|
+
plot_max_x = float('-inf')
|
|
107
|
+
|
|
108
|
+
# Check for Surface (z) or Scatter (x,y)
|
|
109
|
+
for trace in fig.data:
|
|
110
|
+
# Prefer explicitly defined X data
|
|
111
|
+
if hasattr(trace, 'x') and trace.x is not None:
|
|
112
|
+
x_data = np.array(trace.x)
|
|
113
|
+
if x_data.size > 0:
|
|
114
|
+
plot_min_x = min(plot_min_x, np.min(x_data))
|
|
115
|
+
plot_max_x = max(plot_max_x, np.max(x_data))
|
|
116
|
+
# Fallback for Surface plots without explicit X (usually 0 to N)
|
|
117
|
+
elif hasattr(trace, 'z') and trace.z is not None:
|
|
118
|
+
# Assume local coordinates 0..shape[1] if x not provided
|
|
119
|
+
# But usually ibb.plot_3d provides x
|
|
120
|
+
pass
|
|
121
|
+
|
|
122
|
+
if i == 0:
|
|
123
|
+
x_shift = 0
|
|
124
|
+
else:
|
|
125
|
+
x_shift = prev_plot_max_x - plot_min_x + dx
|
|
126
|
+
else:
|
|
127
|
+
# OVERLAY MODE: Disable shift entirely
|
|
128
|
+
x_shift = 0
|
|
129
|
+
plot_max_x = 0 # Dummy
|
|
130
|
+
|
|
131
|
+
# --- 2. Add Traces ---
|
|
132
|
+
for trace in fig.data:
|
|
133
|
+
new_trace = copy.deepcopy(trace)
|
|
134
|
+
|
|
135
|
+
# Apply shift if X exists
|
|
136
|
+
if hasattr(trace, 'x') and trace.x is not None:
|
|
137
|
+
x_data = np.array(trace.x)
|
|
138
|
+
new_trace.x = x_data + x_shift
|
|
139
|
+
|
|
140
|
+
# Style overrides
|
|
141
|
+
if colors and i < len(colors):
|
|
142
|
+
if hasattr(new_trace, 'line'): new_trace.line.color = colors[i]
|
|
143
|
+
elif hasattr(new_trace, 'marker'): new_trace.marker.color = colors[i]
|
|
144
|
+
if line_styles and i < len(line_styles):
|
|
145
|
+
if hasattr(new_trace, 'line'): new_trace.line.dash = line_styles[i]
|
|
146
|
+
if labels and i < len(labels):
|
|
147
|
+
new_trace.name = labels[i]
|
|
148
|
+
|
|
149
|
+
combined_fig.add_trace(new_trace)
|
|
150
|
+
|
|
151
|
+
if stitch and plot_max_x != float('-inf'):
|
|
152
|
+
prev_plot_max_x = plot_max_x + x_shift
|
|
153
|
+
|
|
154
|
+
# Final Layout
|
|
155
|
+
combined_fig.update_layout(
|
|
156
|
+
title=title if title else (layout_defaults.title.text if layout_defaults.title else ''),
|
|
157
|
+
xaxis_title=xlabel if xlabel else (layout_defaults.xaxis.title.text if layout_defaults.xaxis.title else ''),
|
|
158
|
+
yaxis_title=ylabel if ylabel else (layout_defaults.yaxis.title.text if layout_defaults.yaxis.title else '')
|
|
159
|
+
)
|
|
160
|
+
if grid: combined_fig.update_layout(xaxis_showgrid=True, yaxis_showgrid=True)
|
|
161
|
+
|
|
162
|
+
combined_fig.update_layout(
|
|
163
|
+
autosize=False, width=width, height=height,
|
|
164
|
+
scene=dict(
|
|
165
|
+
aspectratio=dict(x=1, y=1, z=1),
|
|
166
|
+
camera=dict(eye=dict(x=1.87, y=0.88, z=1.5)),
|
|
167
|
+
),
|
|
168
|
+
margin=dict(l=10, r=10, t=50, b=10),
|
|
169
|
+
legend=dict(x=0, y=1),
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
if show: combined_fig.show()
|
|
173
|
+
|
|
174
|
+
return combined_fig
|
|
175
|
+
|
|
176
|
+
else:
|
|
177
|
+
raise TypeError("Unknown plot object type passed to extend_plots.")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: IBB_Helper
|
|
3
|
-
Version: 0.4.8.
|
|
3
|
+
Version: 0.4.8.dev8
|
|
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,240 +0,0 @@
|
|
|
1
|
-
import matplotlib.pyplot as plt
|
|
2
|
-
import plotly.graph_objects as go
|
|
3
|
-
import copy
|
|
4
|
-
import numpy as np
|
|
5
|
-
|
|
6
|
-
def extend_plot(plot_list, dx=0, colors=None, labels=None, line_styles=None,
|
|
7
|
-
show=True, grid=False, xlim=None, ylim=None, title=None,
|
|
8
|
-
xlabel=None, ylabel=None, width=800, height=700):
|
|
9
|
-
"""
|
|
10
|
-
Stitches multiple plots end-to-end into a single continuous plot with optional horizontal offset.
|
|
11
|
-
|
|
12
|
-
Parameters:
|
|
13
|
-
plot_list : List of matplotlib Axes or plotly Figure objects to be stitched together
|
|
14
|
-
dx : Horizontal offset between consecutive plots (dx=0 no gap, dx>0 gap, dx<0 overlap) (default=0)
|
|
15
|
-
colors : Single color or list of colors for each plot (default=None)
|
|
16
|
-
labels : Labels for each stitched segment (default=None)
|
|
17
|
-
line_styles: Line styles for each plot segment (default=None)
|
|
18
|
-
show : Whether to display the resulting plot (default=True)
|
|
19
|
-
grid : Whether to display a grid (default=False)
|
|
20
|
-
xlim : X-axis limits as (min, max) (default=None)
|
|
21
|
-
ylim : Y-axis limits as (min, max) (default=None)
|
|
22
|
-
title : Plot title (default=None)
|
|
23
|
-
xlabel : X-axis label (default=None)
|
|
24
|
-
ylabel : Y-axis label (default=None)
|
|
25
|
-
|
|
26
|
-
Returns:
|
|
27
|
-
matplotlib Axes or plotly.graph_objects.Figure
|
|
28
|
-
The stitched plot object, matching the input plot type
|
|
29
|
-
"""
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if not plot_list:
|
|
33
|
-
raise ValueError("Plot list cannot be empty")
|
|
34
|
-
|
|
35
|
-
first_plot = plot_list[0]
|
|
36
|
-
|
|
37
|
-
# === MATPLOTLIB AXES HANDLING (PRIMARY BRANCH) ===
|
|
38
|
-
if hasattr(first_plot, 'lines') or hasattr(first_plot, 'get_lines'):
|
|
39
|
-
fig, ax = plt.subplots()
|
|
40
|
-
|
|
41
|
-
# Aggregation variables (for defaults if arguments are None)
|
|
42
|
-
agg_xlim = [float('inf'), float('-inf')]
|
|
43
|
-
|
|
44
|
-
# Use a single color if provided, or prepare for individual colors
|
|
45
|
-
if isinstance(colors, str):
|
|
46
|
-
colors = [colors] * len(plot_list)
|
|
47
|
-
|
|
48
|
-
# Track the ending x position of the previous plot
|
|
49
|
-
prev_plot_max_x = None
|
|
50
|
-
|
|
51
|
-
for i, p in enumerate(plot_list):
|
|
52
|
-
|
|
53
|
-
# Retrieve lines from Axes or Figure
|
|
54
|
-
if hasattr(p, 'lines'):
|
|
55
|
-
lines = p.lines
|
|
56
|
-
elif hasattr(p, 'get_lines'):
|
|
57
|
-
lines = p.get_lines()
|
|
58
|
-
else:
|
|
59
|
-
lines = []
|
|
60
|
-
|
|
61
|
-
# First pass: find min and max x for this plot
|
|
62
|
-
plot_min_x = float('inf')
|
|
63
|
-
plot_max_x = float('-inf')
|
|
64
|
-
|
|
65
|
-
for line in lines:
|
|
66
|
-
x_orig, y_orig = line.get_data()
|
|
67
|
-
if len(x_orig) > 0:
|
|
68
|
-
plot_min_x = min(plot_min_x, np.min(x_orig))
|
|
69
|
-
plot_max_x = max(plot_max_x, np.max(x_orig))
|
|
70
|
-
|
|
71
|
-
# Calculate shift for this plot
|
|
72
|
-
if i == 0:
|
|
73
|
-
# First plot: no shift
|
|
74
|
-
x_shift = 0
|
|
75
|
-
else:
|
|
76
|
-
# Subsequent plots: align min_x with prev_max_x + dx
|
|
77
|
-
x_shift = prev_plot_max_x - plot_min_x + dx
|
|
78
|
-
|
|
79
|
-
# --- Plotting ---
|
|
80
|
-
for line_index, line in enumerate(lines):
|
|
81
|
-
x_orig, y_orig = line.get_data()
|
|
82
|
-
|
|
83
|
-
# Apply shift
|
|
84
|
-
x = x_orig + x_shift
|
|
85
|
-
y = y_orig
|
|
86
|
-
|
|
87
|
-
# Default style transfer from source line
|
|
88
|
-
plot_color = colors[i] if colors and i < len(colors) else line.get_color()
|
|
89
|
-
|
|
90
|
-
# Get linestyle - handle marker-only plots
|
|
91
|
-
orig_linestyle = line.get_linestyle()
|
|
92
|
-
if orig_linestyle in ['None', '']:
|
|
93
|
-
orig_linestyle = ''
|
|
94
|
-
plot_style = line_styles[i] if line_styles and i < len(line_styles) else orig_linestyle
|
|
95
|
-
|
|
96
|
-
# Get marker - normalize 'None' string to empty
|
|
97
|
-
plot_marker = line.get_marker()
|
|
98
|
-
if plot_marker in ['None', '']:
|
|
99
|
-
plot_marker = ''
|
|
100
|
-
|
|
101
|
-
# Label transfer (only the first line of the source plot gets the label)
|
|
102
|
-
plot_label = labels[i] if labels and i < len(labels) and line_index == 0 else None
|
|
103
|
-
|
|
104
|
-
# Plot the segment
|
|
105
|
-
ax.plot(x, y,
|
|
106
|
-
color=plot_color,
|
|
107
|
-
linestyle=plot_style,
|
|
108
|
-
marker=plot_marker,
|
|
109
|
-
markersize=line.get_markersize(),
|
|
110
|
-
linewidth=line.get_linewidth(),
|
|
111
|
-
label=plot_label)
|
|
112
|
-
|
|
113
|
-
# Update global xlim
|
|
114
|
-
if len(x) > 0:
|
|
115
|
-
agg_xlim[0] = min(agg_xlim[0], np.min(x))
|
|
116
|
-
agg_xlim[1] = max(agg_xlim[1], np.max(x))
|
|
117
|
-
|
|
118
|
-
# Update previous plot's max x for next iteration
|
|
119
|
-
if plot_max_x != float('-inf'):
|
|
120
|
-
prev_plot_max_x = plot_max_x + x_shift
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
# --- Final Matplotlib Configuration ---
|
|
124
|
-
|
|
125
|
-
# Apply limits (prioritize argument, then aggregated data, then source plot limits)
|
|
126
|
-
final_xlim = xlim if xlim else agg_xlim
|
|
127
|
-
|
|
128
|
-
if ylim is None and hasattr(first_plot, 'get_ylim'):
|
|
129
|
-
final_ylim = first_plot.get_ylim()
|
|
130
|
-
else:
|
|
131
|
-
final_ylim = ylim
|
|
132
|
-
|
|
133
|
-
ax.set_xlim(final_xlim)
|
|
134
|
-
if final_ylim:
|
|
135
|
-
ax.set_ylim(final_ylim)
|
|
136
|
-
|
|
137
|
-
# Apply labels/title (prioritize argument, then source plot labels)
|
|
138
|
-
ax.set_title(title if title else (first_plot.get_title() if hasattr(first_plot, 'get_title') else ''))
|
|
139
|
-
ax.set_xlabel(xlabel if xlabel else (first_plot.get_xlabel() if hasattr(first_plot, 'get_xlabel') else ''))
|
|
140
|
-
ax.set_ylabel(ylabel if ylabel else (first_plot.get_ylabel() if hasattr(first_plot, 'get_ylabel') else ''))
|
|
141
|
-
|
|
142
|
-
if grid:
|
|
143
|
-
ax.grid(True)
|
|
144
|
-
if labels: # Only show legend if we managed labels
|
|
145
|
-
ax.legend()
|
|
146
|
-
|
|
147
|
-
if show:
|
|
148
|
-
plt.show()
|
|
149
|
-
else:
|
|
150
|
-
plt.close()
|
|
151
|
-
|
|
152
|
-
return ax
|
|
153
|
-
|
|
154
|
-
# === PLOTLY FIGURE HANDLING (SECONDARY BRANCH) ===
|
|
155
|
-
elif hasattr(first_plot, 'data'):
|
|
156
|
-
# Plotly branch
|
|
157
|
-
combined_fig = go.Figure()
|
|
158
|
-
prev_plot_max_x = None
|
|
159
|
-
|
|
160
|
-
# Retrieve layout defaults from the first figure
|
|
161
|
-
layout_defaults = first_plot.layout
|
|
162
|
-
|
|
163
|
-
for i, fig in enumerate(plot_list):
|
|
164
|
-
# First pass: find min and max x for this plot
|
|
165
|
-
plot_min_x = float('inf')
|
|
166
|
-
plot_max_x = float('-inf')
|
|
167
|
-
|
|
168
|
-
for trace in fig.data:
|
|
169
|
-
|
|
170
|
-
if hasattr(trace, 'x') and trace.x is not None:
|
|
171
|
-
x_data = np.array(trace.x)
|
|
172
|
-
if len(x_data) > 0:
|
|
173
|
-
plot_min_x = min(plot_min_x, np.min(x_data))
|
|
174
|
-
plot_max_x = max(plot_max_x, np.max(x_data))
|
|
175
|
-
|
|
176
|
-
# Calculate shift for this plot
|
|
177
|
-
if i==0:
|
|
178
|
-
x_shift = 0
|
|
179
|
-
else:
|
|
180
|
-
x_shift = prev_plot_max_x - plot_min_x + dx
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
# Second pass: apply shift and add traces
|
|
184
|
-
for trace in fig.data:
|
|
185
|
-
# Use deepcopy for safe cloning
|
|
186
|
-
new_trace = copy.deepcopy(trace)
|
|
187
|
-
|
|
188
|
-
# Apply shift
|
|
189
|
-
if hasattr(trace, 'x') and trace.x is not None:
|
|
190
|
-
x_data = np.array(trace.x)
|
|
191
|
-
new_trace.x = x_data + x_shift
|
|
192
|
-
|
|
193
|
-
# Apply overrides/defaults
|
|
194
|
-
if colors and i < len(colors):
|
|
195
|
-
if hasattr(new_trace, 'line'):
|
|
196
|
-
new_trace.line.color = colors[i]
|
|
197
|
-
elif hasattr(new_trace, 'marker'):
|
|
198
|
-
new_trace.marker.color = colors[i]
|
|
199
|
-
|
|
200
|
-
if line_styles and i < len(line_styles):
|
|
201
|
-
if hasattr(new_trace, 'line'):
|
|
202
|
-
new_trace.line.dash = line_styles[i]
|
|
203
|
-
|
|
204
|
-
if labels and i < len(labels):
|
|
205
|
-
new_trace.name = labels[i]
|
|
206
|
-
|
|
207
|
-
combined_fig.add_trace(new_trace)
|
|
208
|
-
|
|
209
|
-
# Update previous plot's max x for next iteration
|
|
210
|
-
if plot_max_x != float('-inf'):
|
|
211
|
-
prev_plot_max_x = plot_max_x + x_shift
|
|
212
|
-
|
|
213
|
-
# Final Layout Configuration (prioritize arguments over defaults)
|
|
214
|
-
combined_fig.update_layout(
|
|
215
|
-
title=title if title else (layout_defaults.title.text if layout_defaults.title else ''),
|
|
216
|
-
xaxis_title=xlabel if xlabel else (layout_defaults.xaxis.title.text if layout_defaults.xaxis.title else ''),
|
|
217
|
-
yaxis_title=ylabel if ylabel else (layout_defaults.yaxis.title.text if layout_defaults.yaxis.title else '')
|
|
218
|
-
)
|
|
219
|
-
if grid:
|
|
220
|
-
combined_fig.update_layout(xaxis_showgrid=True, yaxis_showgrid=True)
|
|
221
|
-
|
|
222
|
-
combined_fig.update_layout(
|
|
223
|
-
autosize=False,
|
|
224
|
-
width=width,
|
|
225
|
-
height=height,
|
|
226
|
-
scene=dict(
|
|
227
|
-
aspectratio=dict(x=1, y=1, z=1),
|
|
228
|
-
camera=dict(eye=dict(x=1.87, y=0.88, z=1.5)),
|
|
229
|
-
),
|
|
230
|
-
margin=dict(l=10, r=10, t=50, b=10),
|
|
231
|
-
legend=dict(x=0, y=1),
|
|
232
|
-
)
|
|
233
|
-
|
|
234
|
-
if show:
|
|
235
|
-
combined_fig.show()
|
|
236
|
-
|
|
237
|
-
return combined_fig
|
|
238
|
-
|
|
239
|
-
else:
|
|
240
|
-
raise TypeError("Unknown plot object type passed to extend_plots.")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ibb_helper-0.4.8.dev7 → ibb_helper-0.4.8.dev8}/src/IBB_Helper.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|