From 43669668b236a32a3a3838c49f760066677a3c4d Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Thu, 23 Oct 2025 16:48:32 +0800 Subject: [PATCH 1/4] project: Migrate the 'center'/'endpoint'/'pole'/'width' parameters to the new alias system --- pygmt/src/project.py | 63 +++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/pygmt/src/project.py b/pygmt/src/project.py index 8fc5018313c..724709e2178 100644 --- a/pygmt/src/project.py +++ b/pygmt/src/project.py @@ -2,12 +2,13 @@ project - Project data onto lines or great circles, or generate tracks. """ +from collections.abc import Sequence from typing import Literal import numpy as np import pandas as pd from pygmt._typing import PathLike, TableLike -from pygmt.alias import AliasSystem +from pygmt.alias import Alias, AliasSystem from pygmt.clib import Session from pygmt.exceptions import GMTInvalidInput from pygmt.helpers import ( @@ -22,20 +23,16 @@ @fmt_docstring @use_alias( A="azimuth", - C="center", - E="endpoint", F="convention", G="generate", L="length", N="flat_earth", Q="unit", S="sort", - T="pole", - W="width", Z="ellipse", f="coltypes", ) -@kwargs_to_strings(E="sequence", L="sequence", T="sequence", W="sequence", C="sequence") +@kwargs_to_strings(L="sequence") def project( data: PathLike | TableLike | None = None, x=None, @@ -43,6 +40,10 @@ def project( z=None, output_type: Literal["pandas", "numpy", "file"] = "pandas", outfile: PathLike | None = None, + center: Sequence | None = None, + endpoint: Sequence | None = None, + width: Sequence | None = None, + pole: Sequence | None = None, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, **kwargs, @@ -112,6 +113,10 @@ def project( Full GMT docs at :gmt-docs:`project.html`. {aliases} + - C = center + - E = endpoint + - T = pole + - W = width - V = verbose Parameters @@ -123,19 +128,17 @@ def project( {output_type} {outfile} - center : str or list - *cx*/*cy*. - Set the origin of the projection, in Definition 1 or 2. If - Definition 3 is used, then *cx/cy* are the coordinates of a - point through which the oblique zero meridian (:math:`p = 0`) should - pass. The *cx/cy* is not required to be 90 degrees from the pole. - + center + Set the origin of the projection, in the form of (*cx*, *cy*), in Definitions 1 + or 2. If Definition 3 is used, then (*cx*, *cy*) are the coordinates of a point + through which the oblique zero meridian (:math:`p = 0`) should pass. + (*cx*, *cy*) is not required to be 90 degrees from the pole set by ``pole``. azimuth : float or str Define the azimuth of the projection (Definition 1). - endpoint : str or list - *bx*/*by*. - Define the end point of the projection path (Definition 2). + endpoint + (*bx*, *by*). + Set the end point of the projection path (Definition 2). convention : str Specify the desired output using any combination of **xyzpqrs**, in @@ -182,18 +185,13 @@ def project( sort : bool Sort the output into increasing :math:`p` order. Useful when projecting random data into a sequential profile. - - pole : str or list - *px*/*py*. - Set the position of the rotation pole of the projection. - (Definition 3). - - {verbose} - - width : str or list - *w_min*/*w_max*. - Project only those data whose :math:`q` coordinate is - within :math:`w_{{min}} < q < w_{{max}}`. + pole + (*px*, *py*). + Set the position of the rotation pole of the projection. (Definition 3). + width + (*w_min*, *w_max*). + Specify width controls for the projected points. Project only those points whose + q coordinate is within :math:`w_{{min}} < q < w_{{max}}`. ellipse : str *major*/*minor*/*azimuth* [**+e**\|\ **n**]. @@ -212,7 +210,7 @@ def project( For the Cartesian ellipse (which requires ``flat_earth``), the *direction* is counter-clockwise from the horizontal instead of an *azimuth*. - + {verbose} {coltypes} Returns @@ -241,7 +239,12 @@ def project( if output_type == "pandas" and kwargs.get("G") is not None: column_names = list("rsp") - aliasdict = AliasSystem().add_common( + aliasdict = AliasSystem( + C=Alias(center, name="center", sep="/", size=2), + E=Alias(endpoint, name="endpoint", sep="/", size=2), + T=Alias(pole, name="pole", sep="/", size=2), + W=Alias(width, name="width", sep="/", size=2), + ).add_common( V=verbose, ) aliasdict.merge(kwargs) From 9ff49d0f53ad768835b06fb483d719918849c583 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Thu, 23 Oct 2025 16:58:04 +0800 Subject: [PATCH 2/4] Also migrate the length parameter --- pygmt/src/project.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/pygmt/src/project.py b/pygmt/src/project.py index 724709e2178..234fb7c87e9 100644 --- a/pygmt/src/project.py +++ b/pygmt/src/project.py @@ -14,7 +14,6 @@ from pygmt.helpers import ( build_arg_list, fmt_docstring, - kwargs_to_strings, use_alias, validate_output_table_type, ) @@ -25,15 +24,13 @@ A="azimuth", F="convention", G="generate", - L="length", N="flat_earth", Q="unit", S="sort", Z="ellipse", f="coltypes", ) -@kwargs_to_strings(L="sequence") -def project( +def project( # noqa: PLR0913 data: PathLike | TableLike | None = None, x=None, y=None, @@ -43,6 +40,7 @@ def project( center: Sequence | None = None, endpoint: Sequence | None = None, width: Sequence | None = None, + length: Sequence | Literal["limit"] | None = None, pole: Sequence | None = None, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, @@ -115,6 +113,7 @@ def project( {aliases} - C = center - E = endpoint + - L = length - T = pole - W = width - V = verbose @@ -165,14 +164,12 @@ def project( the pole as part of the segment header [Default is no header]. **Note**: No input is read and the value of ``data``, ``x``, ``y``, and ``z`` is ignored if ``generate`` is used. - - length : str or list - [**w**\|\ *l_min*/*l_max*]. - Project only those data whose *p* coordinate is - within :math:`l_{{min}} < p < l_{{max}}`. If ``endpoint`` has been set, - then you may alternatively use **w** to stay within the distance from - ``center`` to ``endpoint``. - + length + (*lmin*, *lmax*) or ``"limit"``. + Project only those data whose *p* coordinate is within + :math:`l_{{min}} < p < l_{{max}}`. If ``endpoint`` has been set, then you may + alternatively set it to ``"limit"`` to stay within the distance from ``center`` + to ``endpoint``. flat_earth : bool Make a Cartesian coordinate transformation in the plane. [Default is ``False``; plane created with spherical trigonometry.] @@ -242,6 +239,7 @@ def project( aliasdict = AliasSystem( C=Alias(center, name="center", sep="/", size=2), E=Alias(endpoint, name="endpoint", sep="/", size=2), + L=Alias(length, name="length", sep="/", size=2, mapping={"limit": "w"}), T=Alias(pole, name="pole", sep="/", size=2), W=Alias(width, name="width", sep="/", size=2), ).add_common( From 1a6f9b83aeb7f7a65575f5ed5df7f4f2c1f1d9ea Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Thu, 23 Oct 2025 17:01:49 +0800 Subject: [PATCH 3/4] Fix styling issue --- pygmt/src/project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/src/project.py b/pygmt/src/project.py index 234fb7c87e9..4a18f682d42 100644 --- a/pygmt/src/project.py +++ b/pygmt/src/project.py @@ -30,7 +30,7 @@ Z="ellipse", f="coltypes", ) -def project( # noqa: PLR0913 +def project( # noqa: PLR0913 data: PathLike | TableLike | None = None, x=None, y=None, From d4c1a831fe9c6fb444a5eb9407c82fae3d89df7d Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Thu, 23 Oct 2025 17:17:09 +0800 Subject: [PATCH 4/4] Improve type hints --- pygmt/src/project.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pygmt/src/project.py b/pygmt/src/project.py index 4a18f682d42..55698b47d62 100644 --- a/pygmt/src/project.py +++ b/pygmt/src/project.py @@ -37,11 +37,11 @@ def project( # noqa: PLR0913 z=None, output_type: Literal["pandas", "numpy", "file"] = "pandas", outfile: PathLike | None = None, - center: Sequence | None = None, - endpoint: Sequence | None = None, - width: Sequence | None = None, - length: Sequence | Literal["limit"] | None = None, - pole: Sequence | None = None, + center: Sequence[float | str] | None = None, + endpoint: Sequence[float | str] | None = None, + width: Sequence[float | str] | None = None, + length: Sequence[float | str] | Literal["limit"] | None = None, + pole: Sequence[float | str] | None = None, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, **kwargs,