nomenclature
nomenclature
IAU-approved surface feature names, as a plottable layer.
The matplotlib basemap/cartopy habit of dropping coastlines() onto a plot to make it legible has no planetary equivalent — there are no coastlines on Mars. What there is: the USGS Gazetteer of Planetary Nomenclature, the authority for IAU-adopted feature names on 47 bodies. This module fetches it, caches it, and puts it on your axes.
>>> from planetarypy import nomenclature
>>> nomenclature.features("mars", type="Crater", min_diameter=100)
>>> nomenclature.add_features(ax, "mars") # onto axes you already have
Data comes from the Gazetteer’s per-body GIS downloads. There is no JSON API — the search pages are HTML only — so the shapefile zips are the machine-readable path. Everything shipped is approval == "Adopted by IAU".
A note on coordinate systems, because it matters here: the gazetteer ships ESRI authority codes (Mars is ESRI:104905, an ellipsoid), while planetarypy standardises on IAU_2015. Results are therefore reprojected by default, and :func:features says so through :class:~planetarypy.crs.CRSConversionWarning unless you named a CRS yourself. Set :func:~planetarypy.crs.set_target_crs to put nomenclature, footprints and rasters in one frame for a whole session.
Requires geopandas: pip install "planetarypy[geo]".
Functions
| Name | Description |
|---|---|
| add_features | Overlay named features onto existing axes — the coastlines() move. |
| bodies | Bodies with published nomenclature, lowercase. |
| download | Fetch and unpack one body’s nomenclature shapefile; return the .shp. |
| features | IAU-adopted named features for body, as a GeoDataFrame. |
| find | One named feature, so coordinates come from the IAU rather than memory. |
add_features
nomenclature.add_features(
ax,
body,
*,
type=None,
min_diameter=None,
bbox='auto',
extent=True,
label=True,
max_labels=25,
declutter=True,
to_crs=None,
marker_kw=None,
extent_kw=None,
text_kw=None,
)Overlay named features onto existing axes — the coastlines() move.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| ax | matplotlib.axes.Axes | Axes to draw on. Whatever is already plotted stays. | required |
| bbox | 'auto' or tuple | "auto" (default) reads the axes’ current limits, so this composes with a plot you already made without restating the area. |
'auto' |
| extent | bool | Draw each feature’s lat/lon box from the gazetteer’s min/max columns. On by default: a centre point says a name is near here, the box says whether your footprint actually overlaps the feature. Set False for centre points only. |
True |
| label | bool | Draw feature names. | True |
| max_labels | int | Cap on labels drawn, largest features first. | 25 |
| declutter | bool | Skip labels that would overlap one already placed. | True |
| to_crs | optional | Passed to :func:features; overrides the session target CRS. |
None |
Returns
| Name | Type | Description |
|---|---|---|
| geopandas.GeoDataFrame | The features drawn, so you can inspect or annotate further. |
bodies
nomenclature.bodies()Bodies with published nomenclature, lowercase.
download
nomenclature.download(body, *, refresh=False)Fetch and unpack one body’s nomenclature shapefile; return the .shp.
Cached under storage_root/nomenclature/<BODY>/. The gazetteer grows as the IAU adopts names, so refresh=True re-fetches.
features
nomenclature.features(
body,
*,
name=None,
type=None,
min_diameter=None,
bbox=None,
to_crs=None,
refresh=False,
)IAU-adopted named features for body, as a GeoDataFrame.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| body | str | Body name, e.g. "mars". See :func:bodies. |
required |
| name | str | Exact feature name, case-insensitive. Exact rather than substring so "Jezero" does not also return "Jezero Mons". |
None |
| type | str | Feature class, matched against the leading singular of the gazetteer’s type column — pass "Crater", not "Crater, craters". |
None |
| min_diameter | float | Keep features at least this many km across. The gazetteer will happily return 1237 Mars craters; diameter is the usual way to mean “the ones worth naming on this plot”. | None |
| bbox | tuple | (west, south, east, north) in degrees east / planetocentric north, the same convention as :func:planetarypy.search.bbox_from_point. |
None |
| to_crs | optional | Reproject to this CRS. Overrides the session target CRS. | None |
| refresh | bool | Re-download rather than using the cache. | False |
Returns
| Name | Type | Description |
|---|---|---|
| geopandas.GeoDataFrame | Columns include name, type, diameter (km), center_lon/center_lat and the feature’s bounding box as min_lon/max_lon/min_lat/max_lat. |
Notes
CRS precedence is to_crs > session target > the body’s own IAU CRS. Reprojection you did not explicitly request warns via :class:~planetarypy.crs.CRSConversionWarning — the gazetteer’s ESRI codes and planetarypy’s IAU codes differ in more than their label, so the conversion is worth knowing about.
find
nomenclature.find(body, name, **kwargs)One named feature, so coordinates come from the IAU rather than memory.
jezero = find(“mars”, “Jezero”) jezero.center_lon, jezero.center_lat (77.6873, 18.4082)
Hardcoding a feature’s coordinates is easy and quietly wrong: the value most people carry around for Jezero is about 17 km off the IAU one. This looks it up instead.
Raises
| Name | Type | Description |
|---|---|---|
| LookupError | If no feature on body has that exact name. |
|
| ValueError | If the name is ambiguous — the gazetteer does reuse names across feature classes on some bodies. |
Returns
| Name | Type | Description |
|---|---|---|
| pandas.Series | The single matching row, with center_lon/center_lat, diameter, the bounding box and the rest of the schema. |