Skip to content

Commit b2c9877

Browse files
committed
Improve Axis/Axes/Frame and add more tests
1 parent 6f97c57 commit b2c9877

File tree

2 files changed

+102
-24
lines changed

2 files changed

+102
-24
lines changed

pygmt/params/frame.py

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from typing import Any, Literal
77

88
from pygmt.alias import Alias
9+
from pygmt.exceptions import GMTInvalidInput
910
from pygmt.params.base import BaseParam
1011

1112

@@ -15,9 +16,17 @@ class Axis(BaseParam):
1516
Class for setting up one axis of a plot.
1617
"""
1718

18-
#: Intervals for annotations and major tick spacing, minor tick spacing, and/or
19-
#: grid line spacing.
20-
interval: float | str
19+
#: Specify annotation for the axis. Provide a specific interval with an optional
20+
#: unit. Set to ``True`` to use default interval.
21+
annotation: float | str | bool = False
22+
23+
#: Specify ticks for the axis. Provide a specific interval with an optional unit.
24+
#: Set to ``True`` to use default interval.
25+
tick: float | str | bool = False
26+
27+
#: Specify grid lines for the axis. Provide a specific interval with an optional
28+
#: unit. Set to ``True`` to use default interval.
29+
grid: float | str | bool = False
2130

2231
#: Plot slanted annotations (for Cartesian plots only), where *angle* is measured
2332
#: with respect to the horizontal and must be in the -90 <= *angle* <= 90 range.
@@ -26,10 +35,10 @@ class Axis(BaseParam):
2635
#: :gmt-term:`MAP_ANNOT_ORTHO`.
2736
angle: float | None = None
2837

29-
#: Skip annotations that fall exactly at the ends of the axis. Choose from ``left``
30-
#: or ``right`` to skip only the lower or upper annotation, respectively, or
38+
#: Skip annotations that fall exactly at the ends of the axis. Choose from ``lower``
39+
#: or ``upper`` to skip only the lower or upper annotation, respectively, or
3140
#: ``True`` to skip both.
32-
skip_edge: Literal["left", "right"] | bool = False
41+
skip_edge: Literal["lower", "upper"] | bool = False
3342

3443
#: Give fancy annotations with W|E|S|N suffixes encoding the sign (for geographic
3544
#: axes only).
@@ -58,22 +67,43 @@ class Axis(BaseParam):
5867
#: :gmt-term:`FORMAT_GEO_MAP`.
5968
unit: str | None = None
6069

70+
def _validate(self):
71+
"""
72+
Validate the parameters.
73+
"""
74+
if self.label is not None and self.hlabel is not None:
75+
msg = "Parameters 'label' and 'hlabel' cannot be both set."
76+
raise GMTInvalidInput(msg)
77+
if self.alt_label is not None and self.alt_hlabel is not None:
78+
msg = "Parameters 'alt_label' and 'alt_hlabel' cannot be both set."
79+
raise GMTInvalidInput(msg)
80+
6181
@property
6282
def _aliases(self):
6383
return [
64-
Alias(self.interval, name="interval"),
65-
Alias(self.angle, name="angle", prefix="+a"),
84+
Alias(self.annotation, name="annotation", prefix="a"),
85+
Alias(self.tick, name="tick", prefix="f"),
86+
Alias(self.grid, name="grid", prefix="g"),
87+
Alias(
88+
self.angle,
89+
name="angle",
90+
prefix="+a",
91+
mapping={"normal": "n", "parallel": "p"}
92+
if isinstance(self.angle, str)
93+
else None,
94+
),
6695
Alias(
6796
self.skip_edge,
6897
name="skip_edge",
6998
prefix="+e",
70-
mapping={True: True, "left": "l", "right": "r"},
99+
mapping={True: True, "lower": "l", "upper": "u"},
71100
),
72101
Alias(self.fancy, name="fancy", prefix="+f"),
73102
Alias(self.label, name="label", prefix="+l"),
74103
Alias(self.hlabel, name="hlabel", prefix="+L"),
75104
Alias(self.alt_label, name="alt_label", prefix="+s"),
76105
Alias(self.alt_hlabel, name="alt_hlabel", prefix="+S"),
106+
Alias(self.prefix, name="prefix", prefix="+p"),
77107
Alias(self.unit, name="unit", prefix="+u"),
78108
]
79109

@@ -115,17 +145,25 @@ class Frame(BaseParam):
115145
"""
116146

117147
axes: Any = None
148+
axis: Any = None
118149
xaxis: Any = None
119150
yaxis: Any = None
120151
zaxis: Any = None
152+
xaxis_secondary: Any = None
153+
yaxis_secondary: Any = None
154+
zaxis_secondary: Any = None
121155

