Skip to content

Commit 7667e5c

Browse files
committed
Add Figure.magnetic_rose to plot a magnetic rose on map
1 parent b4a94d7 commit 7667e5c

File tree

6 files changed

+176
-4
lines changed

6 files changed

+176
-4
lines changed

doc/api/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Plotting map elements
3131
Figure.inset
3232
Figure.legend
3333
Figure.logo
34+
Figure.magnetic_rose
3435
Figure.solar
3536
Figure.text
3637
Figure.timestamp

pygmt/figure.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ def _repr_html_(self) -> str:
422422
inset,
423423
legend,
424424
logo,
425+
magnetic_rose,
425426
meca,
426427
plot,
427428
plot3d,

pygmt/src/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from pygmt.src.inset import inset
3636
from pygmt.src.legend import legend
3737
from pygmt.src.logo import logo
38+
from pygmt.src.magnetic_rose import magnetic_rose
3839
from pygmt.src.makecpt import makecpt
3940
from pygmt.src.meca import meca
4041
from pygmt.src.nearneighbor import nearneighbor

pygmt/src/magnetic_rose.py

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
"""
2+
magnetic_rose - Add a map magnetic rose.
3+
"""
4+
5+
from collections.abc import Sequence
6+
from typing import Literal
7+
8+
from pygmt.alias import Alias, AliasSystem
9+
from pygmt.clib import Session
10+
from pygmt.exceptions import GMTInvalidInput
11+
from pygmt.helpers import build_arg_list
12+
from pygmt.params import Box, Position
13+
14+
15+
def magnetic_rose( # noqa: PLR0913
16+
self,
17+
position: Position | None = None,
18+
width: float | str | None = None,
19+
labels: Sequence[str] | bool = False,
20+
outer_pen: str | bool = False,
21+
inner_pen: str | bool = False,
22+
declination: float | None = None,
23+
declination_label: str | None = None,
24+
intervals: Sequence[float] | None = None,
25+
box: Box | bool = False,
26+
perspective: str | bool = False,
27+
verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"]
28+
| bool = False,
29+
transparency: float | None = None,
30+
):
31+
"""
32+
Add a magnetic rose to the map.
33+
34+
The magnetic rose is plotted at the location defined by the reference point
35+
(specified by the **position** and *position_type** parameters) and anchor point
36+
(specified by the **anchor** and **anchor_offset** parameters). Refer to
37+
:doc:`/techref/reference_anchor_points` for details about the positioning.
38+
39+
Parameters
40+
----------
41+
position
42+
Specify the location of the magnetic rose on a map. See
43+
:class:`pygmt.params.Position` for details.
44+
width
45+
Width of the rose in plot coordinates (append **i** (inch), **cm**
46+
(centimeters), or **p** (points)), or append % for a size in percentage of map
47+
width [Default is 15 %].
48+
labels
49+
A sequence of four strings to label the cardinal points W,E,S,N. Use an empty
50+
string to skip a specific label. If the north label is ``"*"``, then a north
51+
star is plotted instead of the north label. If set to ``True``, use the default
52+
labels ``["W", "E", "S", "N"]``.
53+
outer_pen
54+
Draw the outer circle of the magnetic rose, using the given pen attributes.
55+
inner_pen
56+
Draw the inner circle of the magnetic rose, using the given pen attributes.
57+
declination
58+
Magnetic declination in degrees. By default, only a geographic north is plotted.
59+
With this parameter set, a magnetic north is also plotted. A magnetic compass
60+
needle is drawn inside the rose to indicate the direction to magnetic north.
61+
declination_label
62+
Label for the magnetic compass needle. Default is to format a label based on
63+
**declination**. To bypass the label, set to ``"-"``.
64+
intervals
65+
Specify the annotation and tick intervals for the geographic and magnetic
66+
directions. It can be a seqeunce of three or six values. If three values are
67+
given, they are used for both geographic and magnetic directions. If six values
68+
are given, the first three are used for geographic directions and the last three
69+
for magnetic directions. Default is ``(30, 5, 1)``. **Note**: If
70+
:gmt-term:`MAP_EMBELLISHMENT_MODE` is ``"auto"`` and the compass size is smaller
71+
than 2.5 cm then the interval defaults are reset to ``(90,30, 3, 45, 15, 3)``.
72+
box
73+
Draw a background box behind the magnetic rose. If set to ``True``, a simple
74+
rectangular box is drawn using :gmt-term:`MAP_FRAME_PEN`. To customize the box
75+
appearance, pass a :class:`pygmt.params.Box` object to control style, fill, pen,
76+
and other box properties.
77+
$perspective
78+
$verbose
79+
$transparency
80+
81+
Examples
82+
--------
83+
>>> import pygmt
84+
>>> from pygmt.params import Position
85+
>>> fig = pygmt.Figure()
86+
>>> fig.basemap(region=[-10, 10, -10, 10], projection="M15c", frame=True)
87+
>>> fig.magnetic_rose(
88+
... position=Position((-5, -5), cstype="mapcoords"),
89+
... width="4c",
90+
... labels=["W", "E", "S", "*"],
91+
... intervals=(45, 15, 3, 60, 20, 4),
92+
... outer_pen="1p,red",
93+
... inner_pen="1p,blue",
94+
... declination=11.5,
95+
... declination_label="11.5°E",
96+
... )
97+
>>> fig.show()
98+
"""
99+
self._activate_figure()
100+
101+
if declination_label is not None and declination is None:
102+
msg = "Parameter 'declination' must be set when 'declination_label' is set."
103+
raise GMTInvalidInput(msg)
104+
105+
aliasdict = AliasSystem(
106+
F=Alias(box, name="box"),
107+
Tm=[
108+
Alias(position, name="position"),
109+
Alias(width, name="width", prefix="+w"),
110+
Alias(labels, name="labels", prefix="+l", sep=",", size=4),
111+
Alias(outer_pen, name="outer_pen", prefix="+p"),
112+
Alias(inner_pen, name="inner_pen", prefix="+i"),
113+
Alias(declination, name="declination", prefix="+d"),
114+
Alias(declination_label, name="declination_label", prefix="/"),
115+
Alias(intervals, name="intervals", prefix="+t", sep="/", size=(3, 6)),
116+
],
117+
).add_common(
118+
V=verbose,
119+
p=perspective,
120+
t=transparency,
121+
)
122+
123+
with Session() as lib:
124+
lib.call_module(module="basemap", args=build_arg_list(aliasdict))

