Skip to content

Commit ccf4eff

Browse files
committed
Merge branch 'main' into pyarrow/string
2 parents 9fd77dc + c50c1ec commit ccf4eff

File tree

7 files changed

+96
-113
lines changed

7 files changed

+96
-113
lines changed

.github/workflows/type_checks.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ jobs:
5050
# 4. other packages that are used somewhere in PyGMT
5151
python -m pip install \
5252
numpy pandas xarray netcdf4 packaging \
53-
contextily geopandas ipython rioxarray \
54-
mypy pandas-stubs \
53+
contextily geopandas ipython pyarrow rioxarray \
54+
mypy pandas-stubs pyarrow-stubs \
5555
matplotlib pytest
5656
python -m pip list
5757

environment.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ dependencies:
1616
- contextily
1717
- geopandas
1818
- ipython
19+
- pyarrow
1920
- rioxarray
2021
# Development dependencies (general)
2122
- dvc

examples/tutorials/basics/lines.py

Lines changed: 50 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Plotting lines
33
==============
44
5-
Plotting lines is handled by :meth:`pygmt.Figure.plot`.
5+
Plotting lines is handled by the :meth:`pygmt.Figure.plot` method.
66
"""
77

88
# %%
@@ -12,123 +12,93 @@
1212
# Plot lines
1313
# ----------
1414
#
15-
# Create a Cartesian figure using ``projection`` parameter and set the axis
16-
# scales using ``region`` (in this case, each axis is 0-10). Pass a list of
17-
# ``x`` and ``y`` values to be plotted as a line.
15+
# Create a Cartesian figure using the :meth:`pygmt.Figure.basemap` method. Pass lists
16+
# containing two values to the ``x`` and ``y`` parameters of the
17+
# :meth:`pygmt.Figure.plot` method. By default, a 0.25-points thick, black, solid
18+
# line is drawn between these two data points.
1819

1920
fig = pygmt.Figure()
20-
fig.plot(
21-
region=[0, 10, 0, 10],
22-
projection="X15c/10c",
23-
frame="a",
24-
x=[1, 8],
25-
y=[5, 9],
26-
pen="1p,black",
27-
)
21+
fig.basemap(region=[0, 10, 0, 10], projection="X15c/10c", frame=True)
22+
23+
fig.plot(x=[1, 5], y=[5, 9])
24+
2825
fig.show()
2926

3027
# %%
31-
# Additional line segments can be added by including additional values for
32-
# ``x`` and ``y``.
28+
# Additional line segments can be added by including more data points in the lists
29+
# passed to ``x`` and ``y``.
3330

3431
fig = pygmt.Figure()
35-
fig.plot(
36-
region=[0, 10, 0, 10],
37-
projection="X15c/10c",
38-
frame="a",
39-
x=[1, 6, 9],
40-
y=[5, 7, 4],
41-
pen="1p,black",
42-
)
32+
fig.basemap(region=[0, 10, 0, 10], projection="X15c/10c", frame=True)
33+
34+
fig.plot(x=[1, 5, 8], y=[5, 9, 4])
35+
4336
fig.show()
4437

4538
# %%
46-
# To plot multiple lines, :meth:`pygmt.Figure.plot` needs to be used for each
47-
# additional line. Parameters such as ``region``, ``projection``, and ``frame``
48-
# do not need to be repeated in subsequent uses.
39+
# To plot multiple lines, :meth:`pygmt.Figure.plot` needs to be used for each line
40+
# separately.
4941

5042
fig = pygmt.Figure()
51-
fig.plot(
52-
region=[0, 10, 0, 10],
53-
projection="X15c/10c",
54-
frame="a",
55-
x=[1, 6, 9],
56-
y=[5, 7, 4],
57-
pen="2p,blue",
58-
)
59-
fig.plot(x=[2, 4, 10], y=[3, 8, 9], pen="2p,red")
43+
fig.basemap(region=[0, 10, 0, 10], projection="X15c/10c", frame=True)
44+
45+
fig.plot(x=[1, 5, 8], y=[5, 9, 4])
46+
fig.plot(x=[2, 4, 9], y=[3, 7, 5])
47+
6048
fig.show()
6149

6250

6351
# %%
6452
# Change line attributes
6553
# ----------------------
6654
#
67-
# The line attributes can be set by the ``pen`` parameter. ``pen`` takes a
68-
# string argument with the optional values *width*,\ *color*,\ *style*.
69-
#
70-
# In the example below, the pen width is set to ``5p``, and with ``black`` as
71-
# the default color and ``solid`` as the default style.
55+
# The line attributes can be set by the ``pen`` parameter which takes a string
56+
# argument with the optional values *width*,\ *color*,\ *style*.
7257

7358
fig = pygmt.Figure()
74-
fig.plot(
75-
region=[0, 10, 0, 10],
76-
projection="X15c/10c",
77-
frame="a",
78-
x=[1, 8],
79-
y=[3, 9],
80-
pen="5p",
81-
)
59+
fig.basemap(region=[0, 10, 0, 10], projection="X15c/10c", frame=True)
60+
61+
# Set the pen width to "5p" (5 points), and use the default color "black" and the
62+
# default style "solid"
63+
fig.plot(x=[1, 8], y=[3, 9], pen="5p")
64+
8265
fig.show()
8366

8467
# %%
8568
# The line color can be set and is added after the line width to the ``pen``
86-
# parameter. In the example below, the line color is set to ``red``.
69+
# parameter.
8770

8871
fig = pygmt.Figure()
89-
fig.plot(
90-
region=[0, 10, 0, 10],
91-
projection="X15c/10c",
92-
frame="a",
93-
x=[1, 8],
94-
y=[3, 9],
95-
pen="5p,red",
96-
)
72+
fig.basemap(region=[0, 10, 0, 10], projection="X15c/10c", frame=True)
73+
74+
# Set the line color to "red", use the default style "solid"
75+
fig.plot(x=[1, 8], y=[3, 9], pen="5p,red")
76+
9777
fig.show()
9878

9979
# %%
10080
# The line style can be set and is added after the line width or color to the
101-
# ``pen`` parameter. In the example below, the line style is set to
102-
# ``..-`` (*dot dot dash*), and the default color ``black`` is used.
81+
# ``pen`` parameter.
10382

10483
fig = pygmt.Figure()
105-
fig.plot(
106-
region=[0, 10, 0, 10],
107-
projection="X15c/10c",
108-
frame="a",
109-
x=[1, 8],
110-
y=[3, 9],
111-
pen="5p,..-",
112-
)
84+
fig.basemap(region=[0, 10, 0, 10], projection="X15c/10c", frame=True)
85+
86+
# Set the line style to "..-" (dot dot dash), use the default color "black"
87+
fig.plot(x=[1, 8], y=[3, 9], pen="5p,..-")
88+
11389
fig.show()
11490

11591
# %%
116-
# The line width, color, and style can all be set in the same ``pen``
117-
# parameter. In the example below, the line width is set to ``7p``, the color
118-
# is set to ``green``, and the line style is ``-.-`` (*dash dot dash*).
119-
#
120-
# For a gallery showing other ``pen`` settings, see
92+
# The line width, color, and style can all be set in the same ``pen`` parameter.
93+
# For a gallery example showing other ``pen`` settings, see
12194
# :doc:`/gallery/lines/linestyles`.
12295

12396
fig = pygmt.Figure()
124-
fig.plot(
125-
region=[0, 10, 0, 10],
126-
projection="X15c/10c",
127-
frame="a",
128-
x=[1, 8],
129-
y=[3, 9],
130-
pen="7p,green,-.-",
131-
)
97+
fig.basemap(region=[0, 10, 0, 10], projection="X15c/10c", frame=True)
98+
99+
# Draw a 7-points thick, green line with style "-.-" (dash dot dash)
100+
fig.plot(x=[1, 8], y=[3, 9], pen="7p,green,-.-")
101+
132102
fig.show()
133103

134-
# sphinx_gallery_thumbnail_number = 3
104+
# sphinx_gallery_thumbnail_number = 6

pygmt/figure.py

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
import numpy as np
1919
from pygmt.clib import Session
20-
from pygmt.exceptions import GMTError, GMTInvalidInput
20+
from pygmt.exceptions import GMTInvalidInput
2121
from pygmt.helpers import launch_external_viewer, unique_name
2222

2323

@@ -135,7 +135,7 @@ def region(self) -> np.ndarray:
135135
wesn = lib.extract_region()
136136
return wesn
137137

138-
def savefig( # noqa: PLR0912
138+
def savefig(
139139
self,
140140
fname: str | PurePath,
141141
transparent: bool = False,
@@ -177,7 +177,8 @@ def savefig( # noqa: PLR0912
177177
The desired figure file name, including the extension. See the list of
178178
supported formats and their extensions above.
179179
transparent
180-
Use a transparent background for the figure. Only valid for PNG format.
180+
Use a transparent background for the figure. Only valid for PNG format and
181+
the PNG file asscoiated with KML format.
181182
crop
182183
Crop the figure canvas (page) to the plot area.
183184
anti_alias
@@ -203,9 +204,9 @@ def savefig( # noqa: PLR0912
203204
"bmp": "b",
204205
"eps": "e",
205206
"jpg": "j",
206-
"kml": "g",
207+
"kml": "G" if transparent is True else "g",
207208
"pdf": "f",
208-
"png": "g",
209+
"png": "G" if transparent is True else "g",
209210
"ppm": "m",
210211
"tif": "t",
211212
"tiff": None, # GeoTIFF doesn't need the -T option
@@ -226,14 +227,12 @@ def savefig( # noqa: PLR0912
226227
msg = "Extension '.ps' is not supported. Use '.eps' or '.pdf' instead."
227228
raise GMTInvalidInput(msg)
228229
case ext if ext not in fmts:
229-
raise GMTInvalidInput(f"Unknown extension '.{ext}'.")
230-
231-
fmt = fmts[ext]
232-
if transparent:
233-
if fmt != "g":
234-
msg = f"Transparency unavailable for '{ext}', only for png."
230+
msg = f"Unknown extension '.{ext}'."
235231
raise GMTInvalidInput(msg)
236-
fmt = fmt.upper()
232+
233+
if transparent and ext not in {"kml", "png"}:
234+
msg = f"Transparency unavailable for '{ext}', only for png and kml."
235+
raise GMTInvalidInput(msg)
237236
if anti_alias:
238237
kwargs["Qt"] = 2
239238
kwargs["Qg"] = 2
@@ -244,18 +243,17 @@ def savefig( # noqa: PLR0912
244243
raise GMTInvalidInput(msg)
245244
kwargs["W"] = True
246245

247-
# pytest-mpl v0.17.0 added the "metadata" parameter to Figure.savefig, which
248-
# is not recognized. So remove it before calling Figure.psconvert.
246+
# pytest-mpl v0.17.0 added the "metadata" parameter to Figure.savefig, which is
247+
# not recognized. So remove it before calling Figure.psconvert.
249248
kwargs.pop("metadata", None)
250-
self.psconvert(prefix=prefix, fmt=fmt, crop=crop, **kwargs)
249+
self.psconvert(prefix=prefix, fmt=fmts[ext], crop=crop, **kwargs)
251250

252-
# Remove the .pgw world file if exists.
253-
# Not necessary after GMT 6.5.0.
251+
# Remove the .pgw world file if exists. Not necessary after GMT 6.5.0.
254252
# See upstream fix https://github.com/GenericMappingTools/gmt/pull/7865
255253
if ext == "tiff":
256254
fname.with_suffix(".pgw").unlink(missing_ok=True)
257255

258-
# Rename if file extension doesn't match the input file suffix
256+
# Rename if file extension doesn't match the input file suffix.
259257
if ext != suffix[1:]:
260258
fname.with_suffix("." + ext).rename(fname)
261259

@@ -331,11 +329,12 @@ def show(
331329
match method:
332330
case "notebook":
333331
if not _HAS_IPYTHON:
334-
raise GMTError(
332+
msg = (
335333
"Notebook display is selected, but IPython is not available. "
336334
"Make sure you have IPython installed, "
337335
"or run the script in a Jupyter notebook."
338336
)
337+
raise ImportError(msg)
339338
png = self._preview(
340339
fmt="png", dpi=dpi, anti_alias=True, as_bytes=True, **kwargs
341340
)
@@ -344,14 +343,15 @@ def show(
344343
pdf = self._preview(
345344
fmt="pdf", dpi=dpi, anti_alias=False, as_bytes=False, **kwargs
346345
)
347-
launch_external_viewer(pdf, waiting=waiting) # type: ignore[arg-type]
346+
launch_external_viewer(pdf, waiting=waiting)
348347
case "none":
349348
pass # Do nothing
350349
case _:
351-
raise GMTInvalidInput(
352-
f"Invalid display method '{method}'. Valid values are 'external', "
353-
"'notebook', 'none' or None."
350+
msg = (
351+
f"Invalid display method '{method}'. "
352+
"Valid values are 'external', 'notebook', 'none' or None."
354353
)
354+
raise GMTInvalidInput(msg)
355355

356356
def _preview(self, fmt: str, dpi: int, as_bytes: bool = False, **kwargs):
357357
"""
@@ -400,7 +400,7 @@ def _repr_html_(self):
400400
html = '<img src="data:image/png;base64,{image}" width="{width}px">'
401401
return html.format(image=base64_png.decode("utf-8"), width=500)
402402

