Skip to content

Commit cfc9ec7

Browse files
authored
Merge branch 'main' into to_numpy/skip-macos
2 parents b83c2c1 + eca2edd commit cfc9ec7

File tree

12 files changed

+222
-262
lines changed

12 files changed

+222
-262
lines changed

.github/workflows/check-links.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535

3636
- name: Link Checker
3737
id: lychee
38-
uses: lycheeverse/lychee-action@v2.0.2
38+
uses: lycheeverse/lychee-action@v2.1.0
3939
with:
4040
fail: false # Don't fail action on broken links
4141
output: /tmp/lychee-out.md

.github/workflows/ci_tests.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,10 @@ jobs:
177177

178178
# Upload coverage to Codecov
179179
- name: Upload coverage to Codecov
180-
uses: codecov/codecov-action@v4.6.0
180+
uses: codecov/codecov-action@v5.0.3
181181
if: success() || failure()
182182
with:
183183
use_oidc: true
184-
file: ./coverage.xml # optional
184+
files: ./coverage.xml # optional
185185
env_vars: OS,PYTHON,NUMPY
186186
fail_ci_if_error: false

doc/maintenance.md

+15-8
Original file line numberDiff line numberDiff line change
@@ -120,18 +120,25 @@ made to our documentation website every time we make a commit in a pull request.
120120
The service has a configuration file `.readthedocs.yaml`, with a list of options
121121
to change the default behaviour at <https://docs.readthedocs.io/en/stable/config-file/index.html>.
122122

123+
## Continuous Benchmarking
123124

