smpl 1.5.3.dev5__tar.gz → 1.5.4__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 (64) hide show
  1. {smpl-1.5.3.dev5 → smpl-1.5.4}/PKG-INFO +1 -1
  2. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/_version.py +2 -2
  3. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/fit.py +23 -2
  4. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/plot.py +46 -4
  5. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/plot2d.py +3 -3
  6. smpl-1.5.4/test_chi2_r2_legend.png +0 -0
  7. smpl-1.5.4/test_chi2_r2_legend.py +29 -0
  8. smpl-1.5.4/test_chi2_uncertainty.py +0 -0
  9. smpl-1.5.4/test_dof_append.py +33 -0
  10. {smpl-1.5.3.dev5 → smpl-1.5.4}/.github/dependabot.yml +0 -0
  11. {smpl-1.5.3.dev5 → smpl-1.5.4}/.github/workflows/ci.yml +0 -0
  12. {smpl-1.5.3.dev5 → smpl-1.5.4}/.gitignore +0 -0
  13. {smpl-1.5.3.dev5 → smpl-1.5.4}/.pre-commit-config.yaml +0 -0
  14. {smpl-1.5.3.dev5 → smpl-1.5.4}/.readthedocs.yml +0 -0
  15. {smpl-1.5.3.dev5 → smpl-1.5.4}/LICENSE +0 -0
  16. {smpl-1.5.3.dev5 → smpl-1.5.4}/Makefile +0 -0
  17. {smpl-1.5.3.dev5 → smpl-1.5.4}/README.md +0 -0
  18. {smpl-1.5.3.dev5 → smpl-1.5.4}/pyproject.toml +0 -0
  19. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/__init__.py +0 -0
  20. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/animation/__init__.py +0 -0
  21. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/animation/animation.py +0 -0
  22. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/data.py +0 -0
  23. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/debug/__init__.py +0 -0
  24. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/debug/debug.py +0 -0
  25. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/doc/__init__.py +0 -0
  26. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/doc/doc.py +0 -0
  27. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/functions.py +0 -0
  28. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/interpolate.py +0 -0
  29. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/io/__init__.py +0 -0
  30. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/io/cat.py +0 -0
  31. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/io/grep.py +0 -0
  32. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/io/head.py +0 -0
  33. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/io/io.py +0 -0
  34. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/io/read_buffer.py +0 -0
  35. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/io/sed.py +0 -0
  36. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/io/tail.py +0 -0
  37. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/latex.py +0 -0
  38. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/parallel/__init__.py +0 -0
  39. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/parallel/parallel.py +0 -0
  40. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/stat.py +0 -0
  41. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/util/__init__.py +0 -0
  42. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/util/util.py +0 -0
  43. {smpl-1.5.3.dev5 → smpl-1.5.4}/smpl/wrap.py +0 -0
  44. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/fit/test_fit_algos.py +0 -0
  45. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/mpl/baseline/test_data.png +0 -0
  46. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/mpl/baseline/test_fit.png +0 -0
  47. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/mpl/baseline/test_fit_lambda.png +0 -0
  48. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/mpl/baseline/test_fit_str.png +0 -0
  49. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/mpl/baseline/test_grid.png +0 -0
  50. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/mpl/baseline/test_style_image.png +0 -0
  51. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/mpl/baseline/test_style_pcolormesh.png +0 -0
  52. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/mpl/baseline/test_style_scatter.png +0 -0
  53. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/mpl/baseline/test_xscale.png +0 -0
  54. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/mpl/baseline/test_yscale.png +0 -0
  55. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/mpl/test_mpl_fit.py +0 -0
  56. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/mpl/test_mpl_plot2d.py +0 -0
  57. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/mpl/test_mpl_smplr.py +0 -0
  58. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/plot/test_fit.py +0 -0
  59. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/plot/test_plot.py +0 -0
  60. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/test_animation.py +0 -0
  61. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/test_linear.txt +0 -0
  62. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/test_wrap.py +0 -0
  63. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/tests/test_line_profiling.py +0 -0
  64. {smpl-1.5.3.dev5 → smpl-1.5.4}/tests/tests/test_line_profiling_doctests.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: smpl
3
- Version: 1.5.3.dev5
3
+ Version: 1.5.4
4
4
  Summary: SiMPLe plotting and fitting
5
5
  Project-URL: Documentation, https://smpl.readthedocs.io/
6
6
  Project-URL: Issues, https://github.com/APN-Pucky/smpl/issues
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '1.5.3.dev5'
21
- __version_tuple__ = version_tuple = (1, 5, 3, 'dev5')
20
+ __version__ = version = '1.5.4'
21
+ __version_tuple__ = version_tuple = (1, 5, 4)
@@ -236,8 +236,29 @@ def _unwrap_param(fitt, fixed, Ntot):
236
236
  def Chi2(datax, datay, function, ff, **kwargs):
237
237
  kwargs = fit_kwargs(kwargs)
238
238
  x, y, _, yerr = fit_split(datax, datay, **kwargs)
