Skip to content

Commit 757da24

Browse files
committed
Merge branch 'main' into pyarrow/string
2 parents f59f93c + 90c1262 commit 757da24

File tree

6 files changed

+65
-41
lines changed

6 files changed

+65
-41
lines changed

pygmt/_typing.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"""
2+
Type aliases for type hints.
3+
"""
4+
5+
from typing import Literal
6+
7+
# Anchor codes
8+
AnchorCode = Literal["TL", "TC", "TR", "ML", "MC", "MR", "BL", "BC", "BR"]

pygmt/clib/conversion.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from collections.abc import Sequence
88

99
import numpy as np
10+
import pandas as pd
11+
from packaging.version import Version
1012
from pygmt.exceptions import GMTInvalidInput
1113

1214
StringArrayTypes = Sequence[str] | np.ndarray
@@ -187,6 +189,10 @@ def vectors_to_arrays(vectors):
187189
>>> [i.ndim for i in data] # Check that they are 1-D arrays
188190
[1, 1, 1]
189191
192+
>>> series = pd.Series(data=[0, 4, pd.NA, 8, 6], dtype=pd.Int32Dtype())
193+
>>> vectors_to_arrays([series])
194+
[array([ 0., 4., nan, 8., 6.])]
195+
190196
>>> import datetime
191197
>>> import pytest
192198
>>> pa = pytest.importorskip("pyarrow")
@@ -214,8 +220,20 @@ def vectors_to_arrays(vectors):
214220
}
215221
arrays = []
216222
for vector in vectors:
217-
vec_dtype = str(getattr(vector, "dtype", ""))
218-
arrays.append(np.ascontiguousarray(vector, dtype=dtypes.get(vec_dtype)))
223+
if (
224+
hasattr(vector, "isna")
225+
and vector.isna().any()
226+
and Version(pd.__version__) < Version("2.2")
227+
):
228+
# Workaround for dealing with pd.NA with pandas < 2.2.
229+
# Bug report at: https://github.com/GenericMappingTools/pygmt/issues/2844
230+
# Following SPEC0, pandas 2.1 will be dropped in 2025 Q3, so it's likely
231+
# we can remove the workaround in PyGMT v0.17.0.
232+
array = np.ascontiguousarray(vector.astype(float))
233+
else:
234+
vec_dtype = str(getattr(vector, "dtype", ""))
235+
array = np.ascontiguousarray(vector, dtype=dtypes.get(vec_dtype))
236+
arrays.append(array)
219237
return arrays
220238

221239

pygmt/clib/session.py

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -115,33 +115,28 @@ class Session:
115115
"""
116116
A GMT API session where most operations involving the C API happen.
117117
118-
Works as a context manager (for use in a ``with`` block) to create a GMT C
119-
API session and destroy it in the end to clean up memory.
118+
Works as a context manager (for use in a ``with`` block) to create a GMT C API
119+
session and destroy it in the end to clean up memory.
120120
121-
Functions of the shared library are exposed as methods of this class. Most
122-
methods MUST be used with an open session (inside a ``with`` block). If
123-
creating GMT data structures to communicate data, put that code inside the
124-
same ``with`` block as the API calls that will use the data.
121+
Functions of the shared library are exposed as methods of this class. Most methods
122+
MUST be used with an open session (inside a ``with`` block). If creating GMT data
123+
structures to communicate data, put that code inside the same ``with`` block as the
124+
API calls that will use the data.
125125
126-
By default, will let :mod:`ctypes` try to find the GMT shared library
127-
(``libgmt``). If the environment variable :term:`GMT_LIBRARY_PATH` is set, will
128-
look for the shared library in the directory specified by it.
126+
By default, will let :mod:`ctypes` try to find the GMT shared library (``libgmt``).
127+
If the environment variable :term:`GMT_LIBRARY_PATH` is set, will look for the
128+
shared library in the directory specified by it.
129129
130-
A ``GMTVersionError`` exception will be raised if the GMT shared library
131-
reports a version older than the required minimum GMT version.
132-
133-
The ``session_pointer`` attribute holds a ctypes pointer to the currently
134-
open session.
130+
The ``session_pointer`` attribute holds a ctypes pointer to the currently open
131+
session.
135132
136133
Raises
137134
------
138135
GMTCLibNotFoundError
139-
If there was any problem loading the library (couldn't find it or
140-
couldn't access the functions).
136+
If there was any problem loading the library (couldn't find it or couldn't
137+
access the functions).
141138
GMTCLibNoSessionError
142-
If you try to call a method outside of a 'with' block.
143-
GMTVersionError
144-
If the minimum required version of GMT is not found.
139+
If you try to call a method outside of a ``with`` block.
145140
146141
Examples
147142
--------
@@ -151,45 +146,44 @@ class Session:
151146
>>> grid = load_static_earth_relief()
152147
>>> type(grid)
153148
<class 'xarray.core.dataarray.DataArray'>
154-
>>> # Create a session and destroy it automatically when exiting the "with"
155-
>>> # block.
156-
>>> with Session() as ses:
149+
>>> # Create a session and destroy it automatically when exiting the "with" block.
150+
>>> with Session() as lib:
157151
... # Create a virtual file and link to the memory block of the grid.
158-
... with ses.virtualfile_from_grid(grid) as fin:
152+
... with lib.virtualfile_from_grid(grid) as fin:
159153
... # Create a temp file to use as output.
160154
... with GMTTempFile() as fout:
161-
... # Call the grdinfo module with the virtual file as input
162-
... # and the temp file as output.
163-
... ses.call_module("grdinfo", [fin, "-C", f"->{fout.name}"])
155+
... # Call the grdinfo module with the virtual file as input and the
156+
... # temp file as output.
157+
... lib.call_module("grdinfo", [fin, "-C", f"->{fout.name}"])
164158
... # Read the contents of the temp file before it's deleted.
165159
... print(fout.read().strip())
166160
-55 -47 -24 -10 190 981 1 1 8 14 1 1
167161
"""
168162

