EcoPlots Samples Workflow¶
The EcoPlots client in samples mode lets you discover and retrieve
physical specimen samples collected during field surveys — including soil,
plant tissue, and plant voucher specimens — along with associated metadata
such as IGSN identifiers and sample images.
from terndata.ecoplots import EcoPlots
ec = EcoPlots(mode="samples") # enable samples mode
ec.select(material_sample_type="Soil Pit Sample") # pick a sample type
ec.preview()
df = ec.get_data(dformat="pd") # returns a DataFrame
Note
All methods on this page are available on both
EcoPlots (synchronous) and
AsyncEcoPlots (asynchronous).
For AsyncEcoPlots, use df = await ec.get_data(dformat="pd") in the
final step.
Note
In samples mode the TERN Ecosystem Surveillance dataset is always
applied automatically. You cannot remove it; it is required for all sample
queries.
Note
A runnable walkthrough of all samples-mode features is available in the Samples Demo Notebook.
Creating the Client¶
from terndata.ecoplots import EcoPlots
# Pass mode="samples" at creation time
ec = EcoPlots(mode="samples")
# Or reload a saved samples project
ec = EcoPlots.load("my_samples.ecoproj")
Selectables & Discoverable Facets¶
Filters passed to select() are called facets. The table below lists
every facet available in samples mode, what it represents, and the discovery
method you can call to see valid values for it.
Facet |
Type |
Description |
Discover with |
|---|---|---|---|
|
str |
Sample type. Exactly one must be selected before calling
|
|
|
str / list |
Dataset. Fixed to TERN Ecosystem Surveillance — applied automatically and cannot be removed. |
|
|
str / list |
One or more site identifiers. |
|
|
str |
Category of geographic region (e.g. |
|
|
str / list |
Region name(s) within the chosen |
|
|
str / list |
Species name. Applicable to plant tissue and voucher sample types only. |
|
|
int / list[int] |
Soil sub-site identifier(s). Applicable to soil sample types only. |
|
|
[min, max] |
Filter samples by soil depth in metres. Applicable to soil sample types only. |
|
|
bool |
If |
— (pass |
|
WKT / GeoJSON |
Spatial bounding geometry to restrict results geographically.
Set interactively via |
|
Discovery Methods¶
Use these methods to explore what samples data is available before downloading.
All return pandas.DataFrame and respect your current filters.
Material Sample Types¶
- EcoPlots.get_material_sample_types()[source]
Get the material sample types from the applied filters. Available only in “samples” mode.
- Returns:
A DataFrame containing the material sample types.
- Raises:
EcoPlotsError – If called in a mode other than “samples”.
- Return type:
DataFrame
Available types
Label |
Description |
|---|---|
|
Subsampled tissue taken from a collected plant |
|
Full pressed herbarium voucher specimen (may have images) |
|
Bulk soil sample from a defined pit depth |
|
Replicate soil samples from sub-locations within a site |
|
DNA-grade soil sample for metagenomic analysis |
Example
ec.get_material_sample_types()
Datasets¶
- EcoPlots.get_datasources()[source]
Get the data sources available for applied filters.
- Returns:
A DataFrame containing the data sources.
- Return type:
DataFrame
Sites¶
- EcoPlots.get_sites()[source]
Get the sites from the applied filters.
- Returns:
A DataFrame containing the sites.
- Return type:
DataFrame
Regions¶
- EcoPlots.get_region_types()[source]
Get the available region types from the applied filters.
- Returns:
A DataFrame containing the region types.
- Return type:
DataFrame
- EcoPlots.get_regions(region_type)[source]
Get the available regions for a specific region type from the applied filters.
- Parameters:
region_type (str) – The region type to retrieve regions for.
- Returns:
A DataFrame containing the regions for the specified region type.
- Return type:
DataFrame
Species Names¶
- EcoPlots.get_speciesname()[source]
Get species name distribution for the current filters.
Available only in “samples” mode.
This method preserves all current query filters, including
has_image.- Returns:
A DataFrame with two columns –
speciesnameandcount.- Raises:
EcoPlotsError – If called in a mode other than “samples”.
EcoPlotsError – If none of the required material sample types are selected.
- Return type:
DataFrame
Example (requires Plant Tissue Sample or Plant Voucher Specimen selected)
ec.select(material_sample_type="Plant Voucher Specimen")
ec.get_speciesname()
Filter Methods¶
All filter methods return self for chaining.
- EcoPlots.select(filters=None, **kwargs)
Add/merge filters and validate them.
Accepts either a dict or keyword arguments.
- Parameters:
filters (dict | None) – Mapping like
{"site_id": [...], "dataset": [...]}.**kwargs –
Alternative way to pass filters, e.g.
site_id="ABC". Special keyword filters (handled separately from facet resolution):spatial: WKT string or GeoJSON geometrydictto spatially restrict results to a custom region.has_image(bool, samples mode only): Limit to samples that have attached images.soil_subsite_id(intorlist[int], samples mode only): Restrict to specific soil sub-site identifiers.soil_depth_range([min, max]or{"min": x, "max": y}, samples mode only): Filter samples by soil depth in metres.date_from(str): Earliest date (inclusive) in any recognisable format —"DD/MM/YYYY","21 May 2020","21st May 2020","YYYY-MM-DD"etc. Normalised to"YYYY-MM-DD"internally. Day-first is assumed for all-numeric inputs (MM-DD-YYYYis never accepted).date_to(str): Latest date (inclusive), same format rules asdate_from.
self (SelfType)
- Raises:
EcoPlotsError – Unknown filter keys.
EcoPlotsError –
regionprovided without current or newregion_type.
- Returns:
self for chaining.
- Return type:
SelfType
- EcoPlots.remove(filters=None, **kwargs)
Remove whole facets or specific values (same ergonomics as
select).- Accepts either a dict or keyword arguments. For each facet:
value is
None→ remove the entire facetvalue is a string → remove that single value
value is a list/tuple → remove those values
- Parameters:
filters (dict | None) – Mapping like
{"site_id": ["TCFTNS0002"], "dataset": None}.**kwargs – Alternative way to pass removals, e.g.
site_id="TCFTNS0002".self (SelfType)
- Raises:
EcoPlotsError – Unknown filter keys (not in
QUERY_FACETS).EcoPlotsError – If
datasetis targeted while insamplesmode (theTERN Ecosystem Surveillancedataset is protected).KeyError – Facet not present in current filters.
EcoPlotsError – Specific values requested but not found for that facet.
- Returns:
self (chainable)
- Return type:
SelfType
- EcoPlots.clear()
Clear all filters from the instance.
The method mutates the instance and returns it to allow fluent/chained calls.
- Returns:
self (chainable)
- Parameters:
self (SelfType)
- Return type:
SelfType
Notes
In
samplesmode theTERN Ecosystem Surveillancedataset filter is preserved; only user-added filters are cleared.
- EcoPlots.get_filter(facet=None)
Return the current filter values for a specific facet or all applied filters.
- Parameters:
facet (str | None) – The facet to retrieve the filter for. Defaults to All.
- Raises:
EcoPlotsError – If an invalid facet name is provided.
- Returns:
A list of values for the specified facet, or
Noneif the facet is not currently applied. If facet isNone, returns adictmapping each applied facet to its list of values.- Return type:
list | dict | None
- EcoPlots.get_api_query_filters(facet=None)
Return the current query filters for ecoplots API for a specified facet or all facet.
- Parameters:
facet (str | None) – The facet to retrieve the query filters for. Defaults to None.
- Raises:
EcoPlotsError – If an invalid facet name is provided.
- Returns:
A list of resolved API values for the specified facet, or
Noneif the facet is not currently applied. If facet isNone, returns adictof all resolved query filters.- Return type:
list | dict | None
Samples-specific filter options
The following extra keyword arguments are accepted by select() only in
samples mode:
Keyword |
Type |
Description |
|---|---|---|
|
|
Filter to a specific sample type (see table above). |
|
|
If |
|
|
Restrict to specific soil sub-site identifiers. |
|
|
Restrict samples by soil depth in metres. |
Example
ec.select(
material_sample_type="Soil Pit Sample",
soil_depth_range=[0.0, 0.5],
)
# Filter to samples with images only
ec.select(
material_sample_type="Plant Voucher Specimen",
has_image=True,
)
Note
Exactly one material_sample_type must be selected before calling
get_data() in samples mode.
IGSN Identifiers¶
Every sample in the TERN Ecosystem Surveillance program is registered with the International Geo Sample Number (IGSN) system and assigned a persistent DOI. The IGSN DOI landing page for a sample is its authoritative record — it displays the officially registered attributes for that sample, including collection date, location, sample type, and parentage.
get_sample_igsn() returns a DataFrame of sample names paired with their
IGSN DOIs. view_sample_igsn() opens an interactive widget with an embedded
iframe that loads the DOI landing page for any sample you select from a dropdown.
- EcoPlots.get_sample_igsn()[source]
Get sample names and derived IGSN values.
Available only in
samplesmode. This method discoverssample_namevalues using the current query filters, then returns a DataFrame with: -sample_name: sample name with alphabetic characters capitalized. -igsn: derived as10.60792/{sample_name_raw}.- Returns:
A DataFrame with columns
sample_nameandigsn.- Raises:
EcoPlotsError – If called in a mode other than
samples.- Return type:
DataFrame
- EcoPlots.view_sample_igsn(igsn=None)[source]
Open an interactive notebook viewer for sample IGSN DOI pages.
Available only in
samplesmode. This method discovers sample names, builds IGSN values, and displays either: - a dropdown + iframe widget (default), or - a single iframe for a provided IGSN/DOI value.- Parameters:
igsn (str | None) – Optional IGSN value or DOI URL. Accepted inputs include
10.60792/...,doi.org/10.60792/..., andhttps://doi.org/10.60792/....- Returns:
ipywidgets.VBox – Interactive IGSN viewer widget.
- Raises:
EcoPlotsError – If called in a mode other than
samples.EcoPlotsError – If no material sample type is selected.
Example
# Retrieve IGSN DOIs for the currently filtered samples
ec.get_sample_igsn()
# Open the IGSN viewer widget — choose a sample to load its
# DOI landing page (registered attributes) in the embedded iframe
ec.view_sample_igsn()
# Or navigate directly to a known sample's landing page
ec.view_sample_igsn(igsn="10.60792/AUSM-0017401")
The IGSN viewer widget. Choose a sample from the dropdown to load its IGSN DOI landing page — displaying the officially registered attributes for that sample — in the embedded iframe.¶
Soil Analysis¶
- EcoPlots.get_soil_depth_range()[source]
Get the soil depth range for the current filters.
Available only in “samples” mode.
- Returns:
A GeoDataFrame containing aggregated soil depth range values.
- Raises:
EcoPlotsError – If called in a mode other than “samples”.
EcoPlotsError – If none of the required material sample types are selected.
- Return type:
geopandas.GeoDataFrame
- EcoPlots.get_soilpit()[source]
Get soil pit distribution for the current filters.
Available only in “samples” mode.
- Returns:
A DataFrame with two columns –
soilpitandcounts.- Raises:
EcoPlotsError – If called in a mode other than “samples”.
EcoPlotsError – If none of the required material sample types are selected.
- Return type:
DataFrame
Example (requires a soil material sample type to be selected)
ec.select(material_sample_type="Soil Pit Sample")
# Aggregated depth-range summary as a GeoDataFrame
ec.get_soil_depth_range()
# Soil pit distribution counts
ec.get_soilpit()
Sample Image Viewer¶
For samples that have photographs attached, view_sample_images() opens an
interactive viewer. Each image may be available in multiple resolutions — the
viewer lets you select the resolution you want to display.
- EcoPlots.view_sample_images(data=None, image_column='sample_images', sample_id_column='sample_id', sample_name_column='sample_name', scientific_name_column='scientific_name')[source]
Open an interactive notebook image browser for sample images.
- Parameters:
data (DataFrame | None) – Optional DataFrame to browse. If omitted, data is fetched in samples mode using current filters.
image_column (str) – Name of image column in dataframe.
sample_id_column (str) – Name of sample identifier column in dataframe.
sample_name_column (str) – Name of sample name column in dataframe.
scientific_name_column (str) – Name of scientific name column in dataframe.
- Returns:
ipywidgets.VBox – Interactive viewer widget.
Example
ec.select(
material_sample_type="Plant Voucher Specimen",
has_image=True,
)
ec.view_sample_images() # fetches data and opens the image viewer widget
The sample image viewer widget. Navigate through specimen photos using the previous/next controls.¶
Spatial Filter Widget¶
Draw a polygon or rectangle on a map to restrict results to a geographic area.
- EcoPlots.select_spatial(**kwargs)[source]
Open the spatial selection widget.
A minimal map based spatial selector, similar to spatial selection tool in EcoPlots Portal.
- Parameters:
**kwargs – Additional keyword arguments to pass to the widget.
- Returns:
ipywidgets.VBox – The widget. Use it in a notebook cell to display.
Example
ec.select_spatial()
Data Preview & Retrieval¶
- EcoPlots.summary(dformat=None)[source]
Summarize the EcoPlots data.
- Parameters:
dformat (str | None) – The desired format for the summary. If
"json", returns the raw summarydictfrom the API. Defaults toNone, which returns apandas.DataFrame.- Returns:
When dformat is
"json", returns the raw summarydictfrom the API. Otherwise, returns apandas.DataFramewith columnsmetricandcountsummarising the current selection (e.g. total observations, unique sites, datasets).- Return type:
DataFrame | str
- EcoPlots.preview(dformat=None)[source]
Fetch a small preview of EcoPlots data. # noqa: DAR401, D415
Mirrors
get_data()but limits results to 10 records for a quick look.In
observationsmode, fetches CSV from up to 2 feature types (5 rows each). Insamplesmode, calls the samples endpoint and returns the first 10 rows;"geojson"/"json"formats are not supported in this mode.- Parameters:
dformat (str | None) – Output format. -
"geojson"or"json": returns a GeoJSON dict (observations only). -"pandas"(or"pd"): returns apandas.DataFrame. -"geopandas"(or"gpd") (default): returns aGeoDataFrame.- Returns:
Preview data in the requested format.
- Raises:
EcoPlotsError – If an invalid dformat is provided.
RuntimeError – If no feature types found (observations mode).
- Return type:
geopandas.GeoDataFrame | dict | str
- EcoPlots.get_data(allow_full_download=False, dformat='gpd')[source]
Retrieve EcoPlots data based on the current filters.
- Parameters:
allow_full_download (bool | None) – If True, allows downloading the full dataset without filters. Defaults to False.
dformat (str | None) –
Output format. - “geojson” or “json”: returns a pretty-printed GeoJSON string. - “pandas” (or ‘pd’): returns a pandas DataFrame. - “geopandas” (or ‘gpd’) (default): returns a GeoDataFrame.
In “samples” mode, only “pandas”/”pd” and “geopandas”/”gpd” are supported (no “geojson”/”json”).
In “samples” mode, exactly one
material_sample_typemust be selected at a time.
- Raises:
RuntimeError – If no filters are set and allow_full_download is False.
EcoPlotsError – If an invalid dformat is provided.
- Returns:
Data in the requested format.
- Return type:
geopandas.GeoDataFrame
Typical workflow
# 1. Confirm there are matching records
ec.summary()
# 2. Quick preview before full download
ec.preview()
# 3. Download the full dataset
df = ec.get_data(dformat="pd") # pandas DataFrame
gdf = ec.get_data() # GeoDataFrame (default)
Note
In samples mode get_data() does not support the
"geojson" / "json" formats. Use "pd" or "gpd" only.
Project Save / Load¶
- EcoPlots.save(path=None)
Save project state to a single .ecoproj file (atomic, checksummed).
Writes the current filters and query_filters into a compact binary file with a small header and a JSON (orjson) payload. The filename resolution is:
If path is None: save as ./ecoplots_<UTCSTAMP>.ecoproj.
- If path has no .ecoproj suffix and no parent directory: save as
./<name>.ecoproj in the current working directory.
If path ends with .ecoproj: save exactly to that location.
- Parameters:
path (str | Path | None) – Optional target path or bare name. If omitted, a timestamped filename is created in the current working directory.
- Returns:
Absolute path to the saved .ecoproj file.
- Raises:
Exception – Any unexpected error during the write; temporary files are cleaned up best-effort before re-raising.
- Return type:
str
- classmethod EcoPlots.load(path)
Load a .ecoproj file, validate integrity, and return a new instance.
- Parameters:
path (str | Path) – Path to a .ecoproj file previously created by
save().- Returns:
A new instance of the calling class with
filtersandquery_filtersrestored from the file.- Raises:
FileNotFoundError – If the file does not exist.
EcoPlotsError – If the file does not have a .ecoproj suffix, the magic header or version is invalid, the file is truncated, or the checksum does not match the payload.
- Return type:
SelfType
Example
path = ec.save("soil_pit_survey.ecoproj")
# Reload — mode and all filters are fully restored
ec2 = EcoPlots.load(path)
ec2.get_filter()