Skip to content

Commit

Permalink
Merge branch 'main' into feature/scatter
Browse files Browse the repository at this point in the history
  • Loading branch information
seisman committed Nov 24, 2024
2 parents 4d450cb + bad7943 commit e58d873
Show file tree
Hide file tree
Showing 35 changed files with 529 additions and 478 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/benchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,4 @@ jobs:
with:
# 'bash -el -c' is needed to use the custom shell.
# See https://github.com/CodSpeedHQ/action/issues/65.
run: bash -el -c "python -c \"import pygmt; pygmt.show_versions()\"; PYGMT_USE_EXTERNAL_DISPLAY=false python -m pytest -r P --pyargs pygmt --codspeed"
run: bash -el -c "python -c \"import pygmt; pygmt.show_versions()\"; PYGMT_USE_EXTERNAL_DISPLAY=false python -m pytest -r P --pyargs pygmt --codspeed --override-ini addopts='--verbose'"
2 changes: 1 addition & 1 deletion .github/workflows/check-links.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:

- name: Link Checker
id: lychee
uses: lycheeverse/lychee-action@v2.0.2
uses: lycheeverse/lychee-action@v2.1.0
with:
fail: false # Don't fail action on broken links
output: /tmp/lychee-out.md
Expand Down
51 changes: 25 additions & 26 deletions .github/workflows/ci_tests.yaml
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
# Test PyGMT on Linux/macOS/Windows
#
# This workflow runs regular PyGMT tests and uploads test coverage reports stored
# in `.coverage.xml` to https://app.codecov.io/gh/GenericMappingTools/pygmt
# via the [Codecov GitHub Action](https://github.com/codecov/codecov-action).
# More codecov related configurations are stored in `.github/codecov.yml`.
# If any tests fail, it also uploads the diff images as workflow artifacts.
# This workflow runs regular PyGMT tests and uploads test coverage reports stored in
# `.coverage.xml` to https://app.codecov.io/gh/GenericMappingTools/pygmt via the
# [Codecov GitHub Action](https://github.com/codecov/codecov-action). More codecov
# related configurations are stored in `.github/codecov.yml`. If any tests fail, it also
# uploads the diff images as workflow artifacts.
#
# It is run:
# 1. on every commit to the main branch
# 2. on every commit to the pull request branches, unless the pull requests only
# contain non-code changes.
# 2. on every commit to the pull request branches, unless the pull requests only contain
# non-code changes.
# 3. when a new release is published
#
# It is also scheduled to run daily on the main branch.
#
# In draft pull request, only two jobs on Linux are triggered to save on
# Continuous Integration resources:
# In draft pull request, only jobs on Linux are triggered to save on Continuous
# Integration resources:
#
# - Minimum supported Python, NumPy, pandas, Xarray versions following [SPEC 0](https://scientific-python.org/specs/spec-0000/)
# - Latest Python, NumPy versions + optional packages (e.g. GeoPandas)
# - Minimum supported Python + core packages (minimum supported versions)
# + optional packages (minimum supported versions if any)
# - Latest Python + core packages (latest versions) + optional packages
# - Last release before the latest Python + core packages
#
name: Tests

Expand Down Expand Up @@ -59,35 +61,32 @@ jobs:
# Is it a draft Pull Request (true or false)?
isDraft:
- ${{ github.event.pull_request.draft }}
# Only run two jobs (Ubuntu + Python 3.10/3.12) for draft PRs
# Only run three jobs on Ubuntu for draft PRs
exclude:
- os: macos-latest
isDraft: true
- os: windows-latest
isDraft: true
# Pair Python 3.10 with the minimum supported versions of NumPy, pandas, Xarray
# and Python 3.12 with the latest versions of NumPy, pandas, Xarray
# Only install optional packages on Python 3.12
include:
# Python 3.10 + core packages (minimum supported versions) + optional packages (minimum supported versions if any)
- python-version: '3.10'
numpy-version: '1.24'
pandas-version: '=2.0'
xarray-version: '=2023.04'
optional-packages: ''
optional-packages: ' contextily geopandas<1 ipython pyarrow rioxarray sphinx-gallery'
# Python 3.12 + core packages (latest versions) + optional packages
- python-version: '3.12'
numpy-version: '2.1'
pandas-version: ''
xarray-version: ''
optional-packages: ' contextily geopandas ipython pyarrow rioxarray sphinx-gallery'
# The job below is for testing GeoPandas v0.x on Ubuntu.
# The python-version here can't be the versions in the matrix.python-version
# defined above. Otherwise, other jobs will be overridden by this one.
optional-packages: ' contextily geopandas>=1.0 ipython pyarrow rioxarray sphinx-gallery'
# Python 3.11 + core packages (Linux only)
- os: 'ubuntu-latest'
python-version: '3.11' # Can't be 3.10 or 3.12.
numpy-version: '1.24'
pandas-version: '=2.1'
python-version: '3.11'
numpy-version: ''
pandas-version: ''
xarray-version: ''
optional-packages: ' geopandas<1 pyarrow'
optional-packages: ''

