From 6ed357b51dac6e8ad4df24cffc8410a04a738009 Mon Sep 17 00:00:00 2001 From: Fabian Joswig Date: Wed, 18 Jan 2023 15:03:08 +0000 Subject: [PATCH 1/3] feat: Added wrapper for errorbar matplotlib method for more convenient plotting. --- pyerrors/misc.py | 35 +++++++++++++++++++++++++++++++++++ tests/misc_test.py | 17 +++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 tests/misc_test.py diff --git a/pyerrors/misc.py b/pyerrors/misc.py index 0cd95f86..13e99565 100644 --- a/pyerrors/misc.py +++ b/pyerrors/misc.py @@ -1,8 +1,43 @@ import pickle import numpy as np +import matplotlib.pyplot as plt from .obs import Obs +def errorbar(x, y, axes=plt, *args, **kwargs): + """pyerrors wrapper for the errorbars method fo matplotlib + + Parameters + ---------- + x : list + A list of x-values. It can be a list of Obs objects or int/float. + y : list + A list of y-values. It should be a list of Obs objects. + axes : (matplotlib.pyplot.axes) + The axes to plot on. default is plt. + """ + if not all(isinstance(o, Obs) for o in y): + raise Exception("All entries of 'y' have to be Obs") + + if all(isinstance(o, Obs) for o in x): + if not all(hasattr(o, 'e_dvalue') for o in x): + [o.gamma_method() for o in x] + xval = [o.value for o in x] + xerr = [o.dvalue for o in x] + elif all(isinstance(o, (int, float, np.integer)) for o in x): + xval = x + xerr = None + else: + raise Exception("All entries of 'x' have to be of the same type (int, float or Obs)") + + if not all(hasattr(o, 'e_dvalue') for o in y): + [o.gamma_method() for o in y] + yval = [o.value for o in y] + yerr = [o.dvalue for o in y] + + axes.errorbar(xval, yval, *args, xerr=xerr, yerr=yerr, **kwargs) + + def dump_object(obj, name, **kwargs): """Dump object into pickle file. diff --git a/tests/misc_test.py b/tests/misc_test.py new file mode 100644 index 00000000..a4d1e13d --- /dev/null +++ b/tests/misc_test.py @@ -0,0 +1,17 @@ +import numpy as np +import matplotlib.pyplot as plt +import pyerrors as pe +import pytest + + +def test_obs_errorbar(): + x_float = np.arange(5) + x_obs = [] + y_obs = [] + for x in x_float: + x_obs.append(pe.pseudo_Obs(x, 0.1, "test")) + y_obs.append(pe.pseudo_Obs(x ** 2, 0.1, "test")) + + pe.errorbar(x_float, y_obs, marker="x", ms=2) + pe.errorbar(x_obs, y_obs, marker="x", ms=2) + From c03e4669a0d8a4a44da6431371156bb77042f41b Mon Sep 17 00:00:00 2001 From: Fabian Joswig Date: Wed, 18 Jan 2023 17:01:37 +0000 Subject: [PATCH 2/3] tests: additional tests for generalization of misc.errorbar added. --- tests/misc_test.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/misc_test.py b/tests/misc_test.py index a4d1e13d..3211a806 100644 --- a/tests/misc_test.py +++ b/tests/misc_test.py @@ -12,6 +12,9 @@ def test_obs_errorbar(): x_obs.append(pe.pseudo_Obs(x, 0.1, "test")) y_obs.append(pe.pseudo_Obs(x ** 2, 0.1, "test")) - pe.errorbar(x_float, y_obs, marker="x", ms=2) - pe.errorbar(x_obs, y_obs, marker="x", ms=2) + for xerr in [2, None]: + for yerr in [0.1, None]: + pe.errorbar(x_float, y_obs, marker="x", ms=2, xerr=xerr, yerr=yerr) + pe.errorbar(x_obs, y_obs, marker="x", ms=2, xerr=xerr, yerr=yerr) + plt.close('all') From c475ca53a5e92447e937fc586c367042db6be4d7 Mon Sep 17 00:00:00 2001 From: Fabian Joswig Date: Wed, 18 Jan 2023 17:02:08 +0000 Subject: [PATCH 3/3] feat: misc.errorbar can now also process non Obs data and xerr, yerr can be passed to overwrite the Obs's errors. Co-authored-by: Simon Kuberski --- pyerrors/misc.py | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/pyerrors/misc.py b/pyerrors/misc.py index 13e99565..962b91c5 100644 --- a/pyerrors/misc.py +++ b/pyerrors/misc.py @@ -4,38 +4,35 @@ import matplotlib.pyplot as plt from .obs import Obs -def errorbar(x, y, axes=plt, *args, **kwargs): - """pyerrors wrapper for the errorbars method fo matplotlib +def errorbar(x, y, axes=plt, **kwargs): + """pyerrors wrapper for the errorbars method of matplotlib Parameters ---------- x : list - A list of x-values. It can be a list of Obs objects or int/float. + A list of x-values which can be Obs. y : list - A list of y-values. It should be a list of Obs objects. + A list of y-values which can be Obs. axes : (matplotlib.pyplot.axes) The axes to plot on. default is plt. """ - if not all(isinstance(o, Obs) for o in y): - raise Exception("All entries of 'y' have to be Obs") + val = {} + err = {} + for name, comp in zip(["x", "y"], [x, y]): + if all(isinstance(o, Obs) for o in comp): + if not all(hasattr(o, 'e_dvalue') for o in comp): + [o.gamma_method() for o in comp] + val[name] = [o.value for o in comp] + err[name] = [o.dvalue for o in comp] + else: + val[name] = comp + err[name] = None - if all(isinstance(o, Obs) for o in x): - if not all(hasattr(o, 'e_dvalue') for o in x): - [o.gamma_method() for o in x] - xval = [o.value for o in x] - xerr = [o.dvalue for o in x] - elif all(isinstance(o, (int, float, np.integer)) for o in x): - xval = x - xerr = None - else: - raise Exception("All entries of 'x' have to be of the same type (int, float or Obs)") + if f"{name}err" in kwargs: + err[name] = kwargs.get(f"{name}err") + kwargs.pop(f"{name}err", None) - if not all(hasattr(o, 'e_dvalue') for o in y): - [o.gamma_method() for o in y] - yval = [o.value for o in y] - yerr = [o.dvalue for o in y] - - axes.errorbar(xval, yval, *args, xerr=xerr, yerr=yerr, **kwargs) + axes.errorbar(val["x"], val["y"], xerr=err["x"], yerr=err["y"], **kwargs) def dump_object(obj, name, **kwargs):