GenericMappingTools / GenericMappingTools/pygmt
Consistent syntax for GMT clearance and margins
- 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
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