terndata.ecoplots 1.1.2.dev12__tar.gz → 1.1.2.dev13__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/PKG-INFO +1 -1
  2. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/changelog.rst +8 -0
  3. terndata_ecoplots-1.1.2.dev13/examples/README.md +31 -0
  4. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata/ecoplots/_gui/spatial_selector.py +1 -1
  5. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata/ecoplots/_nlp_utils.py +14 -6
  6. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata/ecoplots/ecoplots.py +6 -1
  7. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata/ecoplots/version.py +2 -2
  8. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata.ecoplots.egg-info/PKG-INFO +1 -1
  9. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata.ecoplots.egg-info/SOURCES.txt +1 -0
  10. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/tests/test_data_retrieval.py +4 -0
  11. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/tests/test_utils.py +27 -0
  12. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/.github/workflows/publish.yml +0 -0
  13. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/.github/workflows/scripts/next_dev_version.py +0 -0
  14. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/.github/workflows/test.yml +0 -0
  15. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/.gitignore +0 -0
  16. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/.readthedocs.yaml +0 -0
  17. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/CITATION.cff +0 -0
  18. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/LICENSE +0 -0
  19. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/Makefile +0 -0
  20. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/NOTICE +0 -0
  21. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/README.md +0 -0
  22. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/Makefile +0 -0
  23. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/_static/brand.css +0 -0
  24. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/_static/img/TERN-logo-primary.png +0 -0
  25. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/_static/img/TERN-logo-reversed.png +0 -0
  26. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/_static/img/ecoplots-logo-base.svg +0 -0
  27. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/_static/img/ecoplots-logo-dark.svg +0 -0
  28. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/_static/img/ecoplots-logo-light.svg +0 -0
  29. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/_static/img/ep-banner.png +0 -0
  30. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/_static/img/github-mark.svg +0 -0
  31. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/_static/img/widget_igsn_viewer.png +0 -0
  32. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/_static/img/widget_sample_image_viewer.png +0 -0
  33. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/_static/img/widget_spatial_selector.png +0 -0
  34. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/api/async_ecoplots_class.rst +0 -0
  35. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/api/ecoplots_class.rst +0 -0
  36. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/api/ecoplots_observations.rst +0 -0
  37. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/api/ecoplots_samples.rst +0 -0
  38. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/api/modules.rst +0 -0
  39. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/api/overview.rst +0 -0
  40. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/api.rst +0 -0
  41. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/api_internal/ecoplots._flatten_response.rst +0 -0
  42. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/api_internal/ecoplots._gui.rst +0 -0
  43. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/api_internal/ecoplots.rst +0 -0
  44. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/api_internal/modules.rst +0 -0
  45. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/conf.py +0 -0
  46. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/index.rst +0 -0
  47. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/internals.rst +0 -0
  48. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/requirements.txt +0 -0
  49. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/docs/workflows.md +0 -0
  50. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/examples/R examples/ReadMe.md +0 -0
  51. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/examples/R examples/terndata.ecoplots_QueenslandSoilColour.R +0 -0
  52. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/examples/R examples/terndata.ecoplots_TrendsInSpeciesCover.R +0 -0
  53. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/examples/demo.ipynb +0 -0
  54. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/examples/demo_samples.ipynb +0 -0
  55. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/pyproject.toml +0 -0
  56. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/requirements-async.txt +0 -0
  57. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/requirements-flake8.txt +0 -0
  58. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/requirements-gui.txt +0 -0
  59. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/requirements-mypy.txt +0 -0
  60. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/requirements-test.txt +0 -0
  61. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/requirements-tox.txt +0 -0
  62. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/requirements.txt +0 -0
  63. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/setup.cfg +0 -0
  64. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata/ecoplots/__init__.py +0 -0
  65. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata/ecoplots/_base.py +0 -0
  66. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata/ecoplots/_config.py +0 -0
  67. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata/ecoplots/_exceptions.py +0 -0
  68. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata/ecoplots/_flatten_response/__init__.py +0 -0
  69. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata/ecoplots/_flatten_response/_streaming.py +0 -0
  70. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata/ecoplots/_flatten_response/_workers.py +0 -0
  71. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata/ecoplots/_gui/__init__.py +0 -0
  72. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata/ecoplots/_gui/igsn_viewer.py +0 -0
  73. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata/ecoplots/_gui/sample_image_viewer.py +0 -0
  74. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata/ecoplots/_utils.py +0 -0
  75. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata/ecoplots/assets/TERN_logo.png +0 -0
  76. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata/ecoplots/assets/ecoplots_logo.svg +0 -0
  77. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata/ecoplots/py.typed +0 -0
  78. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata.ecoplots.egg-info/dependency_links.txt +0 -0
  79. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata.ecoplots.egg-info/requires.txt +0 -0
  80. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/src/terndata.ecoplots.egg-info/top_level.txt +0 -0
  81. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/tests/conftest.py +0 -0
  82. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/tests/test_client_state.py +0 -0
  83. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/tests/test_project_files.py +0 -0
  84. {terndata_ecoplots-1.1.2.dev12 → terndata_ecoplots-1.1.2.dev13}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: terndata.ecoplots