122156
@property
123157
def _aliases(self):
124158
return [
125159
Alias(self.axes),
160+
Alias(self.axis),
126161
Alias(self.xaxis, prefix="x"),
127162
Alias(self.yaxis, prefix="y"),
128163
Alias(self.zaxis, prefix="z"),
164+
Alias(self.xaxis_secondary, prefix="sx"),
165+
Alias(self.yaxis_secondary, prefix="sy"),
166+
Alias(self.zaxis_secondary, prefix="sz"),
129167
]
130168

131169
def __iter__(self):

pygmt/tests/test_params_frame.py

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,66 @@
55
from pygmt.params import Axes, Axis
66

77

8-
def test_params_axis():
8+
def test_params_axis_intervals():
99
"""
10-
Test the Axis class.
10+
Test the annotation, tick, and grid parameters of the Axis class.
1111
"""
12-
assert str(Axis(interval="a1f0.5")) == "a1f0.5"
13-
assert str(Axis(interval="a1f0.5", angle=30)) == "a1f0.5+a30"
14-
assert str(Axis(interval="a1f0.5", angle=30, skip_edge="left")) == "a1f0.5+a30+el"
15-
assert str(Axis(interval="a1f0.5", fancy=True)) == "a1f0.5+f"
16-
assert str(Axis(interval="a1f0.5", label="My Label")) == "a1f0.5+lMy Label"
17-
assert str(Axis(interval="a1f0.5", hlabel="My HLabel")) == "a1f0.5+LMy HLabel"
18-
assert str(Axis(interval="a1f0.5", alt_label="Alt Label")) == "a1f0.5+sAlt Label"
19-
assert str(Axis(interval="a1f0.5", alt_hlabel="Alt HLabel")) == "a1f0.5+SAlt HLabel"
20-
assert str(Axis(interval="a1f0.5", unit="km")) == "a1f0.5+ukm"
12+
assert str(Axis(annotation=1)) == "a1"
13+
assert str(Axis(tick=2)) == "f2"
14+
assert str(Axis(grid=3)) == "g3"
15+
assert str(Axis(annotation=1, tick=2, grid=3)) == "a1f2g3"
16+
17+
assert str(Axis(annotation=True)) == "a"
18+
assert str(Axis(tick=True)) == "f"
19+
assert str(Axis(grid=True)) == "g"
20+
assert str(Axis(annotation=True, tick=True)) == "af"
21+
assert str(Axis(annotation=True, grid=True)) == "ag"
22+
assert str(Axis(tick=True, grid=True)) == "fg"
23+
assert str(Axis(annotation=True, tick=True, grid=True)) == "afg"
24+
25+
26+
def test_params_axis_modifiers():
27+
"""
28+
Test the modifiers of the Axis class.
29+
"""
30+
assert str(Axis(annotation=True, angle=30)) == "a+a30"
31+
assert str(Axis(annotation=True, angle="normal")) == "a+an"
32+
assert str(Axis(annotation=True, angle="parallel")) == "a+ap"
33+
34+
assert str(Axis(annotation=True, skip_edge=True)) == "a+e"
35+
assert str(Axis(annotation=True, skip_edge="lower")) == "a+el"
36+
assert str(Axis(annotation=True, skip_edge="upper")) == "a+eu"
37+
38+
assert str(Axis(annotation=True, fancy=True)) == "a+f"
39+
40+
assert str(Axis(annotation=True, label="My Label")) == "a+lMy Label"
41+
assert str(Axis(annotation=True, hlabel="My HLabel")) == "a+LMy HLabel"
42+
assert str(Axis(annotation=True, alt_label="Alt Label")) == "a+sAlt Label"
43+
assert str(Axis(annotation=True, alt_hlabel="Alt HLabel")) == "a+SAlt HLabel"
44+
45+
axis = Axis(annotation=True, label="My Label", alt_label="My HLabel")
46+
assert str(axis) == "a+lMy Label+sMy HLabel"
47+
48+
assert str(Axis(annotation=True, prefix="$")) == "a+p$"
49+
50+
assert str(Axis(annotation=True, unit="km")) == "a+ukm"
2151

2252

2353
def test_params_axes():
2454
"""
2555
Test the Axes class.
2656
"""
27-
assert (
28-
str(Axes("WSen", title="My Plot Title", fill="lightred"))
29-
== "WSen+glightred+tMy Plot Title"
30-
)
57+
58+
assert str(Axes(axes="WSen")) == "WSen"
59+
assert str(Axes(fill="lightred")) == "+glightred"
60+
assert str(Axes(title="My Plot Title")) == "+tMy Plot Title"
61+
assert str(Axes(subtitle="My Subtitle")) == "+sMy Subtitle"
62+
63+
axes = Axes(axes="WSen", fill="lightred", title="My Plot Title")
64+
assert str(axes) == "WSen+glightred+tMy Plot Title"
65+
66+
67+
def test_params_frame():
68+
"""
69+
Test the Frame class.
70+
"""

0 commit comments

Comments
 (0)