AsyncEcoPlots

Overview

AsyncEcoPlots is the asynchronous client. It is useful when you already run async code (for example in services/apps) and want non-blocking data download.

In practice, most methods are used the same way as the synchronous client. The key difference is that you use await for get_data().

Constructor Parameters

Signature:

AsyncEcoPlots(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()).

Async Usage Note

  • EcoPlots: df = ec.get_data()

  • AsyncEcoPlots: df = await ec.get_data()

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

Bases: EcoPlots

High-level async client for the EcoPlots REST API.

Provides an awaitable get_data() for large/long-running fetches while reusing the synchronous ergonomics elsewhere. Ideal for web backends (ASGI) or notebooks wanting to parallelise I/O heavy pulls.

Examples

Basic async usage:

from terndata.ecoplots import AsyncEcoPlots

ec = AsyncEcoPlots()
ec.select(site_id="TCFTNS0002")    # selection etc. is sync but cheap
gdf = await ec.get_data()          # await the heavy network call

Notes

  • Only get_data() is async here. Other methods inherited from EcoPlots are synchronous and will block.

  • Safety guard: get_data() raises RuntimeError when no filters are set unless allow_full_download=True.

Parameters:
  • filterset (dict | None)

  • query_filters (dict | None)

  • mode (str | None)

async get_data(allow_full_download=False, dformat='gpd')[source]

Retrieve EcoPlots data asynchronously 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.

  • BaseException – Propagated from underlying fetch tasks when data retrieval fails. #noqa: DAR402

Returns:

Data in the requested format.

Return type:

geopandas.GeoDataFrame

__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_datasources()

Get the data sources available for applied filters.

Returns:

A DataFrame containing the data sources.

Return type:

DataFrame

get_datasources_attributes()

Get the attributes of data sources from the applied filters.

Returns:

A DataFrame containing the attributes of the data sources.

Return type:

DataFrame

get_feature_types()

Get the feature types from the applied filters.

Returns:

A DataFrame containing the feature types.

Return type:

DataFrame

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

get_material_sample_types()

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_observation_attributes()

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_observed_properties()

Get the observed properties from the applied filters.

Returns:

A DataFrame containing the observed properties.

Return type:

DataFrame

get_region_types()

Get the available region types from the applied filters.

Returns:

A DataFrame containing the region types.

Return type:

DataFrame

get_regions(region_type)

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_sample_igsn()

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

get_site_visit_attributes()

Get the attributes of site visits from the applied filters.

Returns:

A DataFrame containing the attributes of the site visits.

Return type:

DataFrame

get_sites()

Get the sites from the applied filters.

Returns:

A DataFrame containing the sites.

Return type:

DataFrame

get_sites_attributes()

Get the attributes of sites from the applied filters.

Returns:

A DataFrame containing the attributes of the sites.

Return type:

DataFrame

get_soil_depth_range()

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()

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()

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_used_procedures()

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

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

preview(dformat=None)

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

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

select_spatial(**kwargs)

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.

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.

summary(dformat=None)

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

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")
view_sample_igsn(igsn=None)

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:
view_sample_images(data=None, image_column='sample_images', sample_id_column='sample_id', sample_name_column='sample_name', scientific_name_column='scientific_name')

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.

Magic Methods

The AsyncEcoPlots class inherits all magic methods 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))