diff --git a/pygmt/src/directional_rose.py b/pygmt/src/directional_rose.py index 8a964c10a44..9407e22c5a4 100644 --- a/pygmt/src/directional_rose.py +++ b/pygmt/src/directional_rose.py @@ -8,6 +8,7 @@ from pygmt._typing import AnchorCode from pygmt.alias import Alias, AliasSystem from pygmt.clib import Session +from pygmt.exceptions import GMTParameterError from pygmt.helpers import build_arg_list, fmt_docstring from pygmt.params import Box, Position from pygmt.src._common import _parse_position @@ -22,6 +23,7 @@ def directional_rose( width: float | str | None = None, fancy: Literal[1, 2, 3] | bool = False, labels: Sequence[str] | bool = False, + upright_labels: bool = False, box: Box | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, @@ -63,6 +65,10 @@ def directional_rose( string to skip a specific label. If set to ``True``, default labels are used (``["W", "E", "S", "N"]`` for a fancy rose and ``["", "", "", "N"]`` for a simple rose). + upright_labels + Force the labels to be upright (more readable from the south) if the projection + has extensive rotation of the directions. Requires ``fancy`` and ``labels`` + to be set. box Draw a background box behind the directional rose. If set to ``True``, a simple rectangular box is drawn using :gmt-term:`MAP_FRAME_PEN`. To customize the box @@ -84,13 +90,19 @@ def directional_rose( # Set the default position to "TR" to be consistent with the behavior in GMT 6.7.0 position = _parse_position(position, default=Position("TR", cstype="inside")) + if upright_labels and not (fancy and labels): + raise GMTParameterError( + required=["fancy", "labels"], + reason="Both are required when 'upright_labels' is set.", + ) + aliasdict = AliasSystem( F=Alias(box, name="box"), Td=[ Alias(position, name="position"), Alias(width, name="width", prefix="+w"), - Alias(fancy, name="fancy", prefix="+f"), Alias(labels, name="labels", prefix="+l", sep=",", size=4), + Alias(fancy, name="fancy", prefix="+F" if upright_labels else "+f"), ], ).add_common( V=verbose, diff --git a/pygmt/tests/baseline/test_directional_rose_upright_labels.png b/pygmt/tests/baseline/test_directional_rose_upright_labels.png new file mode 100644 index 00000000000..b87af3f0e29 --- /dev/null +++ b/pygmt/tests/baseline/test_directional_rose_upright_labels.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:20e89f8b0f308bdf1478942814fc0ad9edec05ae86e289710e374d076d28e45e +size 30669 diff --git a/pygmt/tests/test_directional_rose.py b/pygmt/tests/test_directional_rose.py index a6a76dec7be..64e157dd835 100644 --- a/pygmt/tests/test_directional_rose.py +++ b/pygmt/tests/test_directional_rose.py @@ -4,6 +4,7 @@ import pytest from pygmt import Figure +from pygmt.exceptions import GMTParameterError from pygmt.params import Position @@ -43,3 +44,36 @@ def test_directional_rose_complex(): fancy=2, ) return fig + + +@pytest.mark.mpl_image_compare +def test_directional_rose_upright_labels(): + """ + Test the Figure.directional_rose method with upright labels. + + The rose is placed where the map is rotated by more than 90 degrees, so that the + labels would otherwise be upside down. + """ + fig = Figure() + fig.basemap(region=[-180, 180, 60, 90], projection="S0/90/6c", frame=True) + fig.directional_rose(position="TC", width=2, fancy=1, labels=True) + fig.shift_origin(xshift="w+1") + fig.basemap(region=[-180, 180, 60, 90], projection="S0/90/6c", frame=True) + fig.directional_rose( + position="TC", width=2, fancy=1, labels=True, upright_labels=True + ) + return fig + + +def test_directional_rose_upright_labels_fails(): + """ + Test that upright_labels requires both fancy and labels to be set. + """ + fig = Figure() + fig.basemap(region=[0, 80, 0, 30], projection="M10c", frame=True) + with pytest.raises(GMTParameterError): + fig.directional_rose(upright_labels=True) + with pytest.raises(GMTParameterError): + fig.directional_rose(upright_labels=True, fancy=1) + with pytest.raises(GMTParameterError): + fig.directional_rose(upright_labels=True, labels=["W", "E", "S", "N"])