124-
## Dependencies Policy
125+
We use the [CodSpeed](https://codspeed.io) service to continuously track PyGMT's
126+
performance. The `pytest-codspeed` plugin collects benchmark data and uploads it to the
127+
CodSpeed server, where results are available at <https://codspeed.io/GenericMappingTools/pygmt>.
125128

126-
PyGMT has adopted [SPEC 0](https://scientific-python.org/specs/spec-0000/) alongside the
127-
rest of the scientific Python ecosystem, and therefore:
129+
Benchmarking is handled through the `benchmarks.yml` GitHub Actions workflow. It's
130+
automatically executed when a pull request is merged into the main branch. To trigger
131+
benchmarking in a pull request, add the `run/benchmark` label to the pull request.
128132

129-
* Support for Python versions be dropped 3 years after their initial release.
130-
* Support for core package dependencies (NumPy, pandas, Xarray) be dropped 2 years after
131-
their initial release.
133+
To include a new test in the benchmark suite, apply the `@pytest.mark.benchmark`
134+
decorator to a test function.
132135

133-
Similarly, the PyGMT team has decided to discontinue support for GMT versions 3 years
134-
after their initial release.
136+
## Dependencies Policy
137+
138+
PyGMT has adopted [SPEC 0](https://scientific-python.org/specs/spec-0000/) alongside the
139+
rest of the scientific Python ecosystem, and made a few extensions based on the needs of
140+
the project. Please see [Minimum Supported Versions](minversions.md) for the detailed
141+
policy and the minimum supported versions of GMT, Python and core package dependencies.
135142

136143
In `pyproject.toml`, the `requires-python` key should be set to the minimum supported
137144
version of Python. Minimum supported versions of GMT, Python and core package

examples/gallery/images/cross_section.py

+31-47
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,11 @@
22
Cross-section along a transect
33
==============================
44
5-
:func:`pygmt.project` and :func:`pygmt.grdtrack` can be used to focus on
6-
a quantity and its variation along a desired survey line.
7-
In this example, the elevation is extracted from a grid provided via
8-
:func:`pygmt.datasets.load_earth_relief`.
9-
The figure consists of two parts, a map of the elevation in the study
10-
area showing the survey line and a Cartesian plot showing the elevation
11-
along the survey line.
5+
:func:`pygmt.project` and :func:`pygmt.grdtrack` can be used to focus on a quantity and
6+
its variation along a desired survey line. In this example, the elevation is extracted
7+
from a grid provided via :func:`pygmt.datasets.load_earth_relief`. The figure consists
8+
of two parts, a map of the elevation in the study area showing the survey line and a
9+
Cartesian plot showing the elevation along the survey line.
1210
1311
*This example is orientated on an example in the GMT/China documentation*:
1412
https://docs.gmt-china.org/latest/examples/ex026/
@@ -27,33 +25,24 @@
2725
# ----------------------------------------------------------------------------
2826
# Bottom: Map of elevation in study area
2927

30-
# Set up basic map
31-
fig.basemap(
32-
region=region_map,
33-
projection="M12c", # Mercator projection with a width of 12 centimeters
34-
frame="af",
35-
)
28+
# Set up basic map using a Mercator projection with a width of 12 centimeters
29+
fig.basemap(region=region_map, projection="M12c", frame="af")
3630

37-
# Download grid for Earth relief with a resolution of 10 arc-minutes and
38-
# gridline registration [Default]
39-
grid_map = pygmt.datasets.load_earth_relief(
40-
resolution="10m",
41-
region=region_map,
42-
)
31+
# Download grid for Earth relief with a resolution of 10 arc-minutes and gridline
32+
# registration [Default]
33+
grid_map = pygmt.datasets.load_earth_relief(resolution="10m", region=region_map)
4334

4435
# Plot the downloaded grid with color-coding based on the elevation
4536
fig.grdimage(grid=grid_map, cmap="oleron")
4637

4738
# Add a colorbar for the elevation
4839
fig.colorbar(
49-
# Place the colorbar inside the plot (lower-case "j") in the Bottom
50-
# Right (BR) corner with an offset ("+o") of 0.7 centimeters and
51-
# 0.3 centimeters in x or y directions, respectively
52-
# Move the x label above the horizontal colorbar ("+ml")
40+
# Place the colorbar inside the plot (lower-case "j") in the Botton Right (BR)
41+
# corner with an offset ("+o") of 0.7 centimeters and 0.3 centimeters in x or y
42+
# directions, respectively; move the x label above the horizontal colorbar ("+ml")
5343
position="jBR+o0.7c/0.8c+h+w5c/0.3c+ml",
54-
# Add a box around the colobar with a fill ("+g") in "white" color and
55-
# a transparency ("@") of 30 % and with a 0.8-points thick black
56-
# outline ("+p")
44+
# Add a box around the colobar with a fill ("+g") in "white" color and a
45+
# transparency ("@") of 30 % and with a 0.8-points thick, black, outline ("+p")
5746
box="+gwhite@30+p0.8p,black",
5847
# Add x and y labels ("+l")
5948
frame=["x+lElevation", "y+lm"],
@@ -63,7 +52,7 @@
6352
fig.plot(
6453
x=[126, 146], # Longitude in degrees East
6554
y=[42, 40], # Latitude in degrees North
66-
# Draw a 2-points thick red dashed line for the survey line
55+
# Draw a 2-points thick, red, dashed line for the survey line
6756
pen="2p,red,dashed",
6857
)
6958

@@ -79,16 +68,15 @@
7968
# ----------------------------------------------------------------------------
8069
# Top: Elevation along survey line
8170

82-
# Shift plot origin 12.5 centimeters to the top
83-
fig.shift_origin(yshift="12.5c")
71+
# Shift plot origin to the top by the height of the map ("+h") plus 1.5 centimeters
72+
fig.shift_origin(yshift="h+1.5c")
8473

8574
fig.basemap(
8675
region=[0, 15, -8000, 6000], # x_min, x_max, y_min, y_max
87-
# Cartesian projection with a width of 12 centimeters and
88-
# a height of 3 centimeters
76+
# Cartesian projection with a width of 12 centimeters and a height of 3 centimeters
8977
projection="X12c/3c",
90-
# Add annotations ("a") and ticks ("f") as well as labels ("+l")
91-
# at the west or left and south or bottom sides ("WSrt")
78+
# Add annotations ("a") and ticks ("f") as well as labels ("+l") at the west or
79+
# left and south or bottom sides ("WSrt")
9280
frame=["WSrt", "xa2f1+lDistance+u°", "ya4000+lElevation / m"],
9381
)
9482

@@ -101,28 +89,24 @@
10189
font="10p", # Use a font size of 10 points
10290
)
10391

104-
# Generate points along a great circle corresponding to the survey line
105-
# and store them in a pandas.DataFrame
92+
# Generate points along a great circle corresponding to the survey line and store them
93+
# in a pandas.DataFrame
10694
track_df = pygmt.project(
107-
center="126/42", # Start point of survey line (longitude/latitude)
108-
endpoint="146/40", # End point of survey line (longitude/latitude)
109-
generate="0.1", # Output data in steps of 0.1 degrees
95+
center=[126, 42], # Start point of survey line (longitude, latitude)
96+
endpoint=[146, 40], # End point of survey line (longitude, latitude)
97+
generate=0.1, # Output data in steps of 0.1 degrees
11098
)
11199

112-
# Extract the elevation at the generated points from the downloaded grid
113-
# and add it as new column "elevation" to the pandas.DataFrame
114-
track_df = pygmt.grdtrack(
115-
grid=grid_map,
116-
points=track_df,
117-
newcolname="elevation",
118-
)
100+
# Extract the elevation at the generated points from the downloaded grid and add it as
101+
# new column "elevation" to the pandas.DataFrame
102+
track_df = pygmt.grdtrack(grid=grid_map, points=track_df, newcolname="elevation")
119103

120104
# Plot water masses
121105
fig.plot(
122106
x=[0, 15],
123107
y=[0, 0],
124108
fill="lightblue", # Fill the polygon in "lightblue"
125-
# Draw a 0.25-points thick black solid outline
109+
# Draw a 0.25-points thick, black, solid outline
126110
pen="0.25p,black,solid",
127111
close="+y-8000", # Force closed polygon
128112
)
@@ -132,7 +116,7 @@
132116
x=track_df.p,
133117
y=track_df.elevation,
134118
fill="gray", # Fill the polygon in "gray"
135-
# Draw a 1-point thick black solid outline
119+
# Draw a 1-point thick, black, solid outline
136120
pen="1p,black,solid",
137121
close="+y-8000", # Force closed polygon
138122
)

examples/gallery/lines/envelope.py

+13-23
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@
22
Envelope
33
========
44
5-
The ``close`` parameter of the :meth:`pygmt.Figure.plot` method can be
6-
used to build a symmetrical or an asymmetrical envelope. The user can
7-
give either the deviations or the bounds in y-direction. For the first
8-
case append ``"+d"`` or ``"+D"`` and for the latter case ``"+b"``.
5+
The ``close`` parameter of the :meth:`pygmt.Figure.plot` method can be used to build a
6+
symmetrical or an asymmetrical envelope. The user can give either the deviations or the
7+
bounds in y-direction. For the first case append ``"+d"`` or ``"+D"`` and for the latter
8+
case ``"+b"``.
99
"""
1010

1111
# %%
1212
import pandas as pd
1313
import pygmt
1414

15-
# Define a pandas DataFrame with columns for x and y as well as the
16-
# lower and upper deviations
15+
# Define a pandas.DataFrame with columns for x and y as well as the lower and upper
16+
# deviations
1717
df_devi = pd.DataFrame(
1818
data={
1919
"x": [1, 3, 5, 7, 9],
@@ -23,7 +23,7 @@
2323
}
2424
)
2525

26-
# Define the same pandas DataFrame but with lower and upper bounds
26+
# Define the same pandas.DataFrame but with lower and upper bounds
2727
df_bound = pd.DataFrame(
2828
data={
2929
"x": [1, 3, 5, 7, 9],
@@ -34,7 +34,6 @@
3434
)
3535

3636

37-
# Create Figure instance
3837
fig = pygmt.Figure()
3938

4039
# -----------------------------------------------------------------------------
@@ -55,15 +54,10 @@
5554
)
5655

5756
# Plot the data points on top
58-
fig.plot(
59-
data=df_devi,
60-
style="c0.2c", # Use circles with a diameter of 0.2 centimeters
61-
pen="1p,gray30",
62-
fill="darkgray",
63-
)
57+
fig.plot(data=df_devi, style="c0.2c", pen="1p,gray30", fill="darkgray")
6458

65-
# Shift plot origin 11 centimeters in x direction
66-
fig.shift_origin(xshift="11c")
59+
# Shift plot origin by the figure width ("w") plus 1 centimeter in x direction
60+
fig.shift_origin(xshift="w+1c")
6761

6862
# -----------------------------------------------------------------------------
6963
# Middle
@@ -77,18 +71,15 @@
7771
fig.plot(
7872
data=df_devi,
7973
fill="gray@50",
80-
# Add an outline around the envelope
81-
# Here, a dashed pen ("+p") with 0.5-points thickness and
82-
# "gray30" color is used
74+
# Add an outline around the envelope. Here, a dashed pen ("+p") with 0.5-points
75+
# thickness and "gray30" color is used
8376
close="+D+p0.5p,gray30,dashed",
8477
pen="1p,gray30",
8578
)
8679

87-
# Plot the data points on top
8880
fig.plot(data=df_devi, style="c0.2c", pen="1p,gray30", fill="darkgray")
8981

90-
# Shift plot origin 11 centimeters in x-direction
91-
fig.shift_origin(xshift="11c")
82+
fig.shift_origin(xshift="w+1c")
9283

9384
# -----------------------------------------------------------------------------
9485
# Right
@@ -102,7 +93,6 @@
10293
# Plot an envelope based on the bounds ("+b")
10394
fig.plot(data=df_bound, close="+b+p0.5p,gray30,dashed", pen="1p,gray30")
10495

105-
# Plot the data points on top
10696
fig.plot(data=df_bound, style="c0.2c", pen="1p,gray30", fill="darkgray")
10797

10898
fig.show()

examples/gallery/symbols/multi_parameter_symbols.py

+24-19
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
Multi-parameter symbols
33
=======================
44
5-
The :meth:`pygmt.Figure.plot` method can plot individual multi-parameter
6-
symbols by passing the corresponding shortcuts (**e**, **j**, **r**, **R**,
7-
**w**) to the ``style`` parameter:
5+
The :meth:`pygmt.Figure.plot` method can plot individual multi-parameter symbols by
6+
passing the corresponding shortcuts (**e**, **j**, **r**, **R**, **w**) to the ``style``
7+
parameter:
88
99
- **e**: ellipse
1010
- **j**: rotated rectangle
@@ -18,10 +18,10 @@
1818
import pygmt
1919

2020
# %%
21-
# We can plot multi-parameter symbols using the same symbol style. We need to
22-
# define locations (lon, lat) via the ``x`` and ``y`` parameters (scalar for
23-
# a single symbol or 1-D list for several ones) and two or three symbol
24-
# parameters after those shortcuts via the ``style`` parameter.
21+
# We can plot multi-parameter symbols using the same symbol style. We need to define
22+
# locations (lon, lat) via the ``x`` and ``y`` parameters (scalar for a single symbol or
23+
# 1-D list for several ones) and two or three symbol parameters after those shortcuts
24+
# via the ``style`` parameter.
2525
#
2626
# The multi-parameter symbols in the ``style`` parameter are defined as:
2727
#
@@ -30,13 +30,14 @@
3030
# - **r**: rectangle, ``width/height``
3131
# - **R**: rounded rectangle, ``width/height/radius``
3232
# - **w**: pie wedge, ``diameter/startdir/stopdir``, the last two arguments are
33-
# directions given in degrees counter-clockwise from horizontal
33+
# directions given in degrees counter-clockwise from horizontal. Append **+i** and the
34+
# desired value to apply an inner diameter.
3435
#
35-
# Upper-case versions **E**, **J**, and **W** are similar to **e**, **j**, and
36-
# **w** but expect geographic azimuths and distances.
36+
# Upper-case versions **E**, **J**, and **W** are similar to **e**, **j**, and **w**
37+
# but expect geographic azimuths and distances.
3738

3839
fig = pygmt.Figure()
39-
fig.basemap(region=[0, 6, 0, 2], projection="x3c", frame=True)
40+
fig.basemap(region=[0, 7, 0, 2], projection="x3c", frame=True)
4041

4142
# Ellipse
4243
fig.plot(x=0.5, y=1, style="e45/3/1", fill="orange", pen="2p,black")
@@ -48,27 +49,28 @@
4849
fig.plot(x=4.5, y=1, style="R1.25/4/0.5", fill="seagreen", pen="2p,black")
4950
# Pie wedge
5051
fig.plot(x=5.5, y=1, style="w2.5/45/330", fill="lightgray", pen="2p,black")
52+
# Ring sector
53+
fig.plot(x=6.5, y=1, style="w2.5/45/330+i1", fill="lightgray", pen="2p,black")
5154

5255
fig.show()
5356

5457
# %%
55-
# We can also plot symbols with varying parameters via defining those values in
56-
# a 2-D list or numpy array (``[[parameters]]`` for a single symbol or
57-
# ``[[parameters_1],[parameters_2],[parameters_i]]`` for several ones) or using
58-
# an appropriately formatted input file and passing it to ``data``.
58+
# We can also plot symbols with varying parameters via defining those values in a 2-D
59+
# list or numpy array (``[[parameters]]`` for a single symbol or
60+
# ``[[parameters_1],[parameters_2],[parameters_i]]`` for several ones) or using an
61+
# appropriately formatted input file and passing it to ``data``.
5962
#
6063
# The symbol parameters in the 2-D list or numpy array are defined as:
6164
#
6265
# - **e**: ellipse, ``[[lon, lat, direction, major_axis, minor_axis]]``
6366
# - **j**: rotated rectangle, ``[[lon, lat, direction, width, height]]``
6467
# - **r**: rectangle, ``[[lon, lat, width, height]]``
6568
# - **R**: rounded rectangle, ``[[lon, lat, width, height, radius]]``
66-
# - **w**: pie wedge, ``[[lon, lat, diameter, startdir, stopdir]]``, the last
67-
# two arguments are directions given in degrees counter-clockwise from
68-
# horizontal
69+
# - **w**: pie wedge, ``[[lon, lat, diameter, startdir, stopdir]]``, the last two
70+
# arguments are directions given in degrees counter-clockwise from horizontal
6971

7072
fig = pygmt.Figure()
71-
fig.basemap(region=[0, 6, 0, 4], projection="x3c", frame=["xa1f0.2", "ya0.5f0.1"])
73+
fig.basemap(region=[0, 7, 0, 4], projection="x3c", frame=["xa1f0.2", "ya0.5f0.1"])
7274

7375
# Ellipse
7476
data = [[0.5, 1, 45, 3, 1], [0.5, 3, 135, 2, 1]]
@@ -85,6 +87,9 @@
8587
# Pie wedge
8688
data = [[5.5, 1, 2.5, 45, 330], [5.5, 3, 1.5, 60, 300]]
8789
fig.plot(data=data, style="w", fill="lightgray", pen="2p,black")
90+
# Ring sector
91+
data = [[6.5, 1, 2.5, 45, 330], [6.5, 3, 1.5, 60, 300]]
92+
fig.plot(data=data, style="w+i1", fill="lightgray", pen="2p,black")
8893

8994
fig.show()
9095

0 commit comments

Comments
 (0)