EcoPlots Library — Workflow Reference

A quick-reference guide for all supported workflows in both observations and samples modes.


Clients

Sync

Async

Class

EcoPlots

AsyncEcoPlots

get_data()

Blocking

await-able

Everything else

Sync

Sync (inherited)

from terndata.ecoplots import EcoPlots, AsyncEcoPlots

# Observations (default)
ec = EcoPlots()
aec = AsyncEcoPlots()

# Samples
ec = EcoPlots(mode="samples")
aec = AsyncEcoPlots(mode="samples")

Filter Management

All filter methods return self — they are fully chainable.

select()

# Keyword arguments
ec.select(site_id="TCFTNS0002")
ec.select(region_type="States and Territories")

# Dict style
ec.select({"site_id": "TCFTNS0002", "dataset": "TERN Ecosystem Surveillance"})

# Chained
ec.select(site_id="TCFTNS0002").select(feature_type="soil profile")

Values are fuzzy-resolved against the API vocabulary. If the resulting selection yields zero records the filter is automatically rolled back with a warning.

remove()

ec.remove(site_id="TCFTNS0002")          # remove one value
ec.remove(site_id=["A", "B"])            # remove multiple values
ec.remove(site_id=None)                  # remove entire facet
ec.remove({"site_id": None, "dataset": None})

clear()

ec.clear()   # reset all filters
             # in samples mode the mandatory dataset filter is preserved

get_filter() / get_api_query_filters()

ec.get_filter()                   # all human-readable filters
ec.get_filter("site_id")          # one facet
ec.get_api_query_filters()        # all resolved API (URI) filters
ec.get_api_query_filters("dataset")

Date Range Filtering

Available in both modes. Inputs are parsed tolerantly — day-first is assumed for all-numeric formats (DD/MM/YYYY). MM-DD-YYYY is never accepted.

# Chainable helpers
ec.from_date("01/01/2020").till("31/12/2022")

# Equivalent using select()
ec.select(date_from="21st May 2020", date_to="May 31 2022")

# Mix of formats — all normalised to YYYY-MM-DD internally
ec.from_date("1st Jan 2021").till("2022-06-30")

Accepted formats (examples): "21/05/2020", "21-05-2020", "21st May 2020", "May 20 2020", "2020-05-21", "March 3rd 2021".


Observations Mode

Filter Facets

Facet

Description

region_type

e.g. "States and Territories", "IBRA7 Bioregions"

region

Must be used together with region_type

dataset

e.g. "TERN Ecosystem Surveillance"

site_id

e.g. "TCFTNS0002"

site_visit_id

Site visit identifier

feature_type

e.g. "soil profile", "plant occurrence"

observed_property

e.g. "soil pH"

spatial

WKT string or GeoJSON geometry dict

project

Project identifier

date_from / date_to

Date range (any recognisable format)

Discovery

ec.get_datasources()            # available datasets
ec.get_sites()                  # available sites
ec.get_region_types()           # available region types
ec.get_regions("States and Territories")   # regions for a type
ec.get_feature_types()          # available feature types
ec.get_observed_properties()    # available observed properties
ec.get_used_procedures()        # available used procedures

# Attribute lookups (returns metadata for what's selected)
ec.get_datasources_attributes()
ec.get_sites_attributes()
ec.get_site_visit_attributes()
ec.get_observation_attributes()

Preview & Summary

ec.summary()                    # record counts as DataFrame
ec.summary(dformat="json")      # raw API dict

ec.preview()                    # first ~10 rows as GeoDataFrame
ec.preview(dformat="pandas")    # as DataFrame
ec.preview(dformat="geojson")   # raw GeoJSON dict

Retrieve Data

gdf = ec.get_data()                          # GeoDataFrame (default)
df  = ec.get_data(dformat="pandas")         # DataFrame
gj  = ec.get_data(dformat="geojson")        # GeoJSON string

# Allow full download with no filters (use with caution)
gdf = ec.get_data(allow_full_download=True)

# Async
gdf = await aec.get_data()
gdf = await aec.get_data(dformat="pandas")

Spatial Widget

widget = ec.select_spatial()    # interactive map — run in a notebook cell
# After drawing a shape, call ec.get_filter("spatial") to retrieve the WKT

Typical Observations Workflow

from terndata.ecoplots import EcoPlots

ec = EcoPlots()

# 1. Discover
ec.get_datasources()
ec.get_feature_types()

# 2. Filter
ec.select(dataset="TERN Ecosystem Surveillance") \
  .select(feature_type="soil profile") \
  .select(observed_property="soil pH") \
  .from_date("01/01/2019").till("31/12/2023")

# 3. Inspect
ec.summary()
ec.preview()

# 4. Retrieve
gdf = ec.get_data()

# 5. Save project
ec.save("my_soil_query.ecoproj")

Samples Mode

The mandatory TERN Ecosystem Surveillance dataset is always set — it cannot be removed.

Filter Facets

Facet

Description

region_type

Same as observations

region

Same as observations

dataset

Fixed — "TERN Ecosystem Surveillance"

site_id

e.g. "SAAKAN0002"

soil_subsite_id

Integer or list of integers

soil_depth_range

[min, max] or {"min": x, "max": y} (metres)

speciesname

e.g. "Acacia aneura" — fuzzy-matched

material_sample_type

One of the 5 types below

used_procedure

