diff --git a/.gitignore b/.gitignore index 9e0beeb..f43cb07 100644 --- a/.gitignore +++ b/.gitignore @@ -25,4 +25,7 @@ wheels/ CLAUDE.md # documentation builds -docs/_build/ \ No newline at end of file +docs/_build/ + +# notebook checkpoints +docs/user_guide/.ipynb_checkpoints/ diff --git a/README.md b/README.md index 5898d4e..70f5279 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,11 @@ A Python package for detection of deviations in groundwater time series. ## Features +- Manage reference and observation wells with ease - Programmatically fit observation wells to reference wells - Visualize fits and deviations - Save your work, share and pick up later with a custom `.gwref` file format -- More to come... +- Review statistics on fits and deviations ## Installation diff --git a/docs/conf.py b/docs/conf.py index d10cd34..fadcb08 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,7 +14,7 @@ project = "gwrefpy" copyright = "" author = "" -release = "0.4.0" +release = "0.4.1" # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/docs/user_guide/8_using_sgu_wells.ipynb b/docs/user_guide/8_using_sgu_wells.ipynb index 70d5ae4..4589063 100644 --- a/docs/user_guide/8_using_sgu_wells.ipynb +++ b/docs/user_guide/8_using_sgu_wells.ipynb @@ -4,19 +4,7 @@ "cell_type": "markdown", "id": "0f0cc3fb-4041-4c96-a87e-c6464a51a4d3", "metadata": {}, - "source": [ - "# Using SGU wells\n", - "\n", - "This notebook demonstrates the use of the python package `sgu-client` and how to integrate with `gwrefpy`. The package is installed along with `gwrefpy` if recommened add-ons are included: `pip install \"gwrefpy[recommended]\"`\n", - "\n", - "The Geological Survey of Sweden (SGU) serves an API for their groundwater monitoring network. A Python implementation of an API client has been developed in [`sgu-client`](https://github.com/officialankan/sgu-client) which makes getting observed groundwater levels from SGU into Python a breeze. \n", - "\n", - "\n", - "\n", - "```{note}\n", - "The `sgu-client` package is not affiliated with, supported or endorsed by SGU.\n", - "```" - ] + "source": "# Using SGU wells\n\nThis notebook demonstrates the use of the python package `sgu-client` and how to integrate with `gwrefpy`. The package is installed along with `gwrefpy` if recommended add-ons are included: `pip install \"gwrefpy[recommended]\"`\n\nThe Geological Survey of Sweden (SGU) serves an API for their groundwater monitoring network. A Python implementation of an API client has been developed in [`sgu-client`](https://github.com/officialankan/sgu-client) which makes getting observed groundwater levels from SGU into Python a breeze. \n\n\n\n```{note}\nThe `sgu-client` package is not affiliated with, supported or endorsed by SGU.\n```" }, { "cell_type": "code", @@ -45,16 +33,7 @@ "cell_type": "markdown", "id": "fed96e2d-5a13-4522-a9ce-9274f1fa30d7", "metadata": {}, - "source": [ - "## Getting observed groundwater levels\n", - "\n", - "This basic example will show how to fetch observed groundwater levels. For more options, please refer to [these docs](https://github.com/officialankan/sgu-client?tab=readme-ov-file#observed-groundwater-levels).\n", - "\n", - "Below, we wrangle the data in two steps:\n", - "\n", - "1. remove the UTC timezone from the fetched timeseries to achieve compatability with the example model we will load later,\n", - "2. resample to daily medians to align the frequency with that of the example model we will load later" - ] + "source": "## Getting observed groundwater levels\n\nThis basic example will show how to fetch observed groundwater levels. For more options, please refer to [these docs](https://github.com/officialankan/sgu-client?tab=readme-ov-file#observed-groundwater-levels).\n\nBelow, we wrangle the data in two steps:\n\n1. remove the UTC timezone from the fetched timeseries to achieve compatibility with the example model we will load later,\n2. resample to daily medians to align the frequency with that of the example model we will load later" }, { "cell_type": "code", @@ -330,19 +309,7 @@ "cell_type": "markdown", "id": "1ba49a2e-e227-4558-82a0-7e8489a3695c", "metadata": {}, - "source": [ - "## Fitting to modeled groundwater levels\n", - "\n", - "SGU serves an API for accessing modeled groundwater levels. Let's explore how we can integrate it with `gwrefpy`. \n", - "\n", - "More examples on fetching modeled groundwater levels can be found [here](https://github.com/officialankan/sgu-client?tab=readme-ov-file#modeled-groundwater-levels).\n", - "\n", - "Below, we first get the metadata for the monitoring well *4_3* to retrieve its coordinates. We use that to get modeled groundwater levels at the site. Lastly, we get the observed levels which we will need for the fitting.\n", - "\n", - "```{note}\n", - "The example below assumes we are interested in modeled **minor resources** (i.e. shallow or fast responding groundwater systems). To use this in production, the user should make sure to now the modeling workflow and the associated uncertainties related to SGUs modeled groundwater levels.\n", - "```" - ] + "source": "## Fitting to modeled groundwater levels\n\nSGU serves an API for accessing modeled groundwater levels. Let's explore how we can integrate it with `gwrefpy`. \n\nMore examples on fetching modeled groundwater levels can be found [here](https://github.com/officialankan/sgu-client?tab=readme-ov-file#modeled-groundwater-levels).\n\nBelow, we first get the metadata for the monitoring well *4_3* to retrieve its coordinates. We use that to get modeled groundwater levels at the site. Lastly, we get the observed levels which we will need for the fitting.\n\n```{note}\nThe example below assumes we are interested in modeled **minor resources** (i.e. shallow or fast responding groundwater systems). For real-world applications, users should familiarize themselves with SGU's modeling methodology and the associated uncertainties of the modeled groundwater levels.\n```" }, { "cell_type": "code", @@ -370,9 +337,7 @@ "cell_type": "markdown", "id": "ee8d43a6-4869-48a1-b85b-529a1182bd4c", "metadata": {}, - "source": [ - "Below, we create a model and add the observed levels as a observation well and the modeled levels as a reference well." - ] + "source": "Below, we create a model and add the observed levels as an observation well and the modeled levels as a reference well." }, { "cell_type": "code", @@ -660,4 +625,4 @@ }, "nbformat": 4, "nbformat_minor": 5 -} +} \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index adfac99..6d4d64e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "gwrefpy" -version = "0.4.0" -description = "A python implementation of the Akvifär reference method for detecting deviations in groundwater level time series." +version = "0.4.1" +description = "A Python package for detection of deviations in groundwater time series." readme = "README.md" license = "MIT" authors = [ @@ -39,6 +39,7 @@ dev = [ "sphinx-autobuild", "myst-nb>=1.3.0", "sphinx-design>=0.6.1", + "sgu-client" ] recommended = ["notebook", "sgu-client"] diff --git a/src/gwrefpy/__init__.py b/src/gwrefpy/__init__.py index f5788f8..d1db823 100644 --- a/src/gwrefpy/__init__.py +++ b/src/gwrefpy/__init__.py @@ -1,5 +1,5 @@ __name__ = "gwrefpy" -__version__ = "0.4.0" +__version__ = "0.4.1" from .constants import print_constants from .methods.timeseries import analyze_offsets diff --git a/src/gwrefpy/plotter.py b/src/gwrefpy/plotter.py index d039e54..71ef380 100644 --- a/src/gwrefpy/plotter.py +++ b/src/gwrefpy/plotter.py @@ -905,8 +905,15 @@ def _plot_settings(self, ax, num): # Skip custom styling, use matplotlib defaults pass - # limit x axis to data range - ax.set_xlim(left=self._xmin, right=self._xmax) + # limit x axis to data range if not tmax or tmin provided + if self._plot_tmax: + ax.set_xlim(right=pd.Timestamp(self._plot_tmax)) + else: + ax.set_xlim(right=self._xmax) + if self._plot_tmin: + ax.set_xlim(left=pd.Timestamp(self._plot_tmin)) + else: + ax.set_xlim(left=self._xmin) # Apply custom formatting only if plot_style is not None if self._plot_style is not None: diff --git a/uv.lock b/uv.lock index 003e890..2668125 100644 --- a/uv.lock +++ b/uv.lock @@ -568,7 +568,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a4/de/f28ced0a67749cac23fecb02b694f6473f47686dff6afaa211d186e2ef9c/greenlet-3.2.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:96378df1de302bc38e99c3a9aa311967b7dc80ced1dcc6f171e99842987882a2", size = 272305, upload-time = "2025-08-07T13:15:41.288Z" }, { url = "https://files.pythonhosted.org/packages/09/16/2c3792cba130000bf2a31c5272999113f4764fd9d874fb257ff588ac779a/greenlet-3.2.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1ee8fae0519a337f2329cb78bd7a8e128ec0f881073d43f023c7b8d4831d5246", size = 632472, upload-time = "2025-08-07T13:42:55.044Z" }, { url = "https://files.pythonhosted.org/packages/ae/8f/95d48d7e3d433e6dae5b1682e4292242a53f22df82e6d3dda81b1701a960/greenlet-3.2.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:94abf90142c2a18151632371140b3dba4dee031633fe614cb592dbb6c9e17bc3", size = 644646, upload-time = "2025-08-07T13:45:26.523Z" }, - { url = "https://files.pythonhosted.org/packages/d5/5e/405965351aef8c76b8ef7ad370e5da58d57ef6068df197548b015464001a/greenlet-3.2.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:4d1378601b85e2e5171b99be8d2dc85f594c79967599328f95c1dc1a40f1c633", size = 640519, upload-time = "2025-08-07T13:53:13.928Z" }, { url = "https://files.pythonhosted.org/packages/25/5d/382753b52006ce0218297ec1b628e048c4e64b155379331f25a7316eb749/greenlet-3.2.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0db5594dce18db94f7d1650d7489909b57afde4c580806b8d9203b6e79cdc079", size = 639707, upload-time = "2025-08-07T13:18:27.146Z" }, { url = "https://files.pythonhosted.org/packages/1f/8e/abdd3f14d735b2929290a018ecf133c901be4874b858dd1c604b9319f064/greenlet-3.2.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2523e5246274f54fdadbce8494458a2ebdcdbc7b802318466ac5606d3cded1f8", size = 587684, upload-time = "2025-08-07T13:18:25.164Z" }, { url = "https://files.pythonhosted.org/packages/5d/65/deb2a69c3e5996439b0176f6651e0052542bb6c8f8ec2e3fba97c9768805/greenlet-3.2.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1987de92fec508535687fb807a5cea1560f6196285a4cde35c100b8cd632cc52", size = 1116647, upload-time = "2025-08-07T13:42:38.655Z" }, @@ -579,7 +578,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/44/69/9b804adb5fd0671f367781560eb5eb586c4d495277c93bde4307b9e28068/greenlet-3.2.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3b67ca49f54cede0186854a008109d6ee71f66bd57bb36abd6d0a0267b540cdd", size = 274079, upload-time = "2025-08-07T13:15:45.033Z" }, { url = "https://files.pythonhosted.org/packages/46/e9/d2a80c99f19a153eff70bc451ab78615583b8dac0754cfb942223d2c1a0d/greenlet-3.2.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddf9164e7a5b08e9d22511526865780a576f19ddd00d62f8a665949327fde8bb", size = 640997, upload-time = "2025-08-07T13:42:56.234Z" }, { url = "https://files.pythonhosted.org/packages/3b/16/035dcfcc48715ccd345f3a93183267167cdd162ad123cd93067d86f27ce4/greenlet-3.2.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f28588772bb5fb869a8eb331374ec06f24a83a9c25bfa1f38b6993afe9c1e968", size = 655185, upload-time = "2025-08-07T13:45:27.624Z" }, - { url = "https://files.pythonhosted.org/packages/31/da/0386695eef69ffae1ad726881571dfe28b41970173947e7c558d9998de0f/greenlet-3.2.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:5c9320971821a7cb77cfab8d956fa8e39cd07ca44b6070db358ceb7f8797c8c9", size = 649926, upload-time = "2025-08-07T13:53:15.251Z" }, { url = "https://files.pythonhosted.org/packages/68/88/69bf19fd4dc19981928ceacbc5fd4bb6bc2215d53199e367832e98d1d8fe/greenlet-3.2.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c60a6d84229b271d44b70fb6e5fa23781abb5d742af7b808ae3f6efd7c9c60f6", size = 651839, upload-time = "2025-08-07T13:18:30.281Z" }, { url = "https://files.pythonhosted.org/packages/19/0d/6660d55f7373b2ff8152401a83e02084956da23ae58cddbfb0b330978fe9/greenlet-3.2.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b3812d8d0c9579967815af437d96623f45c0f2ae5f04e366de62a12d83a8fb0", size = 607586, upload-time = "2025-08-07T13:18:28.544Z" }, { url = "https://files.pythonhosted.org/packages/8e/1a/c953fdedd22d81ee4629afbb38d2f9d71e37d23caace44775a3a969147d4/greenlet-3.2.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:abbf57b5a870d30c4675928c37278493044d7c14378350b3aa5d484fa65575f0", size = 1123281, upload-time = "2025-08-07T13:42:39.858Z" }, @@ -590,7 +588,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/49/e8/58c7f85958bda41dafea50497cbd59738c5c43dbbea5ee83d651234398f4/greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31", size = 272814, upload-time = "2025-08-07T13:15:50.011Z" }, { url = "https://files.pythonhosted.org/packages/62/dd/b9f59862e9e257a16e4e610480cfffd29e3fae018a68c2332090b53aac3d/greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945", size = 641073, upload-time = "2025-08-07T13:42:57.23Z" }, { url = "https://files.pythonhosted.org/packages/f7/0b/bc13f787394920b23073ca3b6c4a7a21396301ed75a655bcb47196b50e6e/greenlet-3.2.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:710638eb93b1fa52823aa91bf75326f9ecdfd5e0466f00789246a5280f4ba0fc", size = 655191, upload-time = "2025-08-07T13:45:29.752Z" }, - { url = "https://files.pythonhosted.org/packages/f2/d6/6adde57d1345a8d0f14d31e4ab9c23cfe8e2cd39c3baf7674b4b0338d266/greenlet-3.2.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c5111ccdc9c88f423426df3fd1811bfc40ed66264d35aa373420a34377efc98a", size = 649516, upload-time = "2025-08-07T13:53:16.314Z" }, { url = "https://files.pythonhosted.org/packages/7f/3b/3a3328a788d4a473889a2d403199932be55b1b0060f4ddd96ee7cdfcad10/greenlet-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76383238584e9711e20ebe14db6c88ddcedc1829a9ad31a584389463b5aa504", size = 652169, upload-time = "2025-08-07T13:18:32.861Z" }, { url = "https://files.pythonhosted.org/packages/ee/43/3cecdc0349359e1a527cbf2e3e28e5f8f06d3343aaf82ca13437a9aa290f/greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671", size = 610497, upload-time = "2025-08-07T13:18:31.636Z" }, { url = "https://files.pythonhosted.org/packages/b8/19/06b6cf5d604e2c382a6f31cafafd6f33d5dea706f4db7bdab184bad2b21d/greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b", size = 1121662, upload-time = "2025-08-07T13:42:41.117Z" }, @@ -601,7 +598,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/22/5c/85273fd7cc388285632b0498dbbab97596e04b154933dfe0f3e68156c68c/greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0", size = 273586, upload-time = "2025-08-07T13:16:08.004Z" }, { url = "https://files.pythonhosted.org/packages/d1/75/10aeeaa3da9332c2e761e4c50d4c3556c21113ee3f0afa2cf5769946f7a3/greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f", size = 686346, upload-time = "2025-08-07T13:42:59.944Z" }, { url = "https://files.pythonhosted.org/packages/c0/aa/687d6b12ffb505a4447567d1f3abea23bd20e73a5bed63871178e0831b7a/greenlet-3.2.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:c17b6b34111ea72fc5a4e4beec9711d2226285f0386ea83477cbb97c30a3f3a5", size = 699218, upload-time = "2025-08-07T13:45:30.969Z" }, - { url = "https://files.pythonhosted.org/packages/dc/8b/29aae55436521f1d6f8ff4e12fb676f3400de7fcf27fccd1d4d17fd8fecd/greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1", size = 694659, upload-time = "2025-08-07T13:53:17.759Z" }, { url = "https://files.pythonhosted.org/packages/92/2e/ea25914b1ebfde93b6fc4ff46d6864564fba59024e928bdc7de475affc25/greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735", size = 695355, upload-time = "2025-08-07T13:18:34.517Z" }, { url = "https://files.pythonhosted.org/packages/72/60/fc56c62046ec17f6b0d3060564562c64c862948c9d4bc8aa807cf5bd74f4/greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337", size = 657512, upload-time = "2025-08-07T13:18:33.969Z" }, { url = "https://files.pythonhosted.org/packages/23/6e/74407aed965a4ab6ddd93a7ded3180b730d281c77b765788419484cdfeef/greenlet-3.2.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2917bdf657f5859fbf3386b12d68ede4cf1f04c90c3a6bc1f013dd68a22e2269", size = 1612508, upload-time = "2025-11-04T12:42:23.427Z" }, @@ -611,7 +607,7 @@ wheels = [ [[package]] name = "gwrefpy" -version = "0.4.0" +version = "0.4.1" source = { editable = "." } dependencies = [ { name = "matplotlib" }, @@ -626,6 +622,7 @@ dev = [ { name = "pydata-sphinx-theme" }, { name = "pytest" }, { name = "ruff" }, + { name = "sgu-client" }, { name = "sphinx" }, { name = "sphinx-autobuild" }, { name = "sphinx-copybutton" }, @@ -650,6 +647,7 @@ dev = [ { name = "pydata-sphinx-theme" }, { name = "pytest", specifier = ">=8.4.1" }, { name = "ruff", specifier = ">=0.12.10" }, + { name = "sgu-client" }, { name = "sphinx" }, { name = "sphinx-autobuild" }, { name = "sphinx-copybutton" },