169163
@property
170-
def session_pointer(self):
164+
def session_pointer(self) -> ctp.c_void_p:
171165
"""
172166
The :class:`ctypes.c_void_p` pointer to the current open GMT session.
173167
174168
Raises
175169
------
176170
GMTCLibNoSessionError
177-
If trying to access without a currently open GMT session (i.e.,
178-
outside of the context manager).
171+
If trying to access without a currently open GMT session (i.e., outside of
172+
the context manager).
179173
"""
180174
if not hasattr(self, "_session_pointer") or self._session_pointer is None:
181175
raise GMTCLibNoSessionError("No currently open GMT API session.")
182176
return self._session_pointer
183177

184178
@session_pointer.setter
185-
def session_pointer(self, session):
179+
def session_pointer(self, session: ctp.c_void_p):
186180
"""
187181
Set the session void pointer.
188182
"""
189183
self._session_pointer = session
190184

191185
@property
192-
def info(self):
186+
def info(self) -> dict[str, str]:
193187
"""
194188
Dictionary with the GMT version and default paths and parameters.
195189
"""

pygmt/helpers/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import sys
1212
import time
1313
import webbrowser
14-
from collections.abc import Iterable, Sequence
14+
from collections.abc import Iterable, Mapping, Sequence
1515
from typing import Any, Literal
1616

1717
import xarray as xr
@@ -395,7 +395,7 @@ def non_ascii_to_octal(
395395

396396
def build_arg_list( # noqa: PLR0912
397397
kwdict: dict[str, Any],
398-
confdict: dict[str, str] | None = None,
398+
confdict: Mapping[str, Any] | None = None,
399399
infile: str | pathlib.PurePath | Sequence[str | pathlib.PurePath] | None = None,
400400
outfile: str | pathlib.PurePath | None = None,
401401
) -> list[str]:

pygmt/src/text.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
text - Plot text on a figure.
33
"""
44

5+
from collections.abc import Sequence
6+
57
import numpy as np
8+
from pygmt._typing import AnchorCode
69
from pygmt.clib import Session
710
from pygmt.exceptions import GMTInvalidInput
811
from pygmt.helpers import (
@@ -44,11 +47,11 @@ def text_( # noqa: PLR0912
4447
textfiles=None,
4548
x=None,
4649
y=None,
47-
position=None,
50+
position: AnchorCode | None = None,
4851
text=None,
4952
angle=None,
5053
font=None,
51-
justify=None,
54+
justify: bool | None | AnchorCode | Sequence[AnchorCode] = None,
5255
**kwargs,
5356
):
5457
r"""
@@ -90,14 +93,14 @@ def text_( # noqa: PLR0912
9093
x/y : float or 1-D arrays
9194
The x and y coordinates, or an array of x and y coordinates to plot
9295
the text.
93-
position : str
96+
position
9497
Set reference point on the map for the text by using x, y
9598
coordinates extracted from ``region`` instead of providing them
9699
through ``x``/``y``. Specify with a two-letter (order independent)
97100
code, chosen from:
98101
99-
* Horizontal: **L**\ (eft), **C**\ (entre), **R**\ (ight)
100102
* Vertical: **T**\ (op), **M**\ (iddle), **B**\ (ottom)
103+
* Horizontal: **L**\ (eft), **C**\ (entre), **R**\ (ight)
101104
102105
For example, ``position="TL"`` plots the text at the Top Left corner
103106
of the map.
@@ -116,7 +119,7 @@ def text_( # noqa: PLR0912
116119
font. If no font info is explicitly given (i.e. ``font=True``), then
117120
the input to ``textfiles`` must have this information in one of its
118121
columns.
119-
justify : str, bool or list of str
122+
justify
120123
Set the alignment which refers to the part of the text string that
121124
will be mapped onto the (x, y) point. Choose a two-letter
122125
combination of **L**, **C**, **R** (for left, center, or right) and

pygmt/src/timestamp.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from collections.abc import Sequence
77

88
from packaging.version import Version
9+
from pygmt._typing import AnchorCode
910
from pygmt.clib import Session, __gmt_version__
1011
from pygmt.helpers import build_arg_list, kwargs_to_strings
1112

@@ -17,7 +18,7 @@ def timestamp(
1718
self,
1819
text: str | None = None,
1920
label: str | None = None,
20-
justify: str = "BL",
21+
justify: AnchorCode = "BL",
2122
offset: float | str | Sequence[float | str] = ("-54p", "-54p"),
2223
font: str = "Helvetica,black",
2324
timefmt: str = "%Y %b %d %H:%M:%S",

0 commit comments

Comments
 (0)