239
- sigmas = yerr
240
- return stat.Chi2(y, unv(function(x, *ff)), sigmas)
239
+ f = function(x, *ff)
240
+ sigmas = (yerr**2 + usd(f) ** 2) ** 0.5
241
+ return stat.Chi2(y, unv(f), sigmas)
242
+
243
+
244
+ def Dof(datax, datay, function, ff, **kwargs):
245
+ """Calculate the degrees of freedom for a fit."""
246
+ kwargs = fit_kwargs(kwargs)
247
+ x, y, _, yerr = fit_split(datax, datay, **kwargs)
248
+ f = function(x, *ff)
249
+
250
+ # Obtain the number of fitted parameters
251
+ # by counting the number of non-fixed parameters
252
+ # This assumes that the fit function has parameters
253
+ # in the order: x, param1, param2, ..., paramN
254
+ # and that fixed parameters are provided in kwargs
255
+ _, _, fixed, Ntot = _wrap_func_and_param(function, **kwargs)
256
+
257
+ # Number of points fitted
258
+ N_points = len(y)
259
+
260
+ # Fixed parameters do not count towards degrees of freedom
261
+ return N_points - Ntot + len(fixed)
241
262
 
242
263
 
243
264
  @doc.insert_doc(stat.R2)
@@ -214,6 +214,9 @@ default = {
214
214
  "xspace gets called with xspace(xmin,xmax,steps) in :func:`function` to get the points of the function that will be drawn.",
215
215
  ],
216
216
  "alpha": [0.2, "alpha value for the fill_between plot"],
217
+ "append_chi2": [False, "Append chi2 to legend"],
218
+ "append_r2": [False, "Append r2 to legend"],
219
+ "append_dof": [False, "Append degrees of freedom to legend"],
217
220
  }
218
221
 
219
222
 
@@ -272,11 +275,11 @@ def fit(func, *adata, **kwargs):
272
275
  1.0
273
276
 
274
277
  """
275
- if "xaxis" in kwargs and not kwargs["xlabel"]:
278
+ if "xaxis" in kwargs and ("xlabel" not in kwargs or not kwargs["xlabel"]):
276
279
  # warnings.warn("xaxis is deprecated. Use xlabel instead.", DeprecationWarning, 2)
277
280
  kwargs["xlabel"] = kwargs["xaxis"]
278
281
  # TODO maybe pop
279
- if "yaxis" in kwargs and not kwargs["ylabel"]:
282
+ if "yaxis" in kwargs and ("ylabel" not in kwargs or not kwargs["ylabel"]):
280
283
  # warnings.warn("yaxis is deprecated. Use ylabel instead.", DeprecationWarning, 2)
281
284
  kwargs["ylabel"] = kwargs["yaxis"]
282
285
  # TODO maybe pop
@@ -555,6 +558,9 @@ def __function(
555
558
  "steps",
556
559
  "interpolator",
557
560
  "next_color",
561
+ "append_chi2",
562
+ "append_r2",
563
+ "append_dof",
558
564
  ]:
559
565
  kwargs.pop(key, None)
560
566
  func = gfunc
@@ -799,7 +805,7 @@ def plt_data(datax, datay, **kwargs):
799
805
  return ll
800
806
 
801
807
 
802
- def get_fnc_legend(function, rfit, **kwargs):
808
+ def get_fnc_legend(function, rfit, datax=None, datay=None, **kwargs):
803
809
  l = wrap.get_latex(function)
804
810
 
805
811
  vnames = wrap.get_varnames(function, kwargs["xvar"])
@@ -817,6 +823,42 @@ def get_fnc_legend(function, rfit, **kwargs):
817
823
  l = l + ")"
818
824
  if kwargs["units"] is not None:
819
825
  l = l + " " + kwargs["units"][i - 1]
826
+
827
+ # Append Chi2, R2, and DOF if requested and data is available
828
+ if datax is not None and datay is not None:
829
+ if kwargs.get("append_chi2", False):
830
+ try:
831
+ chi2_val = ffit.Chi2(datax, datay, function, rfit, **kwargs)
832
+ l = l + ("\n" if not kwargs["fitinline"] else " ")
833
+ if "number_format" in kwargs:
834
+ l = l + "$\\chi^2$=" + kwargs["number_format"].format(chi2_val)
835
+ else:
836
+ l = l + "$\\chi^2$=%s" % (chi2_val)
837
+ except Exception:
838
+ pass # Ignore errors in Chi2 calculation
839
+
840
+ if kwargs.get("append_r2", False):
841
+ try:
842
+ r2_val = ffit.R2(datax, datay, function, rfit, **kwargs)
843
+ l = l + ("\n" if not kwargs["fitinline"] else " ")
844
+ if "number_format" in kwargs:
845
+ l = l + "$R^2$=" + kwargs["number_format"].format(r2_val)
846
+ else:
847
+ l = l + "$R^2$=%s" % (r2_val)
848
+ except Exception:
849
+ pass # Ignore errors in R2 calculation
850
+
851
+ if kwargs.get("append_dof", False):
852
+ try:
853
+ dof_val = ffit.Dof(datax, datay, function, rfit, **kwargs)
854
+ l = l + ("\n" if not kwargs["fitinline"] else " ")
855
+ if "number_format" in kwargs:
856
+ l = l + "DOF=" + kwargs["number_format"].format(dof_val)
857
+ else:
858
+ l = l + "DOF=%s" % (dof_val)
859
+ except Exception:
860
+ pass # Ignore errors in DOF calculation
861
+
820
862
  return l
821
863
 
822
864
 
@@ -906,7 +948,7 @@ def plt_fit(datax, datay, gfunction, **kwargs):
906
948
  for v in vnames[1:]: # remove fixed parameters from kwargs
907
949
  kwargs.pop(v, None)
908
950
 
909
- l = get_fnc_legend(gfunction, rfit, **kwargs)
951
+ l = get_fnc_legend(gfunction, rfit, datax, datay, **kwargs)
910
952
  return (rfit, *plt_fit_or_interpolate(datax, datay, fitted, l, **kwargs))
911
953
 
912
954
 
@@ -53,13 +53,13 @@ def plot2d(datax, datay, dataz, **kwargs):
53
53
  see :func:`plot2d_kwargs`.
54
54
  """
