rgwfuncs 0.0.53__py3-none-any.whl → 0.0.55__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.
- rgwfuncs/algebra_lib.py +54 -38
- {rgwfuncs-0.0.53.dist-info → rgwfuncs-0.0.55.dist-info}/METADATA +2 -2
- {rgwfuncs-0.0.53.dist-info → rgwfuncs-0.0.55.dist-info}/RECORD +7 -7
- {rgwfuncs-0.0.53.dist-info → rgwfuncs-0.0.55.dist-info}/LICENSE +0 -0
- {rgwfuncs-0.0.53.dist-info → rgwfuncs-0.0.55.dist-info}/WHEEL +0 -0
- {rgwfuncs-0.0.53.dist-info → rgwfuncs-0.0.55.dist-info}/entry_points.txt +0 -0
- {rgwfuncs-0.0.53.dist-info → rgwfuncs-0.0.55.dist-info}/top_level.txt +0 -0
rgwfuncs/algebra_lib.py
CHANGED
@@ -744,12 +744,12 @@ def plot_polynomial_functions(
|
|
744
744
|
show_legend : bool
|
745
745
|
Whether to add a legend to the plot (defaults to True).
|
746
746
|
open_file : bool
|
747
|
-
If saving to path is not
|
748
|
-
the file from the actual location using the system's
|
749
|
-
False).
|
747
|
+
If saving to path is not desirable, opens the SVG as a temp file;
|
748
|
+
otherwise opens the file from the actual location using the system's
|
749
|
+
default viewer (defaults to False).
|
750
750
|
save_path : Optional[str]
|
751
|
-
If specified, saves the output string as a .svg at the indicated path
|
752
|
-
None).
|
751
|
+
If specified, saves the output string as a .svg at the indicated path
|
752
|
+
(defaults to None).
|
753
753
|
|
754
754
|
Returns
|
755
755
|
-------
|
@@ -772,33 +772,34 @@ def plot_polynomial_functions(
|
|
772
772
|
|
773
773
|
expr_tmp = re.sub(DIFF_PATTERN, diff_replacer, expr_str)
|
774
774
|
expr_tmp = expr_tmp.replace("np.", "")
|
775
|
+
|
776
|
+
# Attempt to convert basic Pythonic polynomial expressions to LaTeX
|
775
777
|
try:
|
778
|
+
# Suppose you have a helper function python_polynomial_expression_to_latex
|
779
|
+
# If not, you can do a naive replacement or skip
|
780
|
+
from python_latex_helpers import python_polynomial_expression_to_latex
|
776
781
|
latex_expr = python_polynomial_expression_to_latex(expr_tmp)
|
777
782
|
return latex_expr
|
778
783
|
except Exception:
|
779
|
-
# Fallback:
|
784
|
+
# Fallback: naive ** -> ^
|
780
785
|
return expr_tmp.replace("**", "^")
|
781
786
|
|
782
|
-
def handle_open_and_save(
|
783
|
-
|
784
|
-
|
785
|
-
save_path: Optional[str]
|
786
|
-
) -> None:
|
787
|
-
# Save the SVG to a file if a save path is provided
|
788
|
-
if save_path:
|
787
|
+
def handle_open_and_save(svg_string: str, open_it: bool, path: Optional[str]) -> None:
|
788
|
+
# Save the SVG to a file if a path is provided
|
789
|
+
if path:
|
789
790
|
try:
|
790
|
-
with open(
|
791
|
+
with open(path, 'w', encoding='utf-8') as file:
|
791
792
|
file.write(svg_string)
|
792
|
-
print(f"[INFO] SVG saved to: {
|
793
|
+
print(f"[INFO] SVG saved to: {path}")
|
793
794
|
except IOError as e:
|
794
|
-
print(f"[ERROR] Failed to save SVG to {
|
795
|
+
print(f"[ERROR] Failed to save SVG to {path}. IOError: {e}")
|
795
796
|
|
796
797
|
# Handle opening the file if requested
|
797
|
-
if
|
798
|
-
result = subprocess.run(["xdg-open",
|
798
|
+
if open_it and path:
|
799
|
+
result = subprocess.run(["xdg-open", path], stderr=subprocess.DEVNULL)
|
799
800
|
if result.returncode != 0:
|
800
801
|
print("[ERROR] Failed to open the SVG file with the default viewer.")
|
801
|
-
elif
|
802
|
+
elif open_it:
|
802
803
|
with tempfile.NamedTemporaryFile(delete=False, suffix=".svg") as tmpfile:
|
803
804
|
temp_svg_path = tmpfile.name
|
804
805
|
tmpfile.write(svg_string.encode('utf-8'))
|
@@ -810,60 +811,76 @@ def plot_polynomial_functions(
|
|
810
811
|
fig, ax = plt.subplots()
|
811
812
|
|
812
813
|
for entry in functions:
|
814
|
+
# Each entry is something like {"x**2": {"x": "*", "a": ...}}
|
813
815
|
if len(entry) != 1:
|
814
|
-
print("Skipping invalid item. Must have exactly 1 expression->substitutions pair.")
|
816
|
+
print("[WARNING] Skipping invalid item. Must have exactly 1 expression->substitutions pair.")
|
815
817
|
continue
|
816
818
|
|
817
|
-
expression
|
819
|
+
# Extract the expression string and substitutions
|
820
|
+
expression, sub_dict = next(iter(entry.items()))
|
821
|
+
|
822
|
+
# Check presence of "x"
|
818
823
|
if "x" not in sub_dict:
|
819
|
-
print(f"Skipping '{expression}' because
|
824
|
+
print(f"[WARNING] Skipping '{expression}' because there is no 'x' key.")
|
820
825
|
continue
|
821
826
|
|
822
|
-
# If "x" is "*", create a default domain
|
823
827
|
x_val = sub_dict["x"]
|
828
|
+
|
829
|
+
# 1) If x == "*", generate from -zoom..+zoom
|
830
|
+
print("830", x_val)
|
831
|
+
print("830", type(x_val))
|
824
832
|
if isinstance(x_val, str) and x_val == "*":
|
825
833
|
x_values = np.linspace(-zoom, zoom, 1201)
|
826
|
-
sub_dict["x"] = x_values
|
834
|
+
sub_dict["x"] = x_values # might as well update it in place
|
835
|
+
# 2) If x is already a NumPy array, use as-is
|
827
836
|
elif isinstance(x_val, np.ndarray):
|
828
837
|
x_values = x_val
|
829
838
|
else:
|
830
|
-
print(f"Skipping '{expression}' because 'x' is neither '*' nor a NumPy array.")
|
839
|
+
print(f"[WARNING] Skipping '{expression}' because 'x' is neither '*' nor a NumPy array.")
|
831
840
|
continue
|
832
841
|
|
833
|
-
# Evaluate the expression
|
842
|
+
# Evaluate the expression with the variables from sub_dict
|
843
|
+
# We'll inject them into an eval() context, including 'np'
|
834
844
|
try:
|
835
845
|
eval_context = {"np": np}
|
846
|
+
# Put all user-provided variables (like a=1.23) in:
|
836
847
|
eval_context.update(sub_dict)
|
837
848
|
y_values = eval(expression, {"np": np}, eval_context)
|
838
849
|
except Exception as e:
|
839
|
-
print(f"
|
850
|
+
print(f"[ERROR] Could not evaluate '{expression}' -> {e}")
|
840
851
|
continue
|
841
852
|
|
853
|
+
# Check we got a NumPy array
|
842
854
|
if not isinstance(y_values, np.ndarray):
|
843
|
-
print(f"Skipping '{expression}' because it did not produce a NumPy array.")
|
855
|
+
print(f"[WARNING] Skipping '{expression}' because it did not produce a NumPy array.")
|
844
856
|
continue
|
845
857
|
|
846
|
-
# If
|
858
|
+
# If y is shorter (like np.diff), truncate x
|
847
859
|
if len(y_values) < len(x_values):
|
848
860
|
x_values = x_values[:len(y_values)]
|
849
861
|
|
850
|
-
# Convert expression to a
|
862
|
+
# Convert the expression to a LaTeX label
|
851
863
|
label_expr = latexify_expression(expression)
|
852
864
|
ax.plot(x_values, y_values, label=rf"${label_expr}$")
|
853
865
|
|
854
866
|
# Configure axes
|
855
867
|
ax.set_xlim(-zoom, zoom)
|
856
868
|
ax.set_ylim(-zoom, zoom)
|
869
|
+
|
870
|
+
# Place spines at center
|
857
871
|
ax.spines['left'].set_position('zero')
|
858
872
|
ax.spines['bottom'].set_position('zero')
|
873
|
+
# Hide the right and top spines
|
859
874
|
ax.spines['right'].set_color('none')
|
860
875
|
ax.spines['top'].set_color('none')
|
861
|
-
ax.set_aspect('equal', 'box')
|
862
876
|
ax.xaxis.set_ticks_position('bottom')
|
863
877
|
ax.yaxis.set_ticks_position('left')
|
878
|
+
|
879
|
+
# Ensure equal aspect ratio
|
880
|
+
ax.set_aspect('equal', 'box')
|
864
881
|
ax.grid(True)
|
865
882
|
|
866
|
-
#
|
883
|
+
# If requested, show the legend
|
867
884
|
if show_legend:
|
868
885
|
leg = ax.legend(
|
869
886
|
loc='upper center',
|
@@ -872,16 +889,15 @@ def plot_polynomial_functions(
|
|
872
889
|
shadow=True,
|
873
890
|
ncol=1
|
874
891
|
)
|
875
|
-
plt.savefig(
|
876
|
-
buffer,
|
877
|
-
format='svg',
|
878
|
-
bbox_inches='tight',
|
879
|
-
bbox_extra_artists=[leg] # ensures the legend is fully captured
|
880
|
-
)
|
892
|
+
plt.savefig(buffer, format='svg', bbox_inches='tight', bbox_extra_artists=[leg])
|
881
893
|
else:
|
882
894
|
plt.savefig(buffer, format='svg', bbox_inches='tight')
|
883
895
|
|
884
896
|
plt.close(fig)
|
885
897
|
svg_string = buffer.getvalue().decode('utf-8')
|
898
|
+
|
899
|
+
# Optionally open/save the file
|
886
900
|
handle_open_and_save(svg_string, open_file, save_path)
|
901
|
+
|
887
902
|
return svg_string
|
903
|
+
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: rgwfuncs
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.55
|
4
4
|
Summary: A functional programming paradigm for mathematical modelling and data science
|
5
5
|
Home-page: https://github.com/ryangerardwilson/rgwfunc
|
6
6
|
Author: Ryan Gerard Wilson
|
@@ -550,7 +550,7 @@ This function plots polynomial functions described by a list of expressions and
|
|
550
550
|
|
551
551
|
• Displaying the SVG:
|
552
552
|
|
553
|
-
|
553
|
+

|
554
554
|
|
555
555
|
--------------------------------------------------------------------------------
|
556
556
|
|
@@ -1,12 +1,12 @@
|
|
1
1
|
rgwfuncs/__init__.py,sha256=JjkuVeRV_Bkw8vnqSbJsRcYQRm4iCI3futR86cf3tRI,1637
|
2
|
-
rgwfuncs/algebra_lib.py,sha256=
|
2
|
+
rgwfuncs/algebra_lib.py,sha256=YlXv8R-xD4IQoTaatw9AQyAsi5lWh00K1huQ53figC8,36017
|
3
3
|
rgwfuncs/df_lib.py,sha256=qqRQdakheLy8wMZRBfHwKyIp8DmdZIWfAiLKWgq03QU,68977
|
4
4
|
rgwfuncs/docs_lib.py,sha256=y3wSAOPO3qsA4HZ7xAtW8HimM8w-c8hjcEzMRLJ96ao,1960
|
5
5
|
rgwfuncs/interactive_shell_lib.py,sha256=A7EWsYxAfDev_N0-2GjRvAtp0bAwBPHIczXb8Gu9fzI,1107
|
6
6
|
rgwfuncs/str_lib.py,sha256=rtAdRlnSJIu3JhI-tA_A0wCiPK2m-zn5RoGpBxv_g-4,2228
|
7
|
-
rgwfuncs-0.0.
|
8
|
-
rgwfuncs-0.0.
|
9
|
-
rgwfuncs-0.0.
|
10
|
-
rgwfuncs-0.0.
|
11
|
-
rgwfuncs-0.0.
|
12
|
-
rgwfuncs-0.0.
|
7
|
+
rgwfuncs-0.0.55.dist-info/LICENSE,sha256=7EI8xVBu6h_7_JlVw-yPhhOZlpY9hP8wal7kHtqKT_E,1074
|
8
|
+
rgwfuncs-0.0.55.dist-info/METADATA,sha256=2fr5olJy55MoAetAhCcPOsEVa6Ia3CGiDcKBnpiU-0g,57136
|
9
|
+
rgwfuncs-0.0.55.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
10
|
+
rgwfuncs-0.0.55.dist-info/entry_points.txt,sha256=j-c5IOPIQ0252EaOV6j6STio56sbXl2C4ym_fQ0lXx0,43
|
11
|
+
rgwfuncs-0.0.55.dist-info/top_level.txt,sha256=aGuVIzWsKiV1f2gCb6mynx0zx5ma0B1EwPGFKVEMTi4,9
|
12
|
+
rgwfuncs-0.0.55.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|