pygmt/tests/test_config.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,21 @@ def test_config_font_one():
4747
"""
4848
fig = Figure()
4949
with config(FONT="8p,red"):
50-
fig.basemap(region=[0, 9, 0, 9], projection="C3/3/9c", compass="jTL+w3c+d4.5+l")
51-
fig.basemap(compass="jBR+w3.5c+d-4.5+l")
50+
fig.basemap(region=[0, 9, 0, 9], projection="C3/3/9c", frame="+n")
51+
fig.magnetic_rose(
52+
position_type="inside",
53+
position="TL",
54+
width="3c",
55+
declination=4.5,
56+
labels=True,
57+
)
58+
fig.magnetic_rose(
59+
position_type="inside",
60+
position="BR",
61+
width="3.5c",
62+
declination=-4.5,
63+
labels=True,
64+
)
5265
return fig
5366

5467

@@ -60,8 +73,21 @@ def test_config_font_annot():
6073
"""
6174
fig = Figure()
6275
with config(FONT_ANNOT="6p,red"):
63-
fig.basemap(region=[0, 9, 0, 9], projection="C3/3/9c", compass="jTL+w3c+d4.5")
64-
fig.basemap(compass="jBR+w3.5c+d-4.5")
76+
fig.basemap(region=[0, 9, 0, 9], projection="C3/3/9c", frame="+n")
77+
fig.magnetic_rose(
78+
position_type="inside",
79+
position="TL",
80+
width="3c",
81+
declination=4.5,
82+
labels=True,
83+
)
84+
fig.magnetic_rose(
85+
position_type="inside",
86+
position="BR",
87+
width="3.5c",
88+
declination=-4.5,
89+
labels=True,
90+
)
6591
return fig
6692

6793

pygmt/tests/test_magnetic_rose.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"""
2+
Test Figure.magnetic_rose.
3+
"""
4+
5+
import pytest
6+
from pygmt import Figure
7+
8+
9+
@pytest.mark.mpl_image_compare(filename="test_basemap_compass.png")
10+
def test_magnetic_rose():
11+
"""
12+
Create a map with a compass. Modified from the test_basemap_compass test.
13+
"""
14+
fig = Figure()
15+
fig.basemap(region=[127.5, 128.5, 26, 27], projection="H15c", frame=True)
16+
fig.magnetic_rose(
17+
position_type="inside", position="MC", width="5c", declination=11.5
18+
)
19+
return fig

0 commit comments

Comments
 (0)