GenericMappingTools / GenericMappingTools/pygmt

Consistent syntax for GMT clearance and margins

Open
#4,869 0 comments 0 reactions 0 assignees View on GitHub
discussions
Dominant language
Python
Stars
874
Forks
255
Avg merge
1d 21h
Merged PRs (30d)
40

Description

## Background

In GMT, there are two main types of clearance/margin.

**Type 1: text clearance.**

Syntax is `[/]`, accepting one or two values. If `` is omitted it equals ``.

Examples: `text -C`, `subplot -A...+c`, `grdcontour -A...+c`.

**Type 2: clearances/margins for four sides.**

Accepts 1, 2, or 4 values:

- 1 value: same clearance on all four sides.
- 2 values: clearances for the x- and y-sides, respectively.
- 4 values: clearances for the w, e, s, n sides, respectively.

Examples: `inset -C`, `subplot -C`, `subplot -M`, `basemap -F...+c` (the `Box` class), `psconvert -I+m`.

## What's inconsistent?

**Type 2** has two different syntaxes across GMT modules:

1. **Slash-separated values**, e.g. `-C0.5`, `-C0.5/0.2`, `-C0.5/0.2/0.3/0.4`
2. **Side directives**, e.g. `-C0.5`, `-Cx0.5 -Cy0.2`, `-Cw0.5 -Ce0.2 -Cs0.3 -Cn0.4`

The complexity is that different module options support different subsets:

| module option | slash-separated values | side directives |
|---|---|---|
| `inset -C` | Yes* | Yes |
| `subplot -C` | No | Yes |
| `subplot -M` | Yes | No |
| `basemap -F...+c` | Yes | No |
| `psconvert -I+m` | Yes | No |

*`inset -C` supports the slash-separated-value syntax for backward compatibility.

## Current state in PyGMT

The slash-separated syntax maps cleanly onto Python sequences and is already what we use for, e.g., in `Box`:

```python
Box(clearance=0.5)
Box(clearance=(0.5, 0.2))
Box(clearance=(0.5, 0.2, 0.3, 0.4))
```

The side-directive syntax is more flexible on the GMT command line. It lets you set only specific sides. But it is not Pythonic (can't pass numeric values), and it is what `subplot`'s `clearance` currently exposes:

```python
clearance=0.5
clearance=["x0.5", "y0.2"]
clearance=["w0.5", "e0.2", "s0.3", "n0.4"]
```

## Proposal

A possible way to make the side-directive syntax more Pythonic is:
```
clearance={"west": 0.5, "east": 0.2}
```
But the syntax for clearance/margins will be inconsistent across the PyGMT project.

So, I propose to drop the side-directive syntax from PyGMT's public API and expose Type 2 uniformly as a
scalar or a sequence of 2 or 4 values, matching `Box.clearance` and `subplot.margins`. Internally, we just need to convert `clearance=(0.5, 0, 0, 0)` to `-Cw0.5`.

## TODO

- [ ] `Figure.inset`: Migrate the `clearance` parameter to the new alias system and improve docstrings
- [ ] `Figure.subplot`: Add a private function to support slash-separated syntax and improve docstrings, since GMT doesn't support slash-separated syntax in `subplot -C`

Contributor guide

Open the contributing guide

Research direction

Start with Figure.inset and Figure.subplot, then compare their clearance handling with Box.clearance and subplot.margins. Migrate the public APIs to scalar or 2- or 4-value sequences, add the internal conversion needed for subplot side directives, and update the affected docstrings.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api, developer-experience
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.