From 3e56ced8731923d65059b82bc0a6bca1a54437f3 Mon Sep 17 00:00:00 2001 From: s-weigand Date: Sun, 30 Jun 2024 13:22:34 +0200 Subject: [PATCH 1/6] =?UTF-8?q?=F0=9F=9A=A7=20Add=20requirements=5Fmin.txt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements_min.txt | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 requirements_min.txt diff --git a/requirements_min.txt b/requirements_min.txt new file mode 100644 index 00000000..0917a175 --- /dev/null +++ b/requirements_min.txt @@ -0,0 +1,8 @@ +# Minimum versions runtime dependencies + +cycler==0.10 +numpy==1.21.2 +matplotlib==3.3 +pyglotaran==0.7.2 +tabulate==0.8.9 +xarray==2022.3 From 75b7cfa323a47ac8a5643801d43ac27eef19fa5e Mon Sep 17 00:00:00 2001 From: s-weigand Date: Sun, 30 Jun 2024 14:14:05 +0200 Subject: [PATCH 2/6] =?UTF-8?q?=F0=9F=9A=87=F0=9F=A7=AA=20Add=20job=20to?= =?UTF-8?q?=20run=20tests=20with=20requirements=5Fmin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test.yml | 46 +++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 92319c32..e75a4f03 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -149,11 +149,55 @@ jobs: - name: Run tests run: python -m pytest --nbval --cov=./ --cov-report term --cov-report xml --cov-config pyproject.toml tests + - name: Codecov Upload + continue-on-error: true + uses: codecov/codecov-action@v4 + with: + file: ./coverage.xml + name: test-pyglotaran-dev + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + test-min-versions: + name: Test dependency min versions + runs-on: ubuntu-latest + needs: [pre-commit, docs] + + steps: + - name: Check out repo + uses: actions/checkout@v4 + + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install dependencies + run: | + python -m pip install -U pip wheel + python -m pip install -r requirements_min.txt + python -m pip install -e ".[test]" + + - name: Show installed dependencies + run: pip freeze + + - name: Run tests + run: python -m pytest --nbval --cov=./ --cov-report term --cov-report xml --cov-config pyproject.toml tests + + - name: Codecov Upload + continue-on-error: true + uses: codecov/codecov-action@v4 + with: + file: ./coverage.xml + name: test-min-versions + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + deploy: name: Deploy to PyPi runs-on: ubuntu-latest if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') - needs: test + needs: [test, test-pyglotaran-dev, test-min-versions] permissions: id-token: write # IMPORTANT: this permission is mandatory for trusted publishing steps: From 2701e9e9585faee44995b1e4392eaa67a2fda18d Mon Sep 17 00:00:00 2001 From: s-weigand Date: Sun, 30 Jun 2024 14:05:47 +0200 Subject: [PATCH 3/6] =?UTF-8?q?=E2=9C=A8=20Add=20matplotlib=20<=203.8=20an?= =?UTF-8?q?d=20>=3D3.8=20compatible=20cycler=20call=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyglotaran_extras/plotting/utils.py | 23 +++++++++++++++++++++++ pyglotaran_extras/types.py | 12 ++++++++++++ tests/plotting/test_utils.py | 12 ++++-------- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/pyglotaran_extras/plotting/utils.py b/pyglotaran_extras/plotting/utils.py index 69c38711..865400aa 100644 --- a/pyglotaran_extras/plotting/utils.py +++ b/pyglotaran_extras/plotting/utils.py @@ -28,6 +28,7 @@ from matplotlib.pyplot import Axes from pyglotaran_extras.types import BuiltinSubPlotLabelFormatFunctionKey + from pyglotaran_extras.types import CyclerColor from pyglotaran_extras.types import ResultLike from pyglotaran_extras.types import SubPlotLabelCoord @@ -215,6 +216,28 @@ def add_unique_figure_legend(fig: Figure, axes: Axes) -> None: fig.legend(*zip(*unique, strict=True)) +def get_next_cycler_color(ax: Axes) -> CyclerColor: + """Get next color from cycler assigned to ``ax``. + + Note + ---- + This will advance the cycler to the next state. + + Parameters + ---------- + ax : Axes + Axes to get the color from. + + Returns + ------- + CyclerColor + """ + # Matplotlib<3.8 compat + if hasattr(ax._get_lines, "prop_cycler"): + return next(ax._get_lines.prop_cycler) + return {"color": ax._get_lines.get_next_color()} + + def select_plot_wavelengths( result: ResultLike, axes_shape: tuple[int, int] = (4, 4), diff --git a/pyglotaran_extras/types.py b/pyglotaran_extras/types.py index 17b62d40..cbf013d0 100644 --- a/pyglotaran_extras/types.py +++ b/pyglotaran_extras/types.py @@ -5,12 +5,17 @@ from collections.abc import Mapping from collections.abc import Sequence from pathlib import Path +from typing import TYPE_CHECKING from typing import Literal from typing import TypeAlias +from typing import TypedDict import xarray as xr from glotaran.project.result import Result +if TYPE_CHECKING: + from pyglotaran_extras.plotting.style import ColorCode + class UnsetType: """Type for the ``Unset`` singleton.""" @@ -26,6 +31,13 @@ def __repr__(self) -> str: # noqa: DOC This way we can prevent regressions. """ + +class CyclerColor(TypedDict): + """Color value returned by a cycler.""" + + color: str | ColorCode + + DatasetConvertible: TypeAlias = xr.Dataset | xr.DataArray | str | Path """Types of data which can be converted to a dataset.""" ResultLike: TypeAlias = ( diff --git a/tests/plotting/test_utils.py b/tests/plotting/test_utils.py index bc5cb326..41c21e16 100644 --- a/tests/plotting/test_utils.py +++ b/tests/plotting/test_utils.py @@ -17,6 +17,7 @@ from pyglotaran_extras.plotting.utils import calculate_ticks_in_units_of_pi from pyglotaran_extras.plotting.utils import ensure_axes_array from pyglotaran_extras.plotting.utils import format_sub_plot_number_upper_case_letter +from pyglotaran_extras.plotting.utils import get_next_cycler_color from pyglotaran_extras.plotting.utils import not_single_element_dims if TYPE_CHECKING: @@ -42,11 +43,9 @@ def test_add_cycler_if_not_none_single_axis(cycler: Cycler | None, expected_cycl ax = plt.subplot() add_cycler_if_not_none(ax, cycler) - ax_cycler = iter(ax._get_lines._cycler_items) - for _ in range(10): expected = next(expected_cycler) - assert next(ax_cycler) == expected + assert get_next_cycler_color(ax) == expected @pytest.mark.parametrize( @@ -58,13 +57,10 @@ def test_add_cycler_if_not_none_multiple_axes(cycler: Cycler | None, expected_cy _, axes = plt.subplots(1, 2) add_cycler_if_not_none(axes, cycler) - ax0_cycler = iter(axes[0]._get_lines._cycler_items) - ax1_cycler = iter(axes[1]._get_lines._cycler_items) - for _ in range(10): expected = next(expected_cycler) - assert next(ax0_cycler) == expected - assert next(ax1_cycler) == expected + assert get_next_cycler_color(axes[0]) == expected + assert get_next_cycler_color(axes[1]) == expected @pytest.mark.parametrize( From 93d329e817c13bc997362364ef850f26441cd581 Mon Sep 17 00:00:00 2001 From: s-weigand Date: Sun, 30 Jun 2024 14:07:17 +0200 Subject: [PATCH 4/6] =?UTF-8?q?=F0=9F=A9=B9=20Use=20get=5Fnext=5Fcycler=5F?= =?UTF-8?q?color=20in=20plot=5Fdata=5Fand=5Ffits=20to=20advance=20cycler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyglotaran_extras/plotting/plot_traces.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyglotaran_extras/plotting/plot_traces.py b/pyglotaran_extras/plotting/plot_traces.py index 1baab017..fa79f1ed 100644 --- a/pyglotaran_extras/plotting/plot_traces.py +++ b/pyglotaran_extras/plotting/plot_traces.py @@ -15,6 +15,7 @@ from pyglotaran_extras.plotting.utils import add_unique_figure_legend from pyglotaran_extras.plotting.utils import extract_dataset_scale from pyglotaran_extras.plotting.utils import extract_irf_location +from pyglotaran_extras.plotting.utils import get_next_cycler_color from pyglotaran_extras.plotting.utils import select_plot_wavelengths __all__ = ["select_plot_wavelengths", "plot_fitted_traces"] @@ -96,7 +97,7 @@ def plot_data_and_fits( (result_data.data / scale).plot(x="time", ax=axis, label=f"{dataset_name}_data") (result_data.fitted_data / scale).plot(x="time", ax=axis, label=f"{dataset_name}_fit") else: - [next(axis._get_lines.prop_cycler) for _ in range(2)] + [get_next_cycler_color(axis) for _ in range(2)] if linlog: axis.set_xscale("symlog", linthresh=linthresh) axis.xaxis.set_minor_locator(MinorSymLogLocator(linthresh)) From 44a39dbc2bc356bc220ab092069a3662a94c92d0 Mon Sep 17 00:00:00 2001 From: s-weigand Date: Sun, 30 Jun 2024 14:17:03 +0200 Subject: [PATCH 5/6] =?UTF-8?q?=F0=9F=9A=A7=20Raise=20minimum=20numpy=20ve?= =?UTF-8?q?rsion=20to=201.22?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is required by numba which gets installer together with pygflotaran See error ImportError: Numba needs NumPy 1.22 or greater. Got NumPy 1.21. --- pyproject.toml | 2 +- requirements_min.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 254ce9c4..0c3073df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,7 @@ dynamic = [ dependencies = [ "cycler>=0.10", "matplotlib>=3.3", - "numpy>=1.21.2", + "numpy>=1.22", "pyglotaran>=0.7", "tabulate>=0.8.9", "xarray>=2022.3", diff --git a/requirements_min.txt b/requirements_min.txt index 0917a175..e622faaa 100644 --- a/requirements_min.txt +++ b/requirements_min.txt @@ -1,7 +1,7 @@ # Minimum versions runtime dependencies cycler==0.10 -numpy==1.21.2 +numpy==1.22 matplotlib==3.3 pyglotaran==0.7.2 tabulate==0.8.9 From 515ff7e2893c4d1ae5ed98d751ce94fd857702fc Mon Sep 17 00:00:00 2001 From: s-weigand Date: Sun, 30 Jun 2024 14:50:49 +0200 Subject: [PATCH 6/6] =?UTF-8?q?=F0=9F=9A=A7=F0=9F=93=9A=20Added=20changes?= =?UTF-8?q?=20to=20changelog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- changelog.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/changelog.md b/changelog.md index 594714c2..ece8b332 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,13 @@ # Changelog +(changes-0_7_3)= + +## 0.7.3 (Unreleased) + +- 🩹 Fix incompatibility of plot_data_and_fits with matplotlib>=3.8 (#275) +- 🩹 Fix deprecation warning for using xr.Dataset.dim (#267) +- 🩹 Fix very slow data/residual plots (#239) + (changes-0_7_2)= ## 0.7.2 (2023-12-07)