diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 1d485ee..145bcd8 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -3,6 +3,7 @@ on: push: branches: - develop + - feature/* jobs: actions: runs-on: ubuntu-latest @@ -32,20 +33,25 @@ jobs: DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} run: echo "${DOCKER_PASSWORD}" | docker login -u "${DOCKER_USERNAME}" --password-stdin - name: Sube latest a Docker Hub + if: github.ref_name == 'develop' run: docker push islasgeci/population_trend:latest - name: Sube sha a Docker Hub + if: github.ref_name == 'develop' run: docker push islasgeci/population_trend:${GITHUB_SHA:0:4} - name: Set up Python 3.9 + if: github.ref_name == 'develop' uses: actions/setup-python@master with: python-version: 3.9 - name: Install pypa/build + if: github.ref_name == 'develop' run: >- python -m pip install build --user - name: Build a binary wheel and a source tarball + if: github.ref_name == 'develop' run: >- python -m build @@ -54,6 +60,7 @@ jobs: --outdir dist/ . - name: Publish distribution 📦 to PyPI + if: github.ref_name == 'develop' uses: pypa/gh-action-pypi-publish@release/v1 with: password: ${{ secrets.PYPI_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index ddc5441..b19eb53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,8 +12,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +### Deprecated + ### Removed +## [5.11.0] - 2026-05-11 +### Added +- New CLI command `render-population-trend` with identical behavior to `plot-population-trend`. +### Deprecated +- CLI command `plot-population-trend` is deprecated in favor of `render-population-trend`. The old command will remain functional and will be removed in v6.0.0. Users should update their scripts and automation to use `render-population-trend` instead. ## [5.10.2] - 2026-02-05 ### Fixed - CLI command `plot-population-trend-from-cpue` can plot data with missing seasons. @@ -131,6 +138,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -[unreleased]: https://github.com/IslasGECI/population_trend/compare/v5.5.0...HEAD +[unreleased]: https://github.com/IslasGECI/population_trend/compare/v5.11.0...HEAD +[5.11.0]: https://github.com/IslasGECI/population_trend/compare/v5.10.2...v5.11.0 +[5.10.2]: https://github.com/IslasGECI/population_trend/compare/v5.10.1...v5.10.2 +[5.10.1]: https://github.com/IslasGECI/population_trend/compare/v5.10.0...v5.10.1 +[5.10.0]: https://github.com/IslasGECI/population_trend/compare/v5.9.1...v5.10.0 +[5.9.1]: https://github.com/IslasGECI/population_trend/compare/v5.9.0...v5.9.1 +[5.9.0]: https://github.com/IslasGECI/population_trend/compare/v5.8.0...v5.9.0 +[5.8.0]: https://github.com/IslasGECI/population_trend/compare/v5.7.2...v5.8.0 +[5.7.2]: https://github.com/IslasGECI/population_trend/compare/v5.7.1...v5.7.2 +[5.7.1]: https://github.com/IslasGECI/population_trend/compare/v5.7.0...v5.7.1 +[5.7.0]: https://github.com/IslasGECI/population_trend/compare/v5.6.1...v5.7.0 +[5.6.1]: https://github.com/IslasGECI/population_trend/compare/v5.6.0...v5.6.1 +[5.6.0]: https://github.com/IslasGECI/population_trend/compare/v5.5.0...v5.6.0 [5.5.0]: https://github.com/IslasGECI/population_trend/compare/v5.4.0...v5.5.0 [0.0.1]: https://github.com/IslasGECI/population_trend/releases/tag/v0.0.1 diff --git a/population_trend/__init__.py b/population_trend/__init__.py index 11d842f..60f5742 100644 --- a/population_trend/__init__.py +++ b/population_trend/__init__.py @@ -1,6 +1,6 @@ """A population growth model package""" -__version__ = "5.10.2" +__version__ = "5.11.0" from .calculate_growth_rates import * # noqa from .cli import * # noqa from .filter_data import * # noqa diff --git a/population_trend/cli.py b/population_trend/cli.py index 28d80b6..2f6fca4 100644 --- a/population_trend/cli.py +++ b/population_trend/cli.py @@ -23,6 +23,7 @@ import typer import json import matplotlib.pyplot as plt +import warnings app = typer.Typer(help="Write filtered burrows data by species and island") @@ -62,15 +63,15 @@ def write_burrows_by_species_and_island( filtered.to_csv(output_path, index=False) -@app.command(help="Plot population trend") -def plot_population_trend( - data_path: Annotated[str, typer.Option()], - intervals_path: Annotated[str, typer.Option()], - island: Annotated[str, typer.Option()] = "Guadalupe", - variable_of_interest: Annotated[str, typer.Option()] = "Maxima_cantidad_nidos", - tick_mode: Annotated[str, typer.Option()] = "full", - output_path: Annotated[str, typer.Option()] = "", +def _render_population_trend( + data_path: str, + intervals_path: str, + island: str = "Guadalupe", + variable_of_interest: str = "Maxima_cantidad_nidos", + tick_mode: str = "full", + output_path: str = "", ): + """Shared implementation for rendering population trend plots.""" fit_data = pd.read_csv(data_path) intervals_json = read_json(intervals_path) lambda_latex = intervals_json["lambda_latex_interval"] @@ -87,6 +88,52 @@ def plot_population_trend( Graficador.savefig(island, output_path) +@app.command(name="render-population-trend", help="Plot population trend") +def render_population_trend( + data_path: Annotated[str, typer.Option()], + intervals_path: Annotated[str, typer.Option()], + island: Annotated[str, typer.Option()] = "Guadalupe", + variable_of_interest: Annotated[str, typer.Option()] = "Maxima_cantidad_nidos", + tick_mode: Annotated[str, typer.Option()] = "full", + output_path: Annotated[str, typer.Option()] = "", +): + _render_population_trend( + data_path, intervals_path, island, variable_of_interest, tick_mode, output_path + ) + + +@app.command( + help="(DEPRECATED) Plot population trend. Use 'render-population-trend' instead.", + deprecated=True, +) +def plot_population_trend( + data_path: Annotated[str, typer.Option()], + intervals_path: Annotated[str, typer.Option()], + island: Annotated[str, typer.Option()] = "Guadalupe", + variable_of_interest: Annotated[str, typer.Option()] = "Maxima_cantidad_nidos", + tick_mode: Annotated[str, typer.Option()] = "full", + output_path: Annotated[str, typer.Option()] = "", +): + """(DEPRECATED) Plot population trend. Use 'render-population-trend' instead.""" + typer.secho( + "WARNING: 'plot-population-trend' is deprecated and will be removed in v6.0.0. " + "Use 'render-population-trend' instead.", + fg=typer.colors.YELLOW, + err=True, + ) + + warnings.warn( + "'plot-population-trend' is deprecated, use 'render-population-trend' instead. " + "This command will be removed in v6.0.0.", + DeprecationWarning, + stacklevel=2, + ) + + _render_population_trend( + data_path, intervals_path, island, variable_of_interest, tick_mode, output_path + ) + + @app.command(help="Plot population trend from CPUE") def plot_population_trend_from_cpue( data_path: Annotated[str, typer.Option()], diff --git a/population_trend/population_growth_model.py b/population_trend/population_growth_model.py index 9a617a8..fc6df94 100644 --- a/population_trend/population_growth_model.py +++ b/population_trend/population_growth_model.py @@ -147,8 +147,9 @@ def set_x_lim(self): ) def set_labels(self): - plt.ylabel("Number of breeding pairs", size=20) - plt.xlabel("Seasons", size=20) + labels = {"english": {"ylabel": "Number of breeding pairs", "xlabel": "Seasons"}} + plt.ylabel(labels["english"]["ylabel"], size=20) + plt.xlabel(labels["english"]["xlabel"], size=20) def set_ticks(self): self.get_tick_step() diff --git a/tests/test_Population_trend.py b/tests/test_Population_trend.py index 00e6a79..f4f0734 100644 --- a/tests/test_Population_trend.py +++ b/tests/test_Population_trend.py @@ -52,7 +52,6 @@ def tests_calculate_upper_limit(): {"intervals": [], "bootstrap_intermediate_distribution": []}, "Maxima_cantidad_nidos", ) -Plotter = Plotter_Population_Trend_Model(cormorant_data_for_plotter, pop_model, tick_mode="full") more_cormorant_data = pd.DataFrame( @@ -61,7 +60,11 @@ def tests_calculate_upper_limit(): Sparse_Plotter = Plotter_Population_Trend_Model(more_cormorant_data, pop_model, tick_mode="sparse") +Plotter = Plotter_Population_Trend_Model(cormorant_data_for_plotter, pop_model, tick_mode="full") + + class Tests_Plotter_Population_Trend_Model: + def tests_init_(self): fig, ax = geci_plot() assert type(fig) == type(Plotter.fig) # noqa diff --git a/tests/test_cli.py b/tests/test_cli.py index 558977c..16d6ad0 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -14,7 +14,7 @@ island = "Guadalupe" output_path = "tests/data/laal_guadalupe.csv" intervals_path = "tests/data/gumu_guadalupe_boostrap_intervals.json" -output_figure = "tests/data/figure.png" +data_path_for_trend = "tests/data/gumu_guadalupe_data.csv" def test_app_plot_growth_rate(): @@ -52,6 +52,13 @@ def test_app_plot_population_trend(): assert "XX" not in result.stdout assert "[default: Guadalupe]" in result.stdout assert "[default: Maxima_cantidad_nidos]" in result.stdout + assert result.exit_code == 0 + assert ( + "DEPRECATED" in result.stdout + ), f"Expected 'DEPRECATED' in help text. Got: {result.stdout}" + assert ( + "render-population-trend" in result.stdout + ), f"Expected new command name in help text. Got: {result.stdout}" data_path = "tests/data/gumu_guadalupe_data.csv" output_figure = "tests/data/plot_trend.png" @@ -220,3 +227,31 @@ def test_write_burrows_by_species_and_island(): obtained_columns = len(obtained_csv.columns) expected_columns = 12 assert obtained_columns == expected_columns + + +def test_render_population_trend_new_command_works(): + output_figure_render = "tests/data/render_trend.png" + gtt.if_exist_remove(output_figure_render) + + result = runner.invoke( + app, + [ + "render-population-trend", + "--data-path", + data_path_for_trend, + "--intervals-path", + intervals_path, + "--island", + "Guadalupe", + "--variable-of-interest", + "Maxima_cantidad_nidos", + "--tick-mode", + "sparse", + "--output-path", + output_figure_render, + ], + ) + + assert result.exit_code == 0 + gtt.assert_exist(output_figure_render) + gtt.if_exist_remove(output_figure_render)