IBB-Helper 0.1.2__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.1.2/IBB_Helper/__init__.py +8 -0
- ibb_helper-0.1.2/IBB_Helper/append_plots.py +111 -0
- ibb_helper-0.1.2/IBB_Helper/dis.py +44 -0
- ibb_helper-0.1.2/IBB_Helper/dis_ei.py +83 -0
- ibb_helper-0.1.2/IBB_Helper/dmat.py +43 -0
- ibb_helper-0.1.2/IBB_Helper/extend_plots.py +52 -0
- ibb_helper-0.1.2/IBB_Helper/plot_2d.py +81 -0
- ibb_helper-0.1.2/IBB_Helper/plot_3d.py +83 -0
- ibb_helper-0.1.2/IBB_Helper.egg-info/PKG-INFO +101 -0
- ibb_helper-0.1.2/IBB_Helper.egg-info/SOURCES.txt +16 -0
- ibb_helper-0.1.2/IBB_Helper.egg-info/dependency_links.txt +1 -0
- ibb_helper-0.1.2/IBB_Helper.egg-info/top_level.txt +1 -0
- ibb_helper-0.1.2/LICENSE.txt +29 -0
- ibb_helper-0.1.2/PKG-INFO +101 -0
- ibb_helper-0.1.2/README.md +78 -0
- ibb_helper-0.1.2/pyproject.toml +3 -0
- ibb_helper-0.1.2/setup.cfg +4 -0
- ibb_helper-0.1.2/setup.py +20 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import matplotlib.pyplot as plt
|
|
2
|
+
import plotly.graph_objects as go
|
|
3
|
+
|
|
4
|
+
def append_plots(plot_list, labels=None, line_styles=None, colors=None,
|
|
5
|
+
swap_axes=False, show=True, grid=False,
|
|
6
|
+
xlim=None, ylim=None, title=None, xlabel=None, ylabel=None):
|
|
7
|
+
"""
|
|
8
|
+
Combines multiple individual matplotlib Axes or plotly Figures into a single figure.
|
|
9
|
+
|
|
10
|
+
Parameters same as before.
|
|
11
|
+
|
|
12
|
+
Returns:
|
|
13
|
+
- matplotlib Axes object OR plotly Figure object depending on input.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
if not plot_list:
|
|
17
|
+
raise ValueError("plot_list cannot be empty")
|
|
18
|
+
|
|
19
|
+
first_plot = plot_list[0]
|
|
20
|
+
|
|
21
|
+
# Check if matplotlib plot (Axes)
|
|
22
|
+
if hasattr(first_plot, 'lines'):
|
|
23
|
+
fig, ax = plt.subplots()
|
|
24
|
+
for i, plot_ax in enumerate(plot_list):
|
|
25
|
+
first_line = True
|
|
26
|
+
for line in plot_ax.lines:
|
|
27
|
+
x, y = line.get_data()
|
|
28
|
+
|
|
29
|
+
linestyle = line.get_linestyle()
|
|
30
|
+
if line_styles and i < len(line_styles):
|
|
31
|
+
linestyle = line_styles[i]
|
|
32
|
+
|
|
33
|
+
color = line.get_color()
|
|
34
|
+
if colors and i < len(colors):
|
|
35
|
+
color = colors[i]
|
|
36
|
+
|
|
37
|
+
if swap_axes:
|
|
38
|
+
ax.plot(y, x, color=color, linestyle=linestyle,
|
|
39
|
+
label=labels[i] if first_line and labels and i < len(labels) else None)
|
|
40
|
+
else:
|
|
41
|
+
ax.plot(x, y, color=color, linestyle=linestyle,
|
|
42
|
+
label=labels[i] if first_line and labels and i < len(labels) else None)
|
|
43
|
+
|
|
44
|
+
first_line = False
|
|
45
|
+
|
|
46
|
+
if xlim:
|
|
47
|
+
ax.set_xlim(xlim)
|
|
48
|
+
if ylim:
|
|
49
|
+
ax.set_ylim(ylim)
|
|
50
|
+
if title:
|
|
51
|
+
ax.set_title(title)
|
|
52
|
+
if xlabel:
|
|
53
|
+
ax.set_xlabel(xlabel)
|
|
54
|
+
if ylabel:
|
|
55
|
+
ax.set_ylabel(ylabel)
|
|
56
|
+
if grid:
|
|
57
|
+
ax.grid()
|
|
58
|
+
if labels:
|
|
59
|
+
ax.legend()
|
|
60
|
+
if show:
|
|
61
|
+
plt.show()
|
|
62
|
+
else:
|
|
63
|
+
plt.close()
|
|
64
|
+
|
|
65
|
+
return ax
|
|
66
|
+
|
|
67
|
+
# Check if plotly figure
|
|
68
|
+
elif hasattr(first_plot, 'data'):
|
|
69
|
+
combined_fig = go.Figure()
|
|
70
|
+
for i, fig in enumerate(plot_list):
|
|
71
|
+
for trace in fig.data:
|
|
72
|
+
# Clone the trace to avoid mutating original
|
|
73
|
+
new_trace = trace
|
|
74
|
+
|
|
75
|
+
# Apply colors if provided and trace supports it
|
|
76
|
+
if colors and i < len(colors):
|
|
77
|
+
if hasattr(new_trace, 'line'):
|
|
78
|
+
new_trace.line.color = colors[i]
|
|
79
|
+
elif hasattr(new_trace, 'marker'):
|
|
80
|
+
new_trace.marker.color = colors[i]
|
|
81
|
+
|
|
82
|
+
# Apply line styles if provided and trace supports it (only for scatter lines)
|
|
83
|
+
if line_styles and i < len(line_styles):
|
|
84
|
+
if isinstance(new_trace, go.Scatter) and hasattr(new_trace, 'line'):
|
|
85
|
+
new_trace.line.dash = line_styles[i]
|
|
86
|
+
|
|
87
|
+
# Apply labels if available and applicable
|
|
88
|
+
if labels and i < len(labels):
|
|
89
|
+
new_trace.name = labels[i]
|
|
90
|
+
|
|
91
|
+
combined_fig.add_trace(new_trace)
|
|
92
|
+
|
|
93
|
+
if title:
|
|
94
|
+
combined_fig.update_layout(title=title)
|
|
95
|
+
if xlabel or ylabel:
|
|
96
|
+
combined_fig.update_layout(xaxis_title=xlabel if xlabel else None,
|
|
97
|
+
yaxis_title=ylabel if ylabel else None)
|
|
98
|
+
if xlim:
|
|
99
|
+
combined_fig.update_xaxes(range=xlim)
|
|
100
|
+
if ylim:
|
|
101
|
+
combined_fig.update_yaxes(range=ylim)
|
|
102
|
+
if grid:
|
|
103
|
+
combined_fig.update_layout(xaxis_showgrid=True, yaxis_showgrid=True)
|
|
104
|
+
|
|
105
|
+
if show:
|
|
106
|
+
combined_fig.show()
|
|
107
|
+
|
|
108
|
+
return combined_fig
|
|
109
|
+
|
|
110
|
+
else:
|
|
111
|
+
raise TypeError("Unknown plot object type passed to append_plots.")
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import sympy as sp
|
|
3
|
+
from sympy import latex
|
|
4
|
+
from IPython.display import Math, display
|
|
5
|
+
|
|
6
|
+
def DIS(obj, name="obj", evalf=False, tol=5):
|
|
7
|
+
"""
|
|
8
|
+
Converts vectors/numbers/matrices to LaTeX with optional simplification.
|
|
9
|
+
|
|
10
|
+
Parameters:
|
|
11
|
+
obj : Input (SymPy or NumPy object)
|
|
12
|
+
name : Name used for display
|
|
13
|
+
evalf : If T, evaluates to decimal form before display
|
|
14
|
+
rational: If T, result shown as fraction; if F, decimal
|
|
15
|
+
x : Optional. If given, sets tolerance as 1e-x (e.g., x=3 → tol=1e-3)
|
|
16
|
+
tol : Optional tolerance value (overrides x if both given)
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def safe_eval_entry(x):
|
|
20
|
+
try:
|
|
21
|
+
return sp.sympify(x).evalf(tol)
|
|
22
|
+
except (TypeError, ValueError):
|
|
23
|
+
return x
|
|
24
|
+
|
|
25
|
+
if evalf:
|
|
26
|
+
if isinstance(obj, np.ndarray):
|
|
27
|
+
obj = sp.Matrix(obj).applyfunc(safe_eval_entry)
|
|
28
|
+
elif isinstance(obj, (sp.Matrix, list)):
|
|
29
|
+
obj = sp.Matrix(obj).applyfunc(safe_eval_entry)
|
|
30
|
+
elif isinstance(obj, sp.NDimArray):
|
|
31
|
+
obj = obj.applyfunc(safe_eval_entry)
|
|
32
|
+
else:
|
|
33
|
+
obj = safe_eval_entry(obj)
|
|
34
|
+
else:
|
|
35
|
+
if isinstance(obj, np.ndarray):
|
|
36
|
+
obj = sp.Matrix(obj)
|
|
37
|
+
elif isinstance(obj, (sp.Matrix, list)):
|
|
38
|
+
obj = sp.Matrix(obj)
|
|
39
|
+
elif isinstance(obj, sp.NDimArray):
|
|
40
|
+
obj = obj
|
|
41
|
+
else:
|
|
42
|
+
obj = sp.sympify(obj)
|
|
43
|
+
|
|
44
|
+
display(Math(f"{name} = {latex(obj)}"))
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import sympy as sp
|
|
3
|
+
from sympy import latex
|
|
4
|
+
from IPython.display import Math, display
|
|
5
|
+
import matplotlib.pyplot as plt
|
|
6
|
+
import plotly.graph_objects as go
|
|
7
|
+
|
|
8
|
+
def DIS_EI(A, name="Matrix", evalf=False, tol=5, return_data=False, show=True, show_which="both"):
|
|
9
|
+
"""
|
|
10
|
+
Computes and displays the eigenvalues and eigenvectors of a matrix A with enhanced display options.
|
|
11
|
+
|
|
12
|
+
Parameters:
|
|
13
|
+
A : Square matrix (SymPy Matrix or NumPy ndarray)
|
|
14
|
+
name : Label used for the matrix (default="Matrix")
|
|
15
|
+
evalf : If True, show decimal values (default=False)
|
|
16
|
+
tol : Tolerance for decimal rounding (default=5)
|
|
17
|
+
return_data: If True, also returns eigenvalues and eigenvectors (default=False)
|
|
18
|
+
show : If True, displays the output (default=True)
|
|
19
|
+
show_which : What to display ("both", "eigvals", or "eigvecs") (default="both")
|
|
20
|
+
|
|
21
|
+
Returns (if return_data=True):
|
|
22
|
+
- eigvals: List of eigenvalues
|
|
23
|
+
- eigvecs: List of corresponding eigenvectors (each as a SymPy Matrix)
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
threshold = 10**(-10)
|
|
27
|
+
|
|
28
|
+
def safe_eval(x):
|
|
29
|
+
try:
|
|
30
|
+
val = x.evalf(tol)
|
|
31
|
+
if abs(val) < threshold:
|
|
32
|
+
return sp.Integer(0)
|
|
33
|
+
return round(float(val), tol)
|
|
34
|
+
except (TypeError, ValueError):
|
|
35
|
+
return x
|
|
36
|
+
|
|
37
|
+
# Convert NumPy array to SymPy Matrix if needed
|
|
38
|
+
if isinstance(A, np.ndarray):
|
|
39
|
+
A = sp.Matrix(A)
|
|
40
|
+
|
|
41
|
+
# Compute eigenvalues and eigenvectors
|
|
42
|
+
eigen_data = A.eigenvects()
|
|
43
|
+
|
|
44
|
+
# To store raw data
|
|
45
|
+
eigvals = []
|
|
46
|
+
eigvecs = []
|
|
47
|
+
|
|
48
|
+
# Validate show_which parameter
|
|
49
|
+
show_which = show_which.lower()
|
|
50
|
+
valid_options = ["both", "eigvals", "eigvecs"]
|
|
51
|
+
if show_which not in valid_options:
|
|
52
|
+
raise ValueError(f"show_which must be one of {valid_options}")
|
|
53
|
+
|
|
54
|
+
# Prepare data
|
|
55
|
+
counter = 1
|
|
56
|
+
for eigval, mult, vects in eigen_data:
|
|
57
|
+
for i in range(mult):
|
|
58
|
+
val_disp = safe_eval(eigval) if evalf else eigval
|
|
59
|
+
v_disp = vects[i].applyfunc(safe_eval) if evalf else vects[i]
|
|
60
|
+
eigvals.append(val_disp)
|
|
61
|
+
eigvecs.append(v_disp)
|
|
62
|
+
counter += 1
|
|
63
|
+
|
|
64
|
+
# Build LaTeX string based on options
|
|
65
|
+
if show_which == "both":
|
|
66
|
+
latex_str = f"\\text{{Eigenvalues and Eigenvectors of }} {name}: \\\\"
|
|
67
|
+
for i, (val, vec) in enumerate(zip(eigvals, eigvecs)):
|
|
68
|
+
latex_str += f"\\lambda_{{{i+1}}} = {latex(val)}, \\quad v_{{{i+1}}} = {latex(vec)} \\\\"
|
|
69
|
+
|
|
70
|
+
elif show_which == "eigvals":
|
|
71
|
+
# Default vector display for eigenvalues only
|
|
72
|
+
latex_str = f"\\text{{Eigenvalues of }} {name}: \\quad \\lambda = {latex(sp.Matrix(eigvals))}"
|
|
73
|
+
|
|
74
|
+
elif show_which == "eigvecs":
|
|
75
|
+
# Default matrix display for eigenvectors only
|
|
76
|
+
V = sp.Matrix.hstack(*[vec for vec in eigvecs])
|
|
77
|
+
latex_str = f"\\text{{Eigenvectors of }} {name}: \\quad v = {latex(V)}"
|
|
78
|
+
|
|
79
|
+
if show:
|
|
80
|
+
display(Math(latex_str))
|
|
81
|
+
|
|
82
|
+
if return_data:
|
|
83
|
+
return eigvals, eigvecs
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import sympy as sp
|
|
3
|
+
from sympy import latex
|
|
4
|
+
from IPython.display import Math, display
|
|
5
|
+
import matplotlib.pyplot as plt
|
|
6
|
+
import plotly.graph_objects as go
|
|
7
|
+
|
|
8
|
+
def DMAT(matrix, name="Matrix", r=5, c=5, evalf=False, tol=5):
|
|
9
|
+
"""
|
|
10
|
+
Displays a truncated matrix with optional numerical evaluation and rational simplification.
|
|
11
|
+
|
|
12
|
+
Parameters:
|
|
13
|
+
matrix : Input matrix (NumPy array, SymPy Matrix, or list)
|
|
14
|
+
name : Display name (default: "Matrix")
|
|
15
|
+
r : Max rows to display (default: 5)
|
|
16
|
+
c : Max columns to display (default: 5)
|
|
17
|
+
evalf : If T, apply numerical evaluation (default: F)
|
|
18
|
+
rational: If T, display as fraction; else as decimal (default: T)
|
|
19
|
+
x : Optional. If given, sets tolerance as 1e-x
|
|
20
|
+
tol : Optional tolerance value (overrides x if both are given)
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
# Convert to SymPy Matrix if needed
|
|
24
|
+
if isinstance(matrix, (np.ndarray, list)):
|
|
25
|
+
matrix = sp.Matrix(matrix)
|
|
26
|
+
|
|
27
|
+
# Truncate to r rows and c columns
|
|
28
|
+
submatrix = matrix[:min(r, matrix.rows), :min(c, matrix.cols)]
|
|
29
|
+
|
|
30
|
+
# Apply evaluation if needed
|
|
31
|
+
if evalf:
|
|
32
|
+
processed = submatrix.applyfunc(lambda x: x.evalf(tol))
|
|
33
|
+
else:
|
|
34
|
+
processed = submatrix
|
|
35
|
+
|
|
36
|
+
# Display matrix
|
|
37
|
+
display(Math(f"{name} = {latex(processed)}"))
|
|
38
|
+
|
|
39
|
+
m = matrix.rows
|
|
40
|
+
n = matrix.cols
|
|
41
|
+
# Show truncation message if applicable
|
|
42
|
+
if matrix.rows > r or matrix.cols > c:
|
|
43
|
+
display(Math(rf"\text{{... Truncated to first {r}x{c} out of {m}x{n} matrix}}"))
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import matplotlib.pyplot as plt
|
|
2
|
+
import plotly.graph_objects as go
|
|
3
|
+
|
|
4
|
+
def extend_plots(plot_list, dx=0, colors=None, show=True):
|
|
5
|
+
if not plot_list:
|
|
6
|
+
raise ValueError("Plot list cannot be empty")
|
|
7
|
+
|
|
8
|
+
# Detect if first plot is matplotlib or plotly
|
|
9
|
+
first_plot = plot_list[0]
|
|
10
|
+
|
|
11
|
+
# Check for matplotlib plot: look for .lines or .get_lines()
|
|
12
|
+
if hasattr(first_plot, 'lines') or hasattr(first_plot, 'get_lines'):
|
|
13
|
+
# Matplotlib branch
|
|
14
|
+
# Assume plot_list are matplotlib Axes or Figures with lines
|
|
15
|
+
fig, ax = plt.subplots()
|
|
16
|
+
for p in plot_list:
|
|
17
|
+
# Support Axes or Figure input:
|
|
18
|
+
if hasattr(p, 'lines'):
|
|
19
|
+
lines = p.lines
|
|
20
|
+
elif hasattr(p, 'get_lines'):
|
|
21
|
+
lines = p.get_lines()
|
|
22
|
+
else:
|
|
23
|
+
lines = []
|
|
24
|
+
for line in lines:
|
|
25
|
+
x, y = line.get_data()
|
|
26
|
+
ax.plot(x + dx, y, color=colors)
|
|
27
|
+
if show:
|
|
28
|
+
plt.show()
|
|
29
|
+
else:
|
|
30
|
+
plt.close()
|
|
31
|
+
return ax
|
|
32
|
+
|
|
33
|
+
# Check for Plotly plot: look for .data attribute (list of traces)
|
|
34
|
+
elif hasattr(first_plot, 'data'):
|
|
35
|
+
# Plotly branch
|
|
36
|
+
# Combine traces from all figures into one figure
|
|
37
|
+
combined_fig = go.Figure()
|
|
38
|
+
for fig in plot_list:
|
|
39
|
+
for trace in fig.data:
|
|
40
|
+
# Optionally shift trace x by dx if it has x data
|
|
41
|
+
# This requires modifying trace.x which may be tuple/list/np.array
|
|
42
|
+
if hasattr(trace, 'x') and trace.x is not None:
|
|
43
|
+
shifted_x = [xi + dx for xi in trace.x] if isinstance(trace.x, (list, tuple)) else trace.x
|
|
44
|
+
trace = trace.update(x=shifted_x)
|
|
45
|
+
combined_fig.add_trace(trace)
|
|
46
|
+
if show:
|
|
47
|
+
combined_fig.show()
|
|
48
|
+
|
|
49
|
+
return combined_fig
|
|
50
|
+
|
|
51
|
+
else:
|
|
52
|
+
raise TypeError("Unknown plot object type passed to extend_plots.")
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import sympy as sp
|
|
3
|
+
import matplotlib.pyplot as plt
|
|
4
|
+
from sympy import latex
|
|
5
|
+
|
|
6
|
+
def plot_2d(exprs, var, labels=None, line_styles=None, colors=None,
|
|
7
|
+
title="2D Plot", xlabel="x", ylabel="y",
|
|
8
|
+
xlim=None, ylim=None, resolution=400, show=True):
|
|
9
|
+
"""
|
|
10
|
+
Plots 2D curves from symbolic expressions or (x, y) datasets using Matplotlib.
|
|
11
|
+
Automatically detects whether labels and axis titles should be symbolic (LaTeX)
|
|
12
|
+
or plain text.
|
|
13
|
+
|
|
14
|
+
Rules:
|
|
15
|
+
- Strings containing '\' are treated as LaTeX symbols.
|
|
16
|
+
- Strings without '\' are treated as plain text.
|
|
17
|
+
- SymPy symbols or expressions are automatically converted to LaTeX.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def smart_label(lbl):
|
|
21
|
+
"""Return string for Matplotlib: LaTeX if symbolic, plain text otherwise"""
|
|
22
|
+
if isinstance(lbl, str):
|
|
23
|
+
if "\\" in lbl:
|
|
24
|
+
return f"${lbl}$" # LaTeX
|
|
25
|
+
else:
|
|
26
|
+
return lbl # plain text
|
|
27
|
+
else:
|
|
28
|
+
return f"${latex(lbl)}$" # SymPy expression → LaTeX
|
|
29
|
+
|
|
30
|
+
if not isinstance(exprs, list):
|
|
31
|
+
exprs = [exprs]
|
|
32
|
+
|
|
33
|
+
# Determine symbol and range
|
|
34
|
+
if isinstance(var, tuple):
|
|
35
|
+
x_sym = var[0]
|
|
36
|
+
x_range = var[1]
|
|
37
|
+
else:
|
|
38
|
+
x_sym = var
|
|
39
|
+
x_range = (-1, 1)
|
|
40
|
+
|
|
41
|
+
x_vals = np.linspace(float(x_range[0]), float(x_range[1]), resolution)
|
|
42
|
+
|
|
43
|
+
fig, ax = plt.subplots()
|
|
44
|
+
|
|
45
|
+
for i, expr in enumerate(exprs):
|
|
46
|
+
style = line_styles[i] if line_styles and i < len(line_styles) else 'solid'
|
|
47
|
+
color = colors[i] if colors and i < len(colors) else None
|
|
48
|
+
|
|
49
|
+
label = smart_label(labels[i]) if labels and i < len(labels) else None
|
|
50
|
+
|
|
51
|
+
# If expr is (x_data, y_data)
|
|
52
|
+
if isinstance(expr, (tuple, list)) and len(expr) == 2:
|
|
53
|
+
x_data, y_data = expr
|
|
54
|
+
ax.plot(x_data, y_data, label=label, linestyle=style, color=color)
|
|
55
|
+
else:
|
|
56
|
+
expr = sp.sympify(expr)
|
|
57
|
+
if not expr.has(x_sym):
|
|
58
|
+
y_vals = np.full_like(x_vals, float(expr))
|
|
59
|
+
else:
|
|
60
|
+
f = sp.lambdify(x_sym, expr, modules='numpy')
|
|
61
|
+
y_vals = np.array(f(x_vals)).flatten()
|
|
62
|
+
ax.plot(x_vals, y_vals, label=label, linestyle=style, color=color)
|
|
63
|
+
|
|
64
|
+
ax.set_title(smart_label(title))
|
|
65
|
+
ax.set_xlabel(smart_label(xlabel))
|
|
66
|
+
ax.set_ylabel(smart_label(ylabel))
|
|
67
|
+
|
|
68
|
+
if xlim:
|
|
69
|
+
ax.set_xlim(xlim)
|
|
70
|
+
if ylim:
|
|
71
|
+
ax.set_ylim(ylim)
|
|
72
|
+
if labels:
|
|
73
|
+
ax.legend()
|
|
74
|
+
ax.grid(True)
|
|
75
|
+
|
|
76
|
+
if show:
|
|
77
|
+
plt.show()
|
|
78
|
+
else:
|
|
79
|
+
plt.close()
|
|
80
|
+
|
|
81
|
+
return ax
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import sympy as sp
|
|
3
|
+
from sympy import latex
|
|
4
|
+
from IPython.display import Math, display
|
|
5
|
+
import matplotlib.pyplot as plt
|
|
6
|
+
import plotly.graph_objects as go
|
|
7
|
+
|
|
8
|
+
def plot_3d(exprs, var, labels=None, colors=None,
|
|
9
|
+
title="3D Plot", xlabel="x", ylabel="y", zlabel="Value",
|
|
10
|
+
xlim=None, ylim=None, zlim=None,
|
|
11
|
+
resolution=100, show=True):
|
|
12
|
+
"""
|
|
13
|
+
Plots 3D surfaces from symbolic expressions using Plotly.
|
|
14
|
+
|
|
15
|
+
Parameters:
|
|
16
|
+
- exprs : List of SymPy expressions or a single expression
|
|
17
|
+
- var : Tuple (x_sym, x_range, y_sym, y_range)
|
|
18
|
+
- labels : List of labels (LaTeX strings) for each surface
|
|
19
|
+
- colors : List of colors per surface
|
|
20
|
+
- title : Plot title
|
|
21
|
+
- xlabel, ylabel, zlabel: Axis labels
|
|
22
|
+
- xlim, ylim, zlim: Axis limit tuples
|
|
23
|
+
- resolution: Grid resolution (default: 100x100)
|
|
24
|
+
- show : If True, shows the plot immediately
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
- fig : Plotly Figure object (if show=False)
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
if not isinstance(exprs, list):
|
|
31
|
+
exprs = [exprs]
|
|
32
|
+
|
|
33
|
+
if not isinstance(var, tuple) or len(var) != 4:
|
|
34
|
+
raise ValueError("`var` must be a tuple: (x_sym, x_range, y_sym, y_range)")
|
|
35
|
+
|
|
36
|
+
x_sym, x_range, y_sym, y_range = var
|
|
37
|
+
|
|
38
|
+
x_vals = np.linspace(float(x_range[0]), float(x_range[1]), resolution)
|
|
39
|
+
y_vals = np.linspace(float(y_range[0]), float(y_range[1]), resolution)
|
|
40
|
+
X, Y = np.meshgrid(x_vals, y_vals)
|
|
41
|
+
|
|
42
|
+
fig = go.Figure()
|
|
43
|
+
|
|
44
|
+
for i, expr in enumerate(exprs):
|
|
45
|
+
expr = sp.sympify(expr)
|
|
46
|
+
color = colors[i] if colors and i < len(colors) else None
|
|
47
|
+
label = labels[i] if labels and i < len(labels) else f"Expr {i+1}"
|
|
48
|
+
|
|
49
|
+
f = sp.lambdify((x_sym, y_sym), expr, modules="numpy")
|
|
50
|
+
Z = f(X, Y)
|
|
51
|
+
if np.isscalar(Z):
|
|
52
|
+
# Convert scalar zero (or any scalar) into a 2D array matching X,Y shape
|
|
53
|
+
Z = np.zeros_like(X, dtype=float)
|
|
54
|
+
|
|
55
|
+
fig.add_trace(go.Surface(
|
|
56
|
+
x=X, y=Y, z=Z,
|
|
57
|
+
name=label,
|
|
58
|
+
colorscale='Turbo' if color is None else [[0, color], [1, color]],
|
|
59
|
+
showscale=False,
|
|
60
|
+
opacity=0.9
|
|
61
|
+
))
|
|
62
|
+
|
|
63
|
+
fig.update_layout(
|
|
64
|
+
title=title,
|
|
65
|
+
width=800, height=600,
|
|
66
|
+
scene=dict(
|
|
67
|
+
xaxis_title=xlabel,
|
|
68
|
+
yaxis_title=ylabel,
|
|
69
|
+
zaxis_title=zlabel,
|
|
70
|
+
xaxis=dict(range=list(xlim) if xlim else None),
|
|
71
|
+
yaxis=dict(range=list(ylim) if ylim else None),
|
|
72
|
+
zaxis=dict(range=list(zlim) if zlim else None),
|
|
73
|
+
aspectratio=dict(x=1, y=1, z=0.5),
|
|
74
|
+
camera=dict(eye=dict(x=1.2, y=1.2, z=0.6))
|
|
75
|
+
),
|
|
76
|
+
margin=dict(l=10, r=10, t=50, b=10),
|
|
77
|
+
legend=dict(x=0, y=1)
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
if show:
|
|
81
|
+
fig.show()
|
|
82
|
+
|
|
83
|
+
return fig
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: IBB_Helper
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: helper functions
|
|
5
|
+
Home-page: https://github.tik.uni-stuttgart.de/st193984/IBB_helper.git
|
|
6
|
+
Author: IBB
|
|
7
|
+
Author-email: stud193984@stud.uni-stuttgart.de
|
|
8
|
+
License: custom
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: Other/Proprietary License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE.txt
|
|
14
|
+
Dynamic: author
|
|
15
|
+
Dynamic: author-email
|
|
16
|
+
Dynamic: classifier
|
|
17
|
+
Dynamic: description
|
|
18
|
+
Dynamic: description-content-type
|
|
19
|
+
Dynamic: home-page
|
|
20
|
+
Dynamic: license
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
Dynamic: summary
|
|
23
|
+
|
|
24
|
+
Matrix and Plotting Helper Toolkit
|
|
25
|
+
===================================
|
|
26
|
+
|
|
27
|
+
Author: Institut fuer Baustatik und Baudynamik,Universitaet Stuttgart
|
|
28
|
+
License: ADD LICENSE here
|
|
29
|
+
Version: 1.0
|
|
30
|
+
Date: July 2025
|
|
31
|
+
|
|
32
|
+
Description:
|
|
33
|
+
------------
|
|
34
|
+
This helper module provides a set of tools to make symbolic math, matrix visualization,
|
|
35
|
+
and plotting (2D/3D) more intuitive and presentation-friendly, especially when working
|
|
36
|
+
with SymPy, NumPy, Matplotlib, and Plotly in Jupyter Notebooks or other Python environments.
|
|
37
|
+
|
|
38
|
+
Modules Included:
|
|
39
|
+
-----------------
|
|
40
|
+
|
|
41
|
+
1. DMAT
|
|
42
|
+
- Pretty-prints a truncated matrix with optional decimal or rational evaluation.
|
|
43
|
+
|
|
44
|
+
2. DIS
|
|
45
|
+
- Nicely formats scalars, vectors, or matrices in LaTeX for display.
|
|
46
|
+
|
|
47
|
+
3. DIS_EI
|
|
48
|
+
- Computes and displays eigenvalues and eigenvectors using clean LaTeX formatting.
|
|
49
|
+
|
|
50
|
+
4. plot_2d
|
|
51
|
+
- Plots symbolic expressions or numeric datasets in 2D using Matplotlib.
|
|
52
|
+
|
|
53
|
+
5. plot_3d
|
|
54
|
+
- Plots symbolic 3D surfaces using Plotly for interactive visualization.
|
|
55
|
+
|
|
56
|
+
6. extend_plots
|
|
57
|
+
- Merges multiple plots side-by-side (e.g., shifted versions).
|
|
58
|
+
|
|
59
|
+
7. append_plots
|
|
60
|
+
- Stacks multiple Matplotlib or Plotly plots into one combined figure.
|
|
61
|
+
|
|
62
|
+
Dependencies:
|
|
63
|
+
-------------
|
|
64
|
+
- Python 3.8+
|
|
65
|
+
- numpy
|
|
66
|
+
- sympy
|
|
67
|
+
- matplotlib
|
|
68
|
+
- plotly
|
|
69
|
+
- IPython (for LaTeX rendering in notebooks)
|
|
70
|
+
|
|
71
|
+
How to Use:
|
|
72
|
+
-----------
|
|
73
|
+
1. Import the helper script:
|
|
74
|
+
>>> from your_module_name import *
|
|
75
|
+
|
|
76
|
+
2. Visualize a matrix:
|
|
77
|
+
>>> DMAT(np.array([[1, 2], [3, 4]]), name="A")
|
|
78
|
+
|
|
79
|
+
3. Display a symbolic expression:
|
|
80
|
+
>>> x = sp.Symbol('x')
|
|
81
|
+
>>> DIS(sp.sin(x)**2 + sp.cos(x)**2, name="Identity")
|
|
82
|
+
|
|
83
|
+
4. Plot a symbolic 2D graph:
|
|
84
|
+
>>> plot_2d([sp.sin(x), sp.cos(x)], var=(x, (-np.pi, np.pi)), labels=["sin(x)", "cos(x)"])
|
|
85
|
+
|
|
86
|
+
5. Plot a 3D surface:
|
|
87
|
+
>>> plot_3d(sp.sin(x*y), var=(x, (-2, 2), y, (-2, 2)), title="sin(xy) surface")
|
|
88
|
+
|
|
89
|
+
Notes:
|
|
90
|
+
------
|
|
91
|
+
- This toolkit is especially suited for education, math research, or lab reports
|
|
92
|
+
where symbolic clarity and visualization are critical.
|
|
93
|
+
- Functions are designed to handle both SymPy and NumPy formats seamlessly.
|
|
94
|
+
|
|
95
|
+
License:
|
|
96
|
+
--------
|
|
97
|
+
ADD RELEVANT
|
|
98
|
+
|
|
99
|
+
Contact:
|
|
100
|
+
--------
|
|
101
|
+
Name/Email
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
LICENSE.txt
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
setup.py
|
|
5
|
+
IBB_Helper/__init__.py
|
|
6
|
+
IBB_Helper/append_plots.py
|
|
7
|
+
IBB_Helper/dis.py
|
|
8
|
+
IBB_Helper/dis_ei.py
|
|
9
|
+
IBB_Helper/dmat.py
|
|
10
|
+
IBB_Helper/extend_plots.py
|
|
11
|
+
IBB_Helper/plot_2d.py
|
|
12
|
+
IBB_Helper/plot_3d.py
|
|
13
|
+
IBB_Helper.egg-info/PKG-INFO
|
|
14
|
+
IBB_Helper.egg-info/SOURCES.txt
|
|
15
|
+
IBB_Helper.egg-info/dependency_links.txt
|
|
16
|
+
IBB_Helper.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
IBB_Helper
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025, IBB
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: IBB_Helper
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: helper functions
|
|
5
|
+
Home-page: https://github.tik.uni-stuttgart.de/st193984/IBB_helper.git
|
|
6
|
+
Author: IBB
|
|
7
|
+
Author-email: stud193984@stud.uni-stuttgart.de
|
|
8
|
+
License: custom
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: Other/Proprietary License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE.txt
|
|
14
|
+
Dynamic: author
|
|
15
|
+
Dynamic: author-email
|
|
16
|
+
Dynamic: classifier
|
|
17
|
+
Dynamic: description
|
|
18
|
+
Dynamic: description-content-type
|
|
19
|
+
Dynamic: home-page
|
|
20
|
+
Dynamic: license
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
Dynamic: summary
|
|
23
|
+
|
|
24
|
+
Matrix and Plotting Helper Toolkit
|
|
25
|
+
===================================
|
|
26
|
+
|
|
27
|
+
Author: Institut fuer Baustatik und Baudynamik,Universitaet Stuttgart
|
|
28
|
+
License: ADD LICENSE here
|
|
29
|
+
Version: 1.0
|
|
30
|
+
Date: July 2025
|
|
31
|
+
|
|
32
|
+
Description:
|
|
33
|
+
------------
|
|
34
|
+
This helper module provides a set of tools to make symbolic math, matrix visualization,
|
|
35
|
+
and plotting (2D/3D) more intuitive and presentation-friendly, especially when working
|
|
36
|
+
with SymPy, NumPy, Matplotlib, and Plotly in Jupyter Notebooks or other Python environments.
|
|
37
|
+
|
|
38
|
+
Modules Included:
|
|
39
|
+
-----------------
|
|
40
|
+
|
|
41
|
+
1. DMAT
|
|
42
|
+
- Pretty-prints a truncated matrix with optional decimal or rational evaluation.
|
|
43
|
+
|
|
44
|
+
2. DIS
|
|
45
|
+
- Nicely formats scalars, vectors, or matrices in LaTeX for display.
|
|
46
|
+
|
|
47
|
+
3. DIS_EI
|
|
48
|
+
- Computes and displays eigenvalues and eigenvectors using clean LaTeX formatting.
|
|
49
|
+
|
|
50
|
+
4. plot_2d
|
|
51
|
+
- Plots symbolic expressions or numeric datasets in 2D using Matplotlib.
|
|
52
|
+
|
|
53
|
+
5. plot_3d
|
|
54
|
+
- Plots symbolic 3D surfaces using Plotly for interactive visualization.
|
|
55
|
+
|
|
56
|
+
6. extend_plots
|
|
57
|
+
- Merges multiple plots side-by-side (e.g., shifted versions).
|
|
58
|
+
|
|
59
|
+
7. append_plots
|
|
60
|
+
- Stacks multiple Matplotlib or Plotly plots into one combined figure.
|
|
61
|
+
|
|
62
|
+
Dependencies:
|
|
63
|
+
-------------
|
|
64
|
+
- Python 3.8+
|
|
65
|
+
- numpy
|
|
66
|
+
- sympy
|
|
67
|
+
- matplotlib
|
|
68
|
+
- plotly
|
|
69
|
+
- IPython (for LaTeX rendering in notebooks)
|
|
70
|
+
|
|
71
|
+
How to Use:
|
|
72
|
+
-----------
|
|
73
|
+
1. Import the helper script:
|
|
74
|
+
>>> from your_module_name import *
|
|
75
|
+
|
|
76
|
+
2. Visualize a matrix:
|
|
77
|
+
>>> DMAT(np.array([[1, 2], [3, 4]]), name="A")
|
|
78
|
+
|
|
79
|
+
3. Display a symbolic expression:
|
|
80
|
+
>>> x = sp.Symbol('x')
|
|
81
|
+
>>> DIS(sp.sin(x)**2 + sp.cos(x)**2, name="Identity")
|
|
82
|
+
|
|
83
|
+
4. Plot a symbolic 2D graph:
|
|
84
|
+
>>> plot_2d([sp.sin(x), sp.cos(x)], var=(x, (-np.pi, np.pi)), labels=["sin(x)", "cos(x)"])
|
|
85
|
+
|
|
86
|
+
5. Plot a 3D surface:
|
|
87
|
+
>>> plot_3d(sp.sin(x*y), var=(x, (-2, 2), y, (-2, 2)), title="sin(xy) surface")
|
|
88
|
+
|
|
89
|
+
Notes:
|
|
90
|
+
------
|
|
91
|
+
- This toolkit is especially suited for education, math research, or lab reports
|
|
92
|
+
where symbolic clarity and visualization are critical.
|
|
93
|
+
- Functions are designed to handle both SymPy and NumPy formats seamlessly.
|
|
94
|
+
|
|
95
|
+
License:
|
|
96
|
+
--------
|
|
97
|
+
ADD RELEVANT
|
|
98
|
+
|
|
99
|
+
Contact:
|
|
100
|
+
--------
|
|
101
|
+
Name/Email
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
Matrix and Plotting Helper Toolkit
|
|
2
|
+
===================================
|
|
3
|
+
|
|
4
|
+
Author: Institut fuer Baustatik und Baudynamik,Universitaet Stuttgart
|
|
5
|
+
License: ADD LICENSE here
|
|
6
|
+
Version: 1.0
|
|
7
|
+
Date: July 2025
|
|
8
|
+
|
|
9
|
+
Description:
|
|
10
|
+
------------
|
|
11
|
+
This helper module provides a set of tools to make symbolic math, matrix visualization,
|
|
12
|
+
and plotting (2D/3D) more intuitive and presentation-friendly, especially when working
|
|
13
|
+
with SymPy, NumPy, Matplotlib, and Plotly in Jupyter Notebooks or other Python environments.
|
|
14
|
+
|
|
15
|
+
Modules Included:
|
|
16
|
+
-----------------
|
|
17
|
+
|
|
18
|
+
1. DMAT
|
|
19
|
+
- Pretty-prints a truncated matrix with optional decimal or rational evaluation.
|
|
20
|
+
|
|
21
|
+
2. DIS
|
|
22
|
+
- Nicely formats scalars, vectors, or matrices in LaTeX for display.
|
|
23
|
+
|
|
24
|
+
3. DIS_EI
|
|
25
|
+
- Computes and displays eigenvalues and eigenvectors using clean LaTeX formatting.
|
|
26
|
+
|
|
27
|
+
4. plot_2d
|
|
28
|
+
- Plots symbolic expressions or numeric datasets in 2D using Matplotlib.
|
|
29
|
+
|
|
30
|
+
5. plot_3d
|
|
31
|
+
- Plots symbolic 3D surfaces using Plotly for interactive visualization.
|
|
32
|
+
|
|
33
|
+
6. extend_plots
|
|
34
|
+
- Merges multiple plots side-by-side (e.g., shifted versions).
|
|
35
|
+
|
|
36
|
+
7. append_plots
|
|
37
|
+
- Stacks multiple Matplotlib or Plotly plots into one combined figure.
|
|
38
|
+
|
|
39
|
+
Dependencies:
|
|
40
|
+
-------------
|
|
41
|
+
- Python 3.8+
|
|
42
|
+
- numpy
|
|
43
|
+
- sympy
|
|
44
|
+
- matplotlib
|
|
45
|
+
- plotly
|
|
46
|
+
- IPython (for LaTeX rendering in notebooks)
|
|
47
|
+
|
|
48
|
+
How to Use:
|
|
49
|
+
-----------
|
|
50
|
+
1. Import the helper script:
|
|
51
|
+
>>> from your_module_name import *
|
|
52
|
+
|
|
53
|
+
2. Visualize a matrix:
|
|
54
|
+
>>> DMAT(np.array([[1, 2], [3, 4]]), name="A")
|
|
55
|
+
|
|
56
|
+
3. Display a symbolic expression:
|
|
57
|
+
>>> x = sp.Symbol('x')
|
|
58
|
+
>>> DIS(sp.sin(x)**2 + sp.cos(x)**2, name="Identity")
|
|
59
|
+
|
|
60
|
+
4. Plot a symbolic 2D graph:
|
|
61
|
+
>>> plot_2d([sp.sin(x), sp.cos(x)], var=(x, (-np.pi, np.pi)), labels=["sin(x)", "cos(x)"])
|
|
62
|
+
|
|
63
|
+
5. Plot a 3D surface:
|
|
64
|
+
>>> plot_3d(sp.sin(x*y), var=(x, (-2, 2), y, (-2, 2)), title="sin(xy) surface")
|
|
65
|
+
|
|
66
|
+
Notes:
|
|
67
|
+
------
|
|
68
|
+
- This toolkit is especially suited for education, math research, or lab reports
|
|
69
|
+
where symbolic clarity and visualization are critical.
|
|
70
|
+
- Functions are designed to handle both SymPy and NumPy formats seamlessly.
|
|
71
|
+
|
|
72
|
+
License:
|
|
73
|
+
--------
|
|
74
|
+
ADD RELEVANT
|
|
75
|
+
|
|
76
|
+
Contact:
|
|
77
|
+
--------
|
|
78
|
+
Name/Email
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name='IBB_Helper',
|
|
5
|
+
version='0.1.2',
|
|
6
|
+
packages=find_packages(),
|
|
7
|
+
install_requires=[],
|
|
8
|
+
author='IBB',
|
|
9
|
+
author_email='stud193984@stud.uni-stuttgart.de',
|
|
10
|
+
description='helper functions',
|
|
11
|
+
long_description=open('README.md').read(),
|
|
12
|
+
long_description_content_type='text/markdown',
|
|
13
|
+
url='https://github.tik.uni-stuttgart.de/st193984/IBB_helper.git',
|
|
14
|
+
license="custom",
|
|
15
|
+
classifiers=[
|
|
16
|
+
'Programming Language :: Python :: 3',
|
|
17
|
+
'License :: Other/Proprietary License',
|
|
18
|
+
'Operating System :: OS Independent',
|
|
19
|
+
],
|
|
20
|
+
)
|