diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index c9a8d14..93680eb 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -28,20 +28,20 @@ jobs: fetch-depth: 0 persist-credentials: false - - name: Setup Micromamba - uses: mamba-org/setup-micromamba@d7c9bd84e824b79d2af72a2d4196c7f4300d3476 # v3.0.0 + - name: Set up Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: - environment-name: TEST - init-shell: bash - create-args: >- - python=3 pip - --file requirements.txt - --file requirements-dev.txt - --channel conda-forge + python-version: "3.x" + + + - name: Install pandoc for notebook conversion + run: > + sudo apt-get update + && sudo apt-get install pandoc - name: Install windrose run: | - python -m pip install -e . --no-deps --force-reinstall + python -m pip install -e .[extras,tests,docs] - name: Build documentation run: | diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bca6f2a..70ce40e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,7 +13,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [ "3.10", "3.11", "3.12", "3.13", "3.14" ] + python-version: [ "3.11", "3.12", "3.13", "3.14" ] os: [ ubuntu-latest ] include: - os: windows-latest @@ -31,22 +31,14 @@ jobs: fetch-depth: 0 persist-credentials: false - - name: Setup Micromamba for Python ${{ matrix.python-version }} - uses: mamba-org/setup-micromamba@d7c9bd84e824b79d2af72a2d4196c7f4300d3476 # v3.0.0 + - name: Set up Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: - # Remove the line below when micromamba 2.6.2 is released. - micromamba-version: '2.6.0-0' - environment-name: TEST - init-shell: bash - create-args: >- - python=${{ matrix.python-version }} pip - --file requirements.txt - --file requirements-dev.txt - --channel conda-forge + python-version: ${{ matrix.python-version }} - name: Install windrose run: | - python -m pip install -e . --no-deps --force-reinstall + python -m pip install -e .[extras,tests] - name: Tests run: | diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index be6d9fa..1a3cc9f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -51,12 +51,12 @@ repos: - id: add-trailing-comma - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.17 + rev: v0.15.18 hooks: - id: ruff - repo: https://github.com/tox-dev/pyproject-fmt - rev: v2.24.1 + rev: v2.25.0 hooks: - id: pyproject-fmt @@ -81,7 +81,7 @@ repos: - id: nb-strip-paths - repo: https://github.com/woodruffw/zizmor-pre-commit - rev: v1.25.2 + rev: v1.26.1 hooks: - id: zizmor diff --git a/pyproject.toml b/pyproject.toml index 99ad147..234b8e4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,10 +30,20 @@ dependencies = [ "matplotlib>=3", "numpy>=1.21", ] +optional-dependencies.docs = [ "jupyter", "nbsphinx", "seaborn", "sphinx", "sphinx-copybutton", "sphinx-rtd-theme" ] optional-dependencies.extras = [ "pandas", "scipy", ] +optional-dependencies.tests = [ + "cartopy", + "check-manifest", + "coverage", + "pytest", + "pytest-cov", + "pytest-mpl", + "pytest-sugar" +] urls.documentation = "https://python-windrose.github.io/windrose" urls.homepage = "https://github.com/python-windrose/windrose" urls.repository = "https://github.com/python-windrose/windrose" @@ -41,7 +51,6 @@ urls.repository = "https://github.com/python-windrose/windrose" [tool.setuptools] packages = [ "windrose" ] include-package-data = true -dynamic.dependencies = { file = [ "requirements.txt" ] } dynamic.readme = { file = "README.md", content-type = "text/markdown" } license-files = [ "LICENSE.txt", diff --git a/requirements-dev.txt b/requirements-dev.txt deleted file mode 100644 index 55d0636..0000000 --- a/requirements-dev.txt +++ /dev/null @@ -1,29 +0,0 @@ -black -cartopy -check-manifest -coverage -flake8 -flake8-builtins -flake8-comprehensions -flake8-mutable -flake8-print -interrogate -isort -jupyter -nbsphinx -pre-commit -pyarrow -pydocstyle -pylint -pytest -pytest-cov -pytest-flake8 -pytest-mpl -pytest-sugar -seaborn -setuptools_scm -sphinx -sphinx-copybutton -sphinx_rtd_theme -twine -wheel diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 0f7af4e..0000000 --- a/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -matplotlib >=3 -numpy >=1.21 -pandas -scipy diff --git a/tests/output/df/test_subplots.png b/tests/output/df/test_subplots.png index d23dd78..6bb6ebe 100644 Binary files a/tests/output/df/test_subplots.png and b/tests/output/df/test_subplots.png differ diff --git a/tests/output/func/test_wrbar.png b/tests/output/func/test_wrbar.png index ca8b802..59b5fda 100644 Binary files a/tests/output/func/test_wrbar.png and b/tests/output/func/test_wrbar.png differ diff --git a/tests/test_windrose_factory.py b/tests/test_windrose_factory.py index cfc6711..e255b39 100644 --- a/tests/test_windrose_factory.py +++ b/tests/test_windrose_factory.py @@ -19,7 +19,7 @@ df = pd.DataFrame({"speed": ws, "direction": wd}) -@pytest.mark.mpl_image_compare(baseline_dir="output/") +@pytest.mark.mpl_image_compare(baseline_dir="output/", tolerance=20) def test_bar_from_factory(): ax = WindAxesFactory.create("WindroseAxes") ax.bar(wd, ws, normed=True, opening=0.8, edgecolor="white") @@ -27,7 +27,7 @@ def test_bar_from_factory(): return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/") +@pytest.mark.mpl_image_compare(baseline_dir="output/", tolerance=10) def test_pdf_from_factory(): ax = WindAxesFactory.create("WindAxes") bins = np.arange(0, 8, 1) diff --git a/tests/test_windrose_np_mpl_func.py b/tests/test_windrose_np_mpl_func.py index 6c56671..ee05367 100644 --- a/tests/test_windrose_np_mpl_func.py +++ b/tests/test_windrose_np_mpl_func.py @@ -17,37 +17,37 @@ bins = np.arange(0, 8, 1) -@pytest.mark.mpl_image_compare(baseline_dir="output/func") +@pytest.mark.mpl_image_compare(baseline_dir="output/func", tolerance=10) def test_wrscatter(): ax = wrscatter(wd, ws, alpha=0.2) return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/func", tolerance=15.5) +@pytest.mark.mpl_image_compare(baseline_dir="output/func", tolerance=5) def test_wrbar(): ax = wrbar(wd, ws, normed=True, opening=0.8, edgecolor="white") return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/func", tolerance=6.5) +@pytest.mark.mpl_image_compare(baseline_dir="output/func", tolerance=20) def test_wrbox(): ax = wrbox(wd, ws, bins=bins) return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/func") +@pytest.mark.mpl_image_compare(baseline_dir="output/func", tolerance=20) def test_wrcontourf(): ax = wrcontourf(wd, ws, bins=bins, cmap=cm.hot) return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/func") +@pytest.mark.mpl_image_compare(baseline_dir="output/func", tolerance=20) def test_wrcontour(): ax = wrcontour(wd, ws, bins=bins, cmap=cm.hot, lw=3) return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/func") +@pytest.mark.mpl_image_compare(baseline_dir="output/func", tolerance=10) def test_wrpdf(): ax, params = wrpdf(ws, bins=bins) return ax.figure diff --git a/tests/test_windrose_np_mpl_oo.py b/tests/test_windrose_np_mpl_oo.py index 3783089..565e77b 100644 --- a/tests/test_windrose_np_mpl_oo.py +++ b/tests/test_windrose_np_mpl_oo.py @@ -19,7 +19,7 @@ df = pd.DataFrame({"speed": ws, "direction": wd}) -@pytest.mark.mpl_image_compare(baseline_dir="output/oo") +@pytest.mark.mpl_image_compare(baseline_dir="output/oo", tolerance=10) def test_windrose_with_scatter_plot(): ax = WindroseAxes.from_ax() ax.scatter(wd, ws, alpha=0.2) @@ -36,7 +36,7 @@ def test_windrose_stacked_histogram_normed(): return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/oo", tolerance=6.5) +@pytest.mark.mpl_image_compare(baseline_dir="output/oo", tolerance=20) def test_windrose_stacked_histogram_not_normed_binned(): # Another stacked histogram representation, not normed, with bins limits ax = WindroseAxes.from_ax() @@ -45,7 +45,7 @@ def test_windrose_stacked_histogram_not_normed_binned(): return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/oo", tolerance=6.5) +@pytest.mark.mpl_image_compare(baseline_dir="output/oo", tolerance=20) def test_windrose_stacked_histogram_not_normed_binned_calm_limit(): # Another stacked histogram representation, not normed, with bins limits and a calm limit ax = WindroseAxes.from_ax() @@ -55,7 +55,7 @@ def test_windrose_stacked_histogram_not_normed_binned_calm_limit(): return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/oo", tolerance=15.5) +@pytest.mark.mpl_image_compare(baseline_dir="output/oo", tolerance=20) def test_windrose_stacked_histogram_normed_calm_limit(): # windrose like a stacked histogram with normed (displayed in percent) results and a calm limit ax = WindroseAxes.from_ax() @@ -64,7 +64,7 @@ def test_windrose_stacked_histogram_normed_calm_limit(): return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/oo") +@pytest.mark.mpl_image_compare(baseline_dir="output/oo", tolerance=20) def test_filled_with_colormap(): # A windrose in filled representation, with a controlled colormap ax = WindroseAxes.from_ax() @@ -73,7 +73,7 @@ def test_filled_with_colormap(): return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/oo") +@pytest.mark.mpl_image_compare(baseline_dir="output/oo", tolerance=20) def test_filled_with_colormap_calm_limit(): # A windrose in filled representation, with a controlled colormap and a calm limit ax = WindroseAxes.from_ax() @@ -83,7 +83,7 @@ def test_filled_with_colormap_calm_limit(): return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/oo") +@pytest.mark.mpl_image_compare(baseline_dir="output/oo", tolerance=20) def test_filled_with_colormap_contours(): # Same as above, but with contours over each filled region... ax = WindroseAxes.from_ax() @@ -93,7 +93,7 @@ def test_filled_with_colormap_contours(): return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/oo") +@pytest.mark.mpl_image_compare(baseline_dir="output/oo", tolerance=20) def test_filled_with_colormap_contours_calm_limit(): # Same as above, but with contours over each filled region... ax = WindroseAxes.from_ax() @@ -105,7 +105,7 @@ def test_filled_with_colormap_contours_calm_limit(): return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/oo") +@pytest.mark.mpl_image_compare(baseline_dir="output/oo", tolerance=20) def test_without_filled_with_colormap_contours(): ax = WindroseAxes.from_ax() ax.contour(wd, ws, bins=bins, cmap=cm.hot, lw=3) @@ -113,7 +113,7 @@ def test_without_filled_with_colormap_contours(): return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/oo") +@pytest.mark.mpl_image_compare(baseline_dir="output/oo", tolerance=20) def test_without_filled_with_colormap_contours_calm_limit(): ax = WindroseAxes.from_ax() # the bins most not be below the calm_limit @@ -129,7 +129,7 @@ def test_without_filled_with_colormap_contours_calm_limit(): return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/oo") +@pytest.mark.mpl_image_compare(baseline_dir="output/oo", tolerance=10) def test_pdf(): ax = WindAxes.from_ax() bins = np.arange(0, 8, 1) diff --git a/tests/test_windrose_pandas.py b/tests/test_windrose_pandas.py index 86ac95a..119bac6 100644 --- a/tests/test_windrose_pandas.py +++ b/tests/test_windrose_pandas.py @@ -21,49 +21,49 @@ df = pd.DataFrame({"speed": ws, "direction": wd}) -@pytest.mark.mpl_image_compare(baseline_dir="output/df") +@pytest.mark.mpl_image_compare(baseline_dir="output/df", tolerance=10) def test_scatter(): kind = "scatter" ax = plot_windrose(df, kind=kind, alpha=0.2) return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/df", tolerance=15.5) +@pytest.mark.mpl_image_compare(baseline_dir="output/df", tolerance=20) def test_bar(): kind = "bar" ax = plot_windrose(df, kind=kind, normed=True, opening=0.8, edgecolor="white") return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/df", tolerance=6.5) +@pytest.mark.mpl_image_compare(baseline_dir="output/df", tolerance=20) def test_box(): kind = "box" ax = plot_windrose(df, kind=kind, bins=bins) return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/df") +@pytest.mark.mpl_image_compare(baseline_dir="output/df", tolerance=20) def test_contourf(): kind = "contourf" ax = plot_windrose(df, kind=kind, bins=np.arange(0.01, 8, 1), cmap=cm.hot) return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/df") +@pytest.mark.mpl_image_compare(baseline_dir="output/df", tolerance=20) def test_contour(): kind = "contour" ax = plot_windrose(df, kind=kind, bins=np.arange(0.01, 8, 1), cmap=cm.hot, lw=3) return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/df") +@pytest.mark.mpl_image_compare(baseline_dir="output/df", tolerance=10) def test_pdf(): kind = "pdf" ax, params = plot_windrose(df, kind=kind, bins=np.arange(0.01, 8, 1)) return ax.figure -@pytest.mark.mpl_image_compare(baseline_dir="output/df") +@pytest.mark.mpl_image_compare(baseline_dir="output/df", tolerance=10) def test_windrose_np_plot_and_pd_plot(): # Not really pandas but this is an orphan test and fits the plot_windrose tests. kind = "scatter"