timeout-minutes: 30
defaults:
Expand Down Expand Up @@ -178,10 +177,10 @@ jobs:

# Upload coverage to Codecov
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4.6.0
uses: codecov/codecov-action@v5.0.3
if: success() || failure()
with:
use_oidc: true
file: ./coverage.xml # optional
files: ./coverage.xml # optional
env_vars: OS,PYTHON,NUMPY
fail_ci_if_error: false
2 changes: 1 addition & 1 deletion .github/workflows/ci_tests_legacy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
python=3.10
gmt=${{ matrix.gmt_version }}
ghostscript<10
numpy
numpy<2
pandas
xarray
netCDF4
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ doctest: _runtest
# run tests without image comparisons
# run pytest without the --mpl option to disable image comparisons
# use '-o addopts' to override 'addopts' settings in pyproject.toml file
test_no_images: PYTEST_ARGS=-o addopts="--verbose --durations=0 --durations-min=0.2 --doctest-modules"
test_no_images: PYTEST_ARGS=-o addopts="--verbose --color=yes --durations=0 --durations-min=0.2 --doctest-modules"
test_no_images: _runtest

format:
Expand Down
15 changes: 4 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,7 @@ Other official wrappers for GMT:
## Minimum supported versions

PyGMT has adopted [SPEC 0](https://scientific-python.org/specs/spec-0000/) alongside the
rest of the scientific Python ecosystem, and therefore:

- Support for Python versions be dropped 3 years after their initial release.
- Support for core package dependencies (NumPy, pandas, Xarray) be dropped 2 years after
their initial release.

Similarly, the PyGMT team has decided to discontinue support for GMT versions 3 years
after their initial release.

Please see [Minimum Supported Versions](https://www.pygmt.org/dev/minversions.html) for
the minimum supported versions of GMT, Python and core package dependencies.
rest of the scientific Python ecosystem, and made a few extensions based on the needs of
the project. Please see [Minimum Supported Versions](https://www.pygmt.org/dev/minversions.html)
for the detailed policy and the minimum supported versions of GMT, Python and core
package dependencies.
1 change: 1 addition & 0 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"contextily": ("https://contextily.readthedocs.io/en/stable/", None),
"geopandas": ("https://geopandas.org/en/stable/", None),
"numpy": ("https://numpy.org/doc/stable/", None),
"pyarrow": ("https://arrow.apache.org/docs/", None),
"python": ("https://docs.python.org/3/", None),
"pandas": ("https://pandas.pydata.org/pandas-docs/stable/", None),
"rasterio": ("https://rasterio.readthedocs.io/en/stable/", None),
Expand Down
6 changes: 3 additions & 3 deletions doc/ecosystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ Python objects. They are based on the C++ implementation of Arrow.
```{note}
If you have [PyArrow][] installed, PyGMT does have some initial support for
`pandas.Series` and `pandas.DataFrame` objects with Apache Arrow-backed arrays.
Specifically, only uint/int/float and date32/date64 are supported for now.
Support for string Array dtypes, Duration types and GeoArrow geometry types is still a work in progress.
For more details, see
Specifically, only uint/int/float, date32/date64 and string types are supported for now.
Support for Duration types and GeoArrow geometry types is still a work in progress. For
more details, see
[issue #2800](https://github.com/GenericMappingTools/pygmt/issues/2800).
```

Expand Down
23 changes: 15 additions & 8 deletions doc/maintenance.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,18 +120,25 @@ made to our documentation website every time we make a commit in a pull request.
The service has a configuration file `.readthedocs.yaml`, with a list of options
to change the default behaviour at <https://docs.readthedocs.io/en/stable/config-file/index.html>.

## Continuous Benchmarking

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

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

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

Similarly, the PyGMT team has decided to discontinue support for GMT versions 3 years
after their initial release.
## Dependencies Policy

PyGMT has adopted [SPEC 0](https://scientific-python.org/specs/spec-0000/) alongside the
rest of the scientific Python ecosystem, and made a few extensions based on the needs of
the project. Please see [Minimum Supported Versions](minversions.md) for the detailed
policy and the minimum supported versions of GMT, Python and core package dependencies.

In `pyproject.toml`, the `requires-python` key should be set to the minimum supported
version of Python. Minimum supported versions of GMT, Python and core package
Expand Down
23 changes: 17 additions & 6 deletions doc/minversions.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,25 @@ myst:
# Minimum Supported Versions

PyGMT has adopted [SPEC 0](https://scientific-python.org/specs/spec-0000/) alongside the
rest of the scientific Python ecosystem, and therefore:
rest of the scientific Python ecosystem, and will therefore:

- Support for Python versions be dropped 3 years after their initial release.
- Support for core package dependencies (NumPy, pandas, Xarray) be dropped 2 years after
their initial release.
- Drop support for Python versions 3 years after their initial release.
- Drop support for core package dependencies (NumPy, pandas, Xarray) 2 years after their
initial release.

Similarly, the PyGMT team has decided to discontinue support for GMT versions 3 years
after their initial release.
In addition to the above, the PyGMT team has also decided to:

- Drop support for GMT versions 3 years after their initial release, while ensuring at
least two latest minor versions remain supported.
- Maintain support for [optional dependencies](/ecosystem.md#pygmt-dependencies) for at
least 1 year after their initial release. Users are encouraged to use the most
up-to-date optional dependencies where possible.

:::{note}
The SPEC 0 policy is enforced on a best-effort basis, and the PyGMT team may decide to
drop support for core (and optional) package dependencies earlier than recommended for
compatibility reasons.
:::

| PyGMT Version | GMT | Python | NumPy | pandas | Xarray |
|---|---|---|---|---|---|
Expand Down
2 changes: 0 additions & 2 deletions examples/gallery/GALLERY_HEADER.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
.. _gallery:

Gallery
=======

Expand Down
78 changes: 31 additions & 47 deletions examples/gallery/images/cross_section.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
Cross-section along a transect
==============================
:func:`pygmt.project` and :func:`pygmt.grdtrack` can be used to focus on
a quantity and its variation along a desired survey line.
In this example, the elevation is extracted from a grid provided via
:func:`pygmt.datasets.load_earth_relief`.
The figure consists of two parts, a map of the elevation in the study
area showing the survey line and a Cartesian plot showing the elevation
along the survey line.
:func:`pygmt.project` and :func:`pygmt.grdtrack` can be used to focus on a quantity and
its variation along a desired survey line. In this example, the elevation is extracted
from a grid provided via :func:`pygmt.datasets.load_earth_relief`. The figure consists
of two parts, a map of the elevation in the study area showing the survey line and a
Cartesian plot showing the elevation along the survey line.
*This example is orientated on an example in the GMT/China documentation*:
https://docs.gmt-china.org/latest/examples/ex026/
Expand All @@ -27,33 +25,24 @@
# ----------------------------------------------------------------------------
# Bottom: Map of elevation in study area

# Set up basic map
fig.basemap(
region=region_map,
projection="M12c", # Mercator projection with a width of 12 centimeters
frame="af",
)
# Set up basic map using a Mercator projection with a width of 12 centimeters
fig.basemap(region=region_map, projection="M12c", frame="af")

# Download grid for Earth relief with a resolution of 10 arc-minutes and
# gridline registration [Default]
grid_map = pygmt.datasets.load_earth_relief(
resolution="10m",
region=region_map,
)
# Download grid for Earth relief with a resolution of 10 arc-minutes and gridline
# registration [Default]
grid_map = pygmt.datasets.load_earth_relief(resolution="10m", region=region_map)

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

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

Expand All @@ -79,16 +68,15 @@
# ----------------------------------------------------------------------------
# Top: Elevation along survey line

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

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

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

# Generate points along a great circle corresponding to the survey line
# and store them in a pandas.DataFrame
# Generate points along a great circle corresponding to the survey line and store them
# in a pandas.DataFrame
track_df = pygmt.project(
center="126/42", # Start point of survey line (longitude/latitude)
endpoint="146/40", # End point of survey line (longitude/latitude)
generate="0.1", # Output data in steps of 0.1 degrees
center=[126, 42], # Start point of survey line (longitude, latitude)
endpoint=[146, 40], # End point of survey line (longitude, latitude)
generate=0.1, # Output data in steps of 0.1 degrees
)

# Extract the elevation at the generated points from the downloaded grid
# and add it as new column "elevation" to the pandas.DataFrame
track_df = pygmt.grdtrack(
grid=grid_map,
points=track_df,
newcolname="elevation",
)
# Extract the elevation at the generated points from the downloaded grid and add it as
# new column "elevation" to the pandas.DataFrame
track_df = pygmt.grdtrack(grid=grid_map, points=track_df, newcolname="elevation")

# Plot water masses
fig.plot(
x=[0, 15],
y=[0, 0],
fill="lightblue", # Fill the polygon in "lightblue"
# Draw a 0.25-points thick black solid outline
# Draw a 0.25-points thick, black, solid outline
pen="0.25p,black,solid",
close="+y-8000", # Force closed polygon
)
Expand All @@ -132,7 +116,7 @@
x=track_df.p,
y=track_df.elevation,
fill="gray", # Fill the polygon in "gray"
# Draw a 1-point thick black solid outline
# Draw a 1-point thick, black, solid outline
pen="1p,black,solid",
close="+y-8000", # Force closed polygon
)
Expand Down
Loading

0 comments on commit e58d873

Please sign in to comment.