403-
from pygmt.src import ( # type: ignore [misc]
403+
from pygmt.src import ( # type: ignore[misc]
404404
basemap,
405405
coast,
406406
colorbar,

pygmt/tests/test_clib_put_vector.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,12 @@ def test_put_vector_string_dtype():
172172

173173
def test_put_vector_timedelta64_dtype():
174174
"""
175-
Passing timedelta64 type vectors with various time units (year, month,
176-
week, day, hour, minute, second, millisecond, microsecond) to a dataset.
175+
Passing timedelta64 type vectors with various date/time units to a dataset.
176+
177+
Valid date/time units can be found at
178+
https://numpy.org/devdocs/reference/arrays.datetime.html#datetime-units.
177179
"""
178-
for unit in ["Y", "M", "W", "D", "h", "m", "s", "ms", "μs"]:
180+
for unit in ["Y", "M", "W", "D", "h", "m", "s", "ms", "us", "ns", "ps", "fs", "as"]:
179181
with clib.Session() as lib, GMTTempFile() as tmp_file:
180182
dataset = lib.create_data(
181183
family="GMT_IS_DATASET|GMT_VIA_VECTOR",

pygmt/tests/test_figure.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import numpy.testing as npt
1313
import pytest
1414
from pygmt import Figure, set_display
15-
from pygmt.exceptions import GMTError, GMTInvalidInput
15+
from pygmt.exceptions import GMTInvalidInput
1616
from pygmt.figure import SHOW_CONFIG, _get_default_display_method
1717
from pygmt.helpers import GMTTempFile
1818

@@ -196,12 +196,21 @@ def test_figure_savefig_transparent():
196196
fname = f"{prefix}.{fmt}"
197197
with pytest.raises(GMTInvalidInput):
198198
fig.savefig(fname, transparent=True)
199-
# png should not raise an error
199+
200+
# PNG should support transparency and should not raise an error.
200201
fname = Path(f"{prefix}.png")
201202
fig.savefig(fname, transparent=True)
202203
assert fname.exists()
203204
fname.unlink()
204205

206+
# The companion PNG file with KML format should also support transparency.
207+
fname = Path(f"{prefix}.kml")
208+
fig.savefig(fname, transparent=True)
209+
assert fname.exists()
210+
fname.unlink()
211+
assert fname.with_suffix(".png").exists()
212+
fname.with_suffix(".png").unlink()
213+
205214

206215
def test_figure_savefig_filename_with_spaces():
207216
"""
@@ -321,7 +330,7 @@ def test_figure_show_notebook_error_without_ipython():
321330
"""
322331
fig = Figure()
323332
fig.basemap(region=[0, 1, 2, 3], frame=True)
324-
with pytest.raises(GMTError):
333+
with pytest.raises(ImportError):
325334
fig.show(method="notebook")
326335

327336

@@ -361,7 +370,7 @@ def test_set_display(self):
361370
assert mock_viewer.call_count == 0
362371
assert mock_display.call_count == 1
363372
else:
364-
with pytest.raises(GMTError):
373+
with pytest.raises(ImportError):
365374
fig.show()
366375

367376
# Test the "external" display method

0 commit comments

Comments
 (0)