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 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 desireable, opens the svg as a temp file, else opens
748
- the file from the actual location using the system's default viewer (defaults to
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 (defaults to
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: just do naive **
784
+ # Fallback: naive ** -> ^
780
785
  return expr_tmp.replace("**", "^")
781
786
 
782
- def handle_open_and_save(
783
- svg_string: str,
784
- open_file: bool,
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(save_path, 'w', encoding='utf-8') as file:
791
+ with open(path, 'w', encoding='utf-8') as file:
791
792
  file.write(svg_string)
792
- print(f"[INFO] SVG saved to: {save_path}")
793
+ print(f"[INFO] SVG saved to: {path}")
793
794
  except IOError as e:
794
- print(f"[ERROR] Failed to save SVG to {save_path}. IOError: {e}")
795
+ print(f"[ERROR] Failed to save SVG to {path}. IOError: {e}")
795
796
 
796
797
  # Handle opening the file if requested
797
- if open_file and save_path:
798
- result = subprocess.run(["xdg-open", save_path], stderr=subprocess.DEVNULL)
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 open_file:
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, sub_dict = list(entry.items())[0]
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 sub-dict lacks 'x' key.")
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"Error evaluating expression '{expression}': {e}")
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 y_values is shorter than x_values (like np.diff), truncate x
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 nice LaTeX string
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
- # Show legend
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.53
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
- ![Plot](./media/plot_polynomial_functions_example_1.svg)
553
+ ![Plot](./media/plot_polynomial_functions_example_1.svg)
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=AcGurkWyq3sd-HXPqUDnioEyiYwC_H70PBkJHOcXO7I,35183
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.53.dist-info/LICENSE,sha256=7EI8xVBu6h_7_JlVw-yPhhOZlpY9hP8wal7kHtqKT_E,1074
8
- rgwfuncs-0.0.53.dist-info/METADATA,sha256=dkIVCAMIVUoI1teXGoalzHFYQT1usUebDMG5Mr6bafE,57140
9
- rgwfuncs-0.0.53.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
10
- rgwfuncs-0.0.53.dist-info/entry_points.txt,sha256=j-c5IOPIQ0252EaOV6j6STio56sbXl2C4ym_fQ0lXx0,43
11
- rgwfuncs-0.0.53.dist-info/top_level.txt,sha256=aGuVIzWsKiV1f2gCb6mynx0zx5ma0B1EwPGFKVEMTi4,9
12
- rgwfuncs-0.0.53.dist-info/RECORD,,
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,,