Procedure URI or label

has_image

True / False

spatial

WKT string or GeoJSON geometry dict

date_from / date_to

Date range (any recognisable format)

Material Sample Types

Label

Notes

"Plant Tissue Sample"

"Plant Voucher Specimen"

Required for view_sample_igsn() and get_speciesname()

"Soil Metagenomic Sample"

Required for get_soilpit()

"Soil Pit Sample"

Required for get_soil_depth_range()

"Soil Subsite Sample"

Required for get_soil_depth_range() and get_soilpit()

Discovery

ec = EcoPlots(mode="samples")

ec.get_datasources()             # always returns TERN Ecosystem Surveillance
ec.get_sites()
ec.get_region_types()
ec.get_regions("IBRA7 Bioregions")
ec.get_material_sample_types()   # 5 material sample types
ec.get_used_procedures()         # available procedures

Preview & Summary

ec.summary()
ec.preview()                     # returns GeoDataFrame (first 10 rows)
ec.preview(dformat="pandas")     # as DataFrame
# Note: "geojson"/"json" not supported in samples mode

Retrieve Data

# Select exactly one material_sample_type before calling get_data()
ec.select(material_sample_type="Plant Voucher Specimen")

gdf = ec.get_data()                     # GeoDataFrame
df  = ec.get_data(dformat="pandas")    # DataFrame

# Async
gdf = await aec.get_data()

IGSN Viewer

ec.select(material_sample_type="Plant Voucher Specimen")

df_igsn = ec.get_sample_igsn()           # DataFrame: sample_name, igsn

# Interactive DOI viewer widget (notebook)
ec.view_sample_igsn()                    # dropdown of all IGSNs
ec.view_sample_igsn("10.60792/qda030489")          # specific IGSN
ec.view_sample_igsn("https://doi.org/10.60792/...")  # full DOI URL

Soil Analysis

# Depth range — requires Soil Pit Sample or Soil Subsite Sample
ec.select(material_sample_type="Soil Pit Sample")
ec.get_soil_depth_range()        # GeoDataFrame with depth stats

# Soil pit distribution — requires Soil Metagenomic or Soil Subsite Sample
ec.select(material_sample_type="Soil Subsite Sample")
ec.get_soilpit()                 # DataFrame: soilpit, counts

# Depth range filter
ec.select(soil_depth_range=[0, 0.1])
ec.select(soil_depth_range={"min": 0, "max": 0.3})

Species Distribution

# Requires Plant Tissue Sample or Plant Voucher Specimen
ec.select(material_sample_type="Plant Voucher Specimen")

ec.get_speciesname()             # DataFrame: speciesname, count

# Filter to a specific species (fuzzy-matched)
ec.select(speciesname="Acacia aneura")

Sample Image Viewer

ec.select(material_sample_type="Plant Voucher Specimen")
ec.select(has_image=True)

# Lazy — fetches data automatically
viewer = ec.view_sample_images()
viewer   # display in notebook

# Pre-fetched data
df = ec.get_data(dformat="pandas")
viewer = ec.view_sample_images(data=df)

Spatial Widget

widget = ec.select_spatial()   # same as observations mode

Typical Samples Workflow

from terndata.ecoplots import AsyncEcoPlots

ec = AsyncEcoPlots(mode="samples")

# 1. Discover
ec.get_material_sample_types()
ec.get_sites()

# 2. Filter
ec.select(material_sample_type="Plant Voucher Specimen") \
  .select(region_type="States and Territories") \
  .select(region="Queensland") \
  .select(has_image=True) \
  .from_date("2020-01-01").till("2023-12-31")

# 3. Inspect
ec.summary()
ec.preview()

# 4. Retrieve
gdf = await ec.get_data()

# 5. Explore
viewer = ec.view_sample_images(data=gdf.pipe(lambda d: d))
ec.view_sample_igsn()

# 6. Save
ec.save("plant_vouchers_qld.ecoproj")

Save & Load Projects

# Save current filter state to a .ecoproj file
path = ec.save()                        # timestamped filename
path = ec.save("my_project.ecoproj")    # custom filename

# Reload
ec2 = EcoPlots.load("my_project.ecoproj")
ec2.get_filter()                        # filters restored

# Works for samples mode too
ec2 = AsyncEcoPlots.load("plant_vouchers_qld.ecoproj")

Quick Reference Table

Method

Obs

Samples

Notes

select()

Chainable; validates & fuzzy-resolves

remove()

Chainable

clear()

Samples keeps mandatory dataset

from_date() / till()

Chainable; smart date parsing

get_filter()

get_api_query_filters()

summary()

preview()

Samples: no geojson/json format

get_data()

Async in AsyncEcoPlots

get_datasources()

get_sites()

get_region_types()

get_regions()

get_feature_types()

get_observed_properties()

get_used_procedures()

get_observation_attributes()

get_datasources_attributes()

get_sites_attributes()

get_site_visit_attributes()

get_material_sample_types()

get_sample_igsn()

Requires Plant Voucher Specimen

view_sample_igsn()

Requires Plant Voucher Specimen

get_soil_depth_range()

Requires Soil Pit/Subsite Sample

get_soilpit()

Requires Soil Metagenomic/Subsite

get_speciesname()

Requires Plant Tissue/Voucher

view_sample_images()

select_spatial()

Notebook widget

save() / load()

.ecoproj binary format