3
- Version: 1.1.2.dev12
3
+ Version: 1.1.2.dev13
4
4
  Summary: Python client for discovering, filtering, and retrieving TERN EcoPlots observation and sample data
5
5
  Author-email: Avinash Chandra <avinash.chandra@uq.edu.au>
6
6
  Maintainer-email: "TERN Data Services and Analytics (TDSA)" <esupport@tern.org.au>
@@ -3,6 +3,14 @@ Change Log
3
3
 
4
4
  Changes over time for the EcoPlots Python library.
5
5
 
6
+ v1.1.2 (2026-09-17)
7
+ -------------------
8
+
9
+ - Updated the spatial selector to use the key-free Esri World Shaded Relief basemap, removing the Carto watermark while retaining a subdued map style.
10
+ - Fixed Parquet output for columns containing mixed numeric values and ``"N/A"`` placeholders by converting those placeholders to null values during Parquet serialization.
11
+ - Fixed region type resolution for IBRA7 bioregions and subregions, including space-, hyphen-, and underscore-separated names and the legacy ``bioregions`` and ``subregions`` aliases.
12
+ - Added a dedicated examples README with summaries and direct links to the Python notebooks and R examples.
13
+
6
14
  v1.1.1 (2026-06-26)
7
15
  -------------------
8
16
 
@@ -0,0 +1,31 @@
1
+ # EcoPlots examples
2
+
3
+ This directory contains practical Python and R examples for discovering, filtering,
4
+ retrieving, and visualising TERN EcoPlots data.
5
+
6
+ ## Python examples
7
+
8
+ - [Observations demo](demo.ipynb) — covers discovery, filters, summaries, previews,
9
+ data retrieval, GeoJSON output, and spatial selection.
10
+ - [Samples demo](demo_samples.ipynb) — covers sample discovery and filtering, IGSN
11
+ identifiers, soil and species analysis, image viewing, and spatial selection.
12
+
13
+ The Python examples are Jupyter notebooks. Install the GUI extra to use their
14
+ interactive widgets:
15
+
16
+ ```bash
17
+ pip install "terndata.ecoplots[gui]"
18
+ ```
19
+
20
+ ## R examples
21
+
22
+ The R examples use
23
+ [`reticulate`](https://rstudio.github.io/reticulate/) to call the EcoPlots Python
24
+ package from R:
25
+
26
+ - [R setup and usage guide](<R examples/ReadMe.md>)
27
+ - [Queensland soil colour](<R examples/terndata.ecoplots_QueenslandSoilColour.R>) —
28
+ downloads QBEIS soil-colour observations and plots their site locations and colours.
29
+ - [Trends in species cover](<R examples/terndata.ecoplots_TrendsInSpeciesCover.R>) —
30
+ retrieves observations for a site and visualises changes in species cover between
31
+ visits.
@@ -120,7 +120,7 @@ def spatial_selector(
120
120
  # Map
121
121
  m = Map(center=center, zoom=zoom, scroll_wheel_zoom=True, attribution_control=False)
122
122
  m.layout = Layout(width="100%", height="500px")
123
- m.add_layer(basemap_to_tiles(basemaps.CartoDB.Positron))
123
+ m.add_layer(basemap_to_tiles(basemaps.Esri.WorldGrayCanvas))
124
124
  m.fit_bounds(_AU_BOUNDS)
125
125
  m.max_bounds = _AU_BOUNDS
126
126
 
@@ -13,13 +13,16 @@ from ._config import MATERIAL_SAMPLE_TYPE_MAP
13
13
  ALL_FACETS = ["region_type", "region", "dataset", "feature_type", "observed_property"]
14
14
 
15
15
  REGION_TYPES_MAP = {
16
- "subregions": "https://linked.data.gov.au/dataset/ibra7/subregions",
17
- "bioregions": "https://linked.data.gov.au/dataset/ibra7",
16
+ "ibra7-subregions": "https://linked.data.gov.au/dataset/ibra7/subregions",
17
+ "ibra7-bioregions": "https://linked.data.gov.au/dataset/ibra7",
18
18
  "nrm-regions": "https://linked.data.gov.au/dataset/ausnrm2023",
19
19
  "states-and-territories": "https://linked.data.gov.au/dataset/asgsed3/STE",
20
20
  "local-government-areas": "https://linked.data.gov.au/dataset/asgsed3/LGA2023",
21
21
  "wwf-ecoregions": "https://linked.data.gov.au/dataset/wwf2011",
22
22
  "terrestrial-capad-regions": "https://linked.data.gov.au/dataset/auscapad2022",
23
+ "indigenous-areas": "https://linked.data.gov.au/dataset/asgsed3/IARE",
24
+ "indigenous-locations": "https://linked.data.gov.au/dataset/asgsed3/ILOC",
25
+ "indigenous-regions": "https://linked.data.gov.au/dataset/asgsed3/IREG",
23
26
  }
24
27
 
25
28
  REGION_TYPES = list(REGION_TYPES_MAP.keys())
@@ -127,10 +130,15 @@ def resolve_region_type(
127
130
 
128
131
  # --- Case 2: Input is label (not URL) ---
129
132
  # Normalize user input
130
- user_input = re.sub(
131
- r"\bibra7[-_ ]*", "", user_input, flags=re.IGNORECASE
132
- ) # Remove 'ibra7' prefix if present
133
- cleaned_input = user_input.strip().replace(" ", "-").lower()
133
+ cleaned_input = re.sub(r"[-_\s]+", "-", user_input.strip()).lower()
134
+ cleaned_input = {
135
+ "bioregions": "ibra7-bioregions",
136
+ "subregions": "ibra7-subregions",
137
+ }.get(cleaned_input, cleaned_input)
138
+
139
+ if cleaned_input in allowed_region_types:
140
+ return cleaned_input
141
+
134
142
  if cleaned_input.startswith("l"):
135
143
  threshold = 20
136
144
  result = process.extractOne(cleaned_input, allowed_region_types, scorer=fuzz.QRatio) # type: ignore
@@ -64,9 +64,14 @@ _FILE_FORMAT_SUFFIXES = {
64
64
 
65
65
  def _dataframe_to_parquet_bytes(df: pd.DataFrame) -> bytes:
66
66
  """Serialise a dataframe to parquet bytes."""
67
+ parquet_df = df.copy()
68
+ for column in parquet_df.select_dtypes(include=["object", "string"]).columns:
69
+ values = parquet_df[column].astype(object)
70
+ parquet_df[column] = values.mask(values.eq("N/A"), None)
71
+
67
72
  buffer = io.BytesIO()
68
73
  try:
69
- df.to_parquet(buffer, index=False)
74
+ parquet_df.to_parquet(buffer, index=False)
70
75
  except (ImportError, ValueError) as exc:
71
76
  raise EcoPlotsError(
72
77
  "Parquet output requires pyarrow. Reinstall or upgrade with: "
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '1.1.2.dev12'
22
- __version_tuple__ = version_tuple = (1, 1, 2, 'dev12')
21
+ __version__ = version = '1.1.2.dev13'
22
+ __version_tuple__ = version_tuple = (1, 1, 2, 'dev13')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: terndata.ecoplots
3
- Version: 1.1.2.dev12
3
+ Version: 1.1.2.dev13
4
4
  Summary: Python client for discovering, filtering, and retrieving TERN EcoPlots observation and sample data
5
5
  Author-email: Avinash Chandra <avinash.chandra@uq.edu.au>
6
6
  Maintainer-email: "TERN Data Services and Analytics (TDSA)" <esupport@tern.org.au>
@@ -46,6 +46,7 @@ docs/api_internal/ecoplots._flatten_response.rst
46
46
  docs/api_internal/ecoplots._gui.rst
47
47
  docs/api_internal/ecoplots.rst
48
48
  docs/api_internal/modules.rst
49
+ examples/README.md
49
50
  examples/demo.ipynb
50
51
  examples/demo_samples.ipynb
51
52
  examples/R examples/ReadMe.md
@@ -107,9 +107,11 @@ def test_get_data_rejects_invalid_format():
107
107
 
108
108
  def test_get_data_returns_parquet_bytes(monkeypatch):
109
109
  ec = MockEcoPlots(query_filters={"site_id": ["site-uri"]})
110
+ captured = {}
110
111
 
111
112
  def fake_to_parquet(self, path, index=False):
112
113
  assert index is False
114
+ captured["dataframe"] = self.copy()
113
115
  path.write(b"PARQUET")
114
116
 
115
117
  monkeypatch.setattr(pd.DataFrame, "to_parquet", fake_to_parquet)
@@ -117,6 +119,8 @@ def test_get_data_returns_parquet_bytes(monkeypatch):
117
119
  payload = ec.get_data(dformat="parquet")
118
120
 
119
121
  assert payload == b"PARQUET"
122
+ assert captured["dataframe"].loc[0, "b"] is None
123
+ assert captured["dataframe"].loc[1, "a"] is None
120
124
 
121
125
 
122
126
  def test_export_data_writes_nested_csv(tmp_path):
@@ -2,6 +2,7 @@ import pandas as pd
2
2
  import pytest
3
3
 
4
4
  from terndata.ecoplots import EcoPlotsError
5
+ from terndata.ecoplots._nlp_utils import resolve_region_type
5
6
  from terndata.ecoplots._utils import (
6
7
  _align_and_concat,
7
8
  _ensure_ecoproj_path,
@@ -11,6 +12,32 @@ from terndata.ecoplots._utils import (
11
12
  )
12
13
 
13
14
 
15
+ @pytest.mark.parametrize(
16
+ "raw",
17
+ [
18
+ "IBRA7 Bioregions",
19
+ "IBRA7-Bioregions",
20
+ "ibra7_bioregions",
21
+ "bioregions",
22
+ ],
23
+ )
24
+ def test_resolve_region_type_accepts_ibra7_bioregion_aliases(raw):
25
+ assert resolve_region_type(raw) == "ibra7-bioregions"
26
+
27
+
28
+ @pytest.mark.parametrize(
29
+ "raw",
30
+ [
31
+ "IBRA7 Subregions",
32
+ "IBRA7-Subregions",
33
+ "ibra7_subregions",
34
+ "subregions",
35
+ ],
36
+ )
37
+ def test_resolve_region_type_accepts_ibra7_subregion_aliases(raw):
38
+ assert resolve_region_type(raw) == "ibra7-subregions"
39
+
40
+
14
41
  @pytest.mark.parametrize(
15
42
  ("raw", "expected"),
16
43
  [