55
55
  kwargs = plot2d_kwargs(kwargs)
56
- if "xaxis" in kwargs and not kwargs["xlabel"]:
56
+ if "xaxis" in kwargs and ("xlabel" not in kwargs or not kwargs["xlabel"]):
57
57
  # warnings.warn("xaxis is deprecated. Use xlabel instead.", DeprecationWarning, 2)
58
58
  kwargs["xlabel"] = kwargs["xaxis"]
59
- if "yaxis" in kwargs and not kwargs["ylabel"]:
59
+ if "yaxis" in kwargs and ("ylabel" not in kwargs or not kwargs["ylabel"]):
60
60
  # warnings.warn("yaxis is deprecated. Use ylabel instead.", DeprecationWarning, 2)
61
61
  kwargs["ylabel"] = kwargs["yaxis"]
62
- if "zaxis" in kwargs and not kwargs["zlabel"]:
62
+ if "zaxis" in kwargs and ("zlabel" not in kwargs or not kwargs["zlabel"]):
63
63
  # warnings.warn("zaxis is deprecated. Use zlabel instead.", DeprecationWarning, 2)
64
64
  kwargs["zlabel"] = kwargs["zaxis"]
65
65
 
Binary file
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env python3
2
+ """Test script for append_chi2 and append_r2 functionality."""
3
+
4
+ import numpy as np
5
+ import matplotlib.pyplot as plt
6
+ from smpl import plot, functions
7
+
8
+ # Generate some test data
9
+ np.random.seed(42)
10
+ x = np.linspace(0, 10, 50)
11
+ y_true = 2 * x + 3 # linear function: y = 2x + 3
12
+ y = y_true + np.random.normal(0, 1, len(x)) # add some noise
13
+
14
+ # Test 1: Basic fit without chi2/r2
15
+ print("Test 1: Basic fit without chi2/r2")
16
+ plt.figure(figsize=(12, 4))
17
+
18
+ # Test 2: Fit with chi2 appended
19
+ print("Test 2: Fit with chi2 appended")
20
+ params2 = plot.fit(x, y, functions.line, label="With Chi2", append_chi2=True, init=True,fselector=lambda x,y : (x<2))
21
+ plt.title("With Chi2")
22
+ plt.legend()
23
+
24
+
25
+ plt.tight_layout()
26
+ plt.savefig("test_chi2_r2_legend.png", dpi=150, bbox_inches='tight')
27
+ plt.show()
28
+
29
+ print("Test completed successfully!")
File without changes
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env python3
2
+ """Test script for append_dof functionality."""
3
+
4
+ import numpy as np
5
+ import matplotlib.pyplot as plt
6
+ from smpl import plot, functions
7
+
8
+ # Generate test data
9
+ x = np.linspace(0, 5, 20)
10
+ y = 2 * x + 1 + np.random.normal(0, 0.5, len(x)) # Linear with noise
11
+
12
+ print("Testing append_dof functionality...")
13
+
14
+ # Test 1: Basic fit without DOF
15
+ print("Test 1: Basic fit without DOF")
16
+ params1 = plot.fit(x, y, functions.line, label="Without DOF", init=True)
17
+ plt.title("Without DOF")
18
+ plt.show()
19
+
20
+ # Test 2: Fit with DOF appended
21
+ print("Test 2: Fit with DOF appended")
22
+ params2 = plot.fit(x, y, functions.line, label="With DOF", append_dof=True, init=True)
23
+ plt.title("With DOF")
24
+ plt.show()
25
+
26
+ # Test 3: Fit with Chi2, R2, and DOF all appended
27
+ print("Test 3: Fit with Chi2, R2, and DOF all appended")
28
+ params3 = plot.fit(x, y, functions.line, label="Complete stats",
29
+ append_chi2=True, append_r2=True, append_dof=True, init=True)
30
+ plt.title("With Chi2, R2, and DOF")
31
+ plt.show()
32
+
33
+ print("DOF test completed!")
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
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
File without changes