EcoPlots

Overview

EcoPlots is the synchronous client. It is the best choice for most notebook and script workflows, especially if you are new to Python.

Constructor Parameters

Signature:

EcoPlots(filterset=None, query_filters=None, mode="observations")

What each parameter means:

Parameter

Type

What it sets

Should you set it manually?

filterset

dict or None

Starting human-readable filters.

Usually no. Prefer using select() after creation.

query_filters

dict or None

Internal API-ready filter values.

No. Keep this internal.

mode

str

"observations" (default) or "samples".

Yes, only when you intentionally need samples workflows.

Internal Variables: Do Not Edit Manually

Avoid directly changing these internal attributes:

  • _filters

  • _query_filters

  • _mode

  • _base_url

Use public methods instead (for example select(), remove(), summary(), preview() and get_data()).

class terndata.ecoplots.ecoplots.EcoPlots(filterset=None, query_filters=None, mode='observations')[source]

Bases: EcoPlotsBase

High-level Python client for the EcoPlots REST API.

Provides a small, Pythonic surface for discovering, filtering, previewing, and retrieving ecological plot data. Returns tidy structures for analysis (pandas.DataFrame, geopandas.GeoDataFrame) or raw GeoJSON.

The class mirrors the async runtime (AsyncEcoPlots) but is synchronous for notebook and script workflows. Projects can be serialised and reloaded via .ecoproj files to make analyses reproducible.

Examples

Basic usage:

from terndata.ecoplots import EcoPlots

ecoplots = EcoPlots()
ecoplots.get_datasources().head()         # discover datasets
ecoplots.select(site_id="TCFTNS0002")     # add filters (validated & fuzzy-resolved)
ecoplots.preview().head()                 # quick look (first page)
df = ecoplots.get_data()                  # full pull as GeoDataFrame

Save / load a project:

path = ecoplots.save("myproject.ecoproj")
ecoplots2 = EcoPlots.load(path)
ecoplots2.get_filter("site_id")           # ['TCFTNS0002']

See also

AsyncEcoPlots: Async counterpart with the same surface area.

Parameters:
  • filterset (dict | None)

  • query_filters (dict | None)

  • mode (str | None)

summary(dformat=None)[source]

Summarize the EcoPlots data.

Parameters:

dformat (str | None) – The desired format for the summary. If "json", returns the raw summary dict from the API. Defaults to None, which returns a pandas.DataFrame.

Returns:

When dformat is "json", returns the raw summary dict from the API. Otherwise, returns a pandas.DataFrame with columns metric and count summarising the current selection (e.g. total observations, unique sites, datasets).

Return type:

DataFrame | str

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 observations mode, fetches CSV from up to 2 feature types (5 rows each). In samples mode, 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 a pandas.DataFrame. - "geopandas" (or "gpd") (default): returns a GeoDataFrame.

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

get_datasources()[source]

Get the data sources available for applied filters.

Returns:

A DataFrame containing the data sources.

Return type:

DataFrame

get_datasources_attributes()[source]

Get the attributes of data sources from the applied filters.

Returns:

A DataFrame containing the attributes of the data sources.

Return type:

DataFrame

get_sites()[source]

Get the sites from the applied filters.

Returns:

A DataFrame containing the sites.

Return type:

DataFrame

get_sites_attributes()[source]

Get the attributes of sites from the applied filters.

Returns:

A DataFrame containing the attributes of the sites.

Return type:

DataFrame

get_site_visit_attributes()[source]

Get the attributes of site visits from the applied filters.

Returns:

A DataFrame containing the attributes of the site visits.

Return type:

DataFrame

get_region_types()[source]

Get the available region types from the applied filters.

Returns:

A DataFrame containing the region types.

Return type:

DataFrame

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

get_feature_types()[source]

Get the feature types from the applied filters.

Returns:

A DataFrame containing the feature types.

Return type:

DataFrame

get_observed_properties()[source]

Get the observed properties from the applied filters.

Returns:

A DataFrame containing the observed properties.

Return type:

DataFrame

get_used_procedures()[source]

Get the used procedures available for the current filters.

Available in both observations and samples modes.

Returns:

A DataFrame containing the used procedures.

Return type:

DataFrame

get_observation_attributes()[source]

Get the attributes of observations from the applied filters. Available only in “observations” mode.

Returns:

A DataFrame containing the attributes of the observations.

Raises:

EcoPlotsError – If called in a mode other than “observations”.

Return type:

DataFrame

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

get_sample_igsn()[source]

Get sample names and derived IGSN values.

Available only in samples mode. This method discovers sample_name values using the current query filters, then returns a DataFrame with: - sample_name: sample name with alphabetic characters capitalized. - igsn: derived as 10.60792/{sample_name_raw}.

Returns:

A DataFrame with columns sample_name and igsn.

Raises:

EcoPlotsError – If called in a mode other than samples.

Return type:

DataFrame

view_sample_igsn(igsn=None)[source]

Open an interactive notebook viewer for sample IGSN DOI pages.

Available only in samples mode. 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/..., and https://doi.org/10.60792/....

Returns:

ipywidgets.VBox – Interactive IGSN viewer widget.

Raises:
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

get_soilpit()[source]

Get soil pit distribution for the current filters.

Available only in “samples” mode.

Returns:

A DataFrame with two columnssoilpit and counts.

Raises:
  • EcoPlotsError – If called in a mode other than “samples”.

  • EcoPlotsError – If none of the required material sample types are selected.

Return type:

DataFrame

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 columnsspeciesname and count.

Raises:
  • EcoPlotsError – If called in a mode other than “samples”.

  • EcoPlotsError – If none of the required material sample types are selected.

Return type:

DataFrame

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_type must 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

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.

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.

__bool__()

Truthiness of the instance.

The instance is considered truthy only when it has both human-facing _filters and resolved/_query_filters populated. This reflects that a fully-formed selection requires both sides.

Returns:

True if both _filters and _query_filters are non-empty, False otherwise.

Return type:

bool

Examples

Basic usage:

from terndata.ecoplots import EcoPlots

ec = EcoPlots()
bool(ec)  # False

ec.select(site_id="TCFTNS0002")
_ = ec.preview()           # or: _ = ec.get_data(); resolves query-side filters
bool(ec)  # True
__contains__(item)

Check if a facet is currently applied.

This method first validates the facet name against QUERY_FACETS. For internal consistency it returns True only if the facet exists in both the human-visible _filters and the resolved _query_filters. Raises a KeyError for unknown facets.

Parameters:

item (str) – Facet name to check.

Returns:

True if the facet is present in both _filters and _query_filters.

Raises:

KeyError – If the provided facet name is not known.

Return type:

bool

Examples

Basic usage:

ec = EcoPlots().select(site_id="TCFTNS0002")
_ = ec.preview()        # ensure resolution

"site_id" in ec  # True

# The following raises KeyError (unknown facet):
# "not_a_facet" in ec
__copy__()

Create a shallow copy of the instance.

The returned instance is of the same concrete type and receives shallow copies of the _filters and _query_filters mappings. This is useful for small modifications without affecting the original instance.

Returns:

A new instance (same type) with shallow-copied internal state.

Examples

Basic usage:

import copy
from terndata.ecoplots import EcoPlots

ec1 = EcoPlots().select(site_id="TCFTNS0002")
ec2 = copy.copy(ec1)
ec1 is ec2        # False
ec1 == ec2        # True (same filter state)
__deepcopy__(memo)

Create a deep copy of the instance.

Uses copy.deepcopy on the internal mappings to ensure no shared references remain between the new and original instance.

Parameters:

memo – Memoization dictionary passed by the copy protocol.

Returns:

A new instance (same type) with deeply-copied internal state.

Examples

Basic usage:

import copy
from terndata.ecoplots import EcoPlots

ec1 = EcoPlots().select(site_id=["TCFTNS0002", "TCFTNS0003"])
ec2 = copy.deepcopy(ec1)
ec1 is ec2        # False
ec1 == ec2        # True
__delitem__(key)

Delete a facet or specific values from a facet (delegates to remove).

The method validates provided facet names and delegates to remove(), raising appropriate errors for unknown facets or malformed keys.

Parameters:

key – Either a single facet name (str) or a tuple (facet, values).

Raises:

KeyError – If the facet is unknown or tuple form is malformed.

Return type:

None

Examples

Basic usage:

from terndata.ecoplots import EcoPlots

ec = EcoPlots()
del ec['site_id']                       # remove entire facet
del ec['site_id', 'TCFTNS0002']         # remove a single value
del ec['site_id', ['A','B','C']]        # remove multiple values
__eq__(other)

Compare two instances for structural equality.

Two instances are considered equal when they are of the exact same runtime type and both their internal _filters and _query_filters dicts compare equal.

Parameters:

other – Another object to compare against.

Returns:

True if both type and internal filter state match, False otherwise.

Return type:

bool

Examples

Basic usage:

from terndata.ecoplots import EcoPlots

ec1 = EcoPlots()
ec1.select(site_id="TCFTNS0002")

ec2 = EcoPlots()
ec2.select(site_id="TCFTNS0002")

ec1 == ec2  # True
__getitem__(item)

Retrieve the human-visible values for a given facet.

Validates the facet name and ensures it is present in the current instance. This is an internal accessor that returns the list of values stored in _filters for the facet.

Parameters:

item (str) – Facet name to retrieve.

Returns:

List of values for the facet.

Raises:

KeyError – If facet is invalid or not present in current filters.

Return type:

list

Examples

Basic usage:

from terndata.ecoplots import EcoPlots

ec = EcoPlots().select(site_id=["TCFTNS0002", "TCFTNS0003"])
ec["site_id"]  # ["TCFTNS0002", "TCFTNS0003"]
__len__()

Return the count of selected filter values.

The length is computed as the total number of individual values across all facets in self._filters (i.e. counts values, not facets).

Returns:

Total number of selected filter values (int).

Return type:

int

Examples

Basic usage:

from terndata.ecoplots import EcoPlots

ec = EcoPlots()
ec.select(site_id=["TCFTNS0002"], dataset="TERN Surveillance")
len(ec)  # 2
__repr__()

Return a string representation that can reconstruct the instance.

The representation is a valid Python expression that could be used to recreate an equivalent instance with the same filter configuration.

Returns:

A string representation suitable for debugging and reconstruction.

Return type:

str

__setitem__(facet, values)

Assign values to a facet (delegates to select).

This operator-style API is a convenience wrapper that validates the facet is allowed and then forwards the work to select(), which handles normalization and validation.

Parameters:
  • facet (str) – Facet name to set (must be listed in QUERY_FACETS).

  • values (str | list[str]) – Single value or iterable of values to apply to the facet.

Raises:

KeyError – If the facet is not allowed.

Examples

Basic usage:

from terndata.ecoplots import EcoPlots

ec = EcoPlots()
ec["site_id"] = "TCFTNS0002"
ec["site_id"] = ["TCFTNS0002", "TCFTNS0003"]
ec["dataset"] = "TERN Surveillance"
__str__()

Return a user-friendly string representation of the instance.

The string includes a professional header with the class name and version, followed by a clean, organized summary of the current filter configuration. Uses Unicode box-drawing characters for a polished, institutional look.

Returns:

A formatted string summarizing the instance and its filter state.

Return type:

str

Examples

>>> ec = EcoPlots()
>>> ec.select(site_id="TCFTNS0002")
>>> print(ec)
╔══════════════════════════════════════════════════════════════════════════════╗
║ EcoPlots Observations                                                        ║
║ Version: 1.0.0                                                               ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ Active Filters:                                                              ║
║   • site_id: TCFTNS0002                                                      ║
╚══════════════════════════════════════════════════════════════════════════════╝
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 samples mode the TERN Ecosystem Surveillance dataset filter is preserved; only user-added filters are cleared.

discover(discovery_facet, region_type=None)

Resolve and call the discovery endpoint for a facet.

Parameters:
  • discovery_facet (str) – Facet to discover (must resolve via configured discovery facets).

  • region_type (str | None) – Optional region type used when discovering regions.

Returns:

Parsed JSON payload returned by the discovery endpoint.

Raises:

EcoPlotsError – If the facet cannot be resolved.

Return type:

dict

Notes

  • Internal use only

  • A 60-second request timeout is enforced.

discover_attributes(discovery_attribute)

Discovers attribute URIs for a given entity type.

Parameters:

discovery_attribute (str) – Attribute namespace to discover (must resolve via configured discovery attributes).

Returns:

Parsed JSON payload containing attribute identifiers.

Raises:

EcoPlotsError – If the attribute cannot be resolved.

Return type:

dict

Notes

  • A 30-second request timeout is enforced.

  • Intended for internal use only.

discover_samples(discovery_facet, region_type=None)

Resolve and call the discovery endpoint for samples.

Parameters:
  • discovery_facet (str) – Facet to discover (must resolve via SAMPLE_DISCOVERY_FACETS).

  • region_type (str | None) – Optional region type used when discovering regions. Required when discovery_facet is “region”.

Returns:

Parsed JSON payload returned by the discovery endpoint.

Raises:

EcoPlotsError – If the facet cannot be resolved or region_type is missing when discovering regions.

Return type:

dict

Notes

  • Internal use only

  • A 60-second request timeout is enforced.

discover_soil_depth_range()

Discover soil depth range aggregates for the current query.

Sends the current samples query to the /samples/soildepth endpoint and returns a single-row GeoDataFrame with descriptive depth summary columns.

Returns:

geopandas.GeoDataFrame – One-row table with soil depth aggregate values.

Raises:

EcoPlotsError – If called outside samples mode.

discover_soilpit()

Discover soil pit distribution for the current samples query.

Sends the current query to the /samples/soilpit endpoint and returns a two-column table with the soil pit identifier and its document count.

Returns:

pandas.DataFrame – Columns are soilpit and counts.

Raises:

EcoPlotsError – If called outside samples mode.

discover_species()

Discover species name distribution for the current samples query.

Sends the current query to the /samples/speciesname endpoint and returns a two-column table with species name and document count.

Notes

  • Preserves all query filters including has_image.

Returns:

pandas.DataFrame – Columns are speciesname and count.

Raises:

EcoPlotsError – If called outside samples mode.

async fetch_data(page_number=None, page_size=None, dformat='geojson', **extras)

Fetch data for the current query, optionally paginated.

Posts the current query filters to EcoPlots API data endpoint.

Parameters:
  • page_number (int | None) – Page index to request. Must be provided together with page_size.

  • page_size (int | None) – Number of items per page. Must be provided together with page_number.

  • dformat (str) – Output format, either “geojson” (default) or “csv”.

  • **extras – Additional query filters to merge into the current query

Returns:

Parsed JSON payload (GeoJSON) returned by the data endpoint.

Raises:

EcoPlotsError – If an invalid dformat is provided.

Return type:

dict

Notes

  • Timeout is 300s (5 min) when pagination is used; 3000s (50 min) otherwise.

  • Socket read timeout matches total timeout; connection timeout is 30s.

  • Intended for internal use only.

async fetch_samples_data()

Fetch sample data from the samples endpoint.

Returns data as a geopandas GeoDataFrame extracted from the _source field of response hits.

Returns:

A geopandas GeoDataFrame with sample data.

Raises:

EcoPlotsError – If material_sample_type is not selected or if multiple material_sample_types are selected (only one allowed).

Notes

  • Timeout is 300s (5 min)

  • material_sample_type is required and must be single-valued

  • Intended for internal use only

from_date(date)

Set an earliest-date filter (inclusive).

Chainable with till(). The date string is parsed tolerantly — "DD/MM/YYYY", "21 May 2020", "21st May 2020", "YYYY-MM-DD" etc. are all accepted. For all-numeric inputs the day-first convention (DD-MM-YYYY) is always used.

Equivalent to select(date_from=date).

Parameters:
  • date (str) – Start date in any recognisable human format.

  • self (SelfType)

Returns:

self (chainable)

Raises:

EcoPlotsError – If the date string cannot be parsed.

Return type:

SelfType

Examples

ec.select(site_id="ABC").from_date("01/01/2020").to_date("31/12/2022")
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 None if the facet is not currently applied. If facet is None, returns a dict of all resolved query filters.

Return type:

list | dict | None

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 None if the facet is not currently applied. If facet is None, returns a dict mapping each applied facet to its list of values.

Return type:

list | dict | None

classmethod 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 filters and query_filters restored 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

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 facet

  • value 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 dataset is targeted while in samples mode (the TERN Ecosystem Surveillance dataset 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

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

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 geometry dict to spatially restrict results to a custom region.

    • has_image (bool, samples mode only): Limit to samples that have attached images.

    • soil_subsite_id (int or list[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-YYYY is never accepted).

    • date_to (str): Latest date (inclusive), same format rules as date_from.

  • self (SelfType)

Raises:
Returns:

self for chaining.

Return type:

SelfType

summarise_data(query_filters=None)

Request a lightweight summary for the given or current query filters.

Parameters:

query_filters (dict | None) – Canonical filters to use for the summary. When omitted, the instance’s current canonical query filters are used.

Returns:

Parsed JSON payload containing counts and related summary fields.

Return type:

dict

Notes

  • A 30-second request timeout is enforced.

  • Intended for internal use only.

to_date(date)

Set a latest-date filter (inclusive).

Chainable with from_date(). Accepts the same flexible date formats — "DD/MM/YYYY", "31 Dec 2022", "YYYY-MM-DD", etc.

Equivalent to select(date_to=date).

Parameters:
  • date (str) – End date in any recognisable human format.

  • self (SelfType)

Returns:

self (chainable)

Raises:

EcoPlotsError – If the date string cannot be parsed.

Return type:

SelfType

Examples

ec.select(site_id="ABC").from_date("01/01/2020").to_date("31/12/2022")

Magic Methods

The EcoPlots class supports several magic methods inherited from EcoPlotsBase for intuitive interactions:

Display & Representation:
  • __str__() - Pretty-printed box format showing filters and version

  • __repr__() - Evaluable string representation for debugging

Comparison:
  • __eq__(other) - Compare two instances for structural equality

  • __bool__() - Check if any filters are applied (if ecoplots:)

Container Operations:
  • __len__() - Count active filters (len(ecoplots))

  • __contains__(key) - Check if filter exists ("site_id" in ecoplots)

  • __getitem__(key) - Get filter values (ecoplots["site_id"])

  • __setitem__(key, value) - Set filter (ecoplots["dataset"] = "TERN")

  • __delitem__(key) - Remove filter (del ecoplots["site_id"])

Copying:
  • __copy__() - Shallow copy support (copy.copy(ecoplots))

  • __deepcopy__(memo) - Deep copy support (copy.deepcopy(ecoplots))