diff --git a/examples/gallery/maps/choropleth_map.py b/examples/gallery/maps/choropleth_map.py index efa3f75f7f6..4c3927c5578 100644 --- a/examples/gallery/maps/choropleth_map.py +++ b/examples/gallery/maps/choropleth_map.py @@ -27,7 +27,7 @@ africa = world[world["CONTINENT"] == "Africa"].copy() fig = pygmt.Figure() -fig.basemap(region=[-19.5, 53, -37.5, 38], projection="M10c", frame="+n") +fig.basemap(region=[-19.5, 53, -37.5, 38], projection="M10c", frame="none") # First, we define the colormap to fill the polygons based on the "POP_EST" column. pygmt.makecpt(cmap="SCM/acton", series=(0, 100), reverse=True) diff --git a/pygmt/alias.py b/pygmt/alias.py index f9aa3f69109..06b5186d07d 100644 --- a/pygmt/alias.py +++ b/pygmt/alias.py @@ -338,7 +338,9 @@ def add_common(self, **kwargs): # noqa: PLR0912 for key, value in kwargs.items(): match key: case "B": - alias = Alias(value, name="frame") + # Mapping frame="none" to '-B+n'. + _value = "+n" if value == "none" else value + alias = Alias(_value, name="frame") case "J": alias = Alias(value, name="projection") case "R": diff --git a/pygmt/helpers/decorators.py b/pygmt/helpers/decorators.py index 8920c0ac408..579cf0c4077 100644 --- a/pygmt/helpers/decorators.py +++ b/pygmt/helpers/decorators.py @@ -90,9 +90,12 @@ that do not match the pattern. Append **i** for case insensitive matching. This does not apply to headers or segment headers.""", "frame": r""" - frame : bool, str, or list - Set map boundary - :doc:`frame and axes attributes `.""", + frame + Set frame and axes attributes for the plot. It can be a bool, a string, or + a list of strings. If ``frame=True``, frame will be drawn with the default + attributes. If ``frame="none"``, no frame will be drawn. A tutorial is + available at :doc:`frame and axes attributes `. + Full documentation is at :gmt-docs:`gmt.html#b-full`.""", "gap": r""" gap : str or list **x**\|\ **y**\|\ **z**\|\ **d**\|\ **X**\|\ **Y**\|\ diff --git a/pygmt/src/basemap.py b/pygmt/src/basemap.py index b795ccfce06..f03dd028b30 100644 --- a/pygmt/src/basemap.py +++ b/pygmt/src/basemap.py @@ -18,7 +18,7 @@ def basemap( # noqa: PLR0913 zscale: float | str | None = None, zsize: float | str | None = None, region: Sequence[float | str] | str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, map_scale: str | None = None, diff --git a/pygmt/src/coast.py b/pygmt/src/coast.py index 31b7d3d7eec..db4fa4050e8 100644 --- a/pygmt/src/coast.py +++ b/pygmt/src/coast.py @@ -30,7 +30,7 @@ def coast( # noqa: PLR0913 box: Box | bool = False, projection: str | None = None, region: Sequence[float | str] | str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, panel: int | Sequence[int] | bool = False, diff --git a/pygmt/src/colorbar.py b/pygmt/src/colorbar.py index a52c8d9336f..b7994f887a1 100644 --- a/pygmt/src/colorbar.py +++ b/pygmt/src/colorbar.py @@ -168,7 +168,7 @@ def colorbar( # noqa: PLR0913 scale: float | None = None, projection: str | None = None, region: Sequence[float | str] | str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, panel: int | Sequence[int] | bool = False, @@ -322,7 +322,8 @@ def colorbar( # noqa: PLR0913 $projection $region frame - Set colorbar boundary frame, labels, and axes attributes. + Set colorbar boundary frame, labels, and axes attributes. If set to ``"none"``, + then no frame will be drawn. $verbose $panel $perspective diff --git a/pygmt/src/contour.py b/pygmt/src/contour.py index ae36b4d8c22..3c7661e97ea 100644 --- a/pygmt/src/contour.py +++ b/pygmt/src/contour.py @@ -40,7 +40,7 @@ def contour( # noqa: PLR0913 no_clip: bool = False, projection: str | None = None, region: Sequence[float | str] | str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, panel: int | Sequence[int] | bool = False, diff --git a/pygmt/src/grdcontour.py b/pygmt/src/grdcontour.py index 0e06f31be81..c2eabc5397b 100644 --- a/pygmt/src/grdcontour.py +++ b/pygmt/src/grdcontour.py @@ -40,7 +40,7 @@ def grdcontour( grid: PathLike | xr.DataArray, projection: str | None = None, region: Sequence[float | str] | str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, panel: int | Sequence[int] | bool = False, diff --git a/pygmt/src/grdimage.py b/pygmt/src/grdimage.py index 8fce5bff0ec..e546bd0f56a 100644 --- a/pygmt/src/grdimage.py +++ b/pygmt/src/grdimage.py @@ -32,7 +32,7 @@ def grdimage( # noqa: PLR0913 no_clip: bool = False, projection: str | None = None, region: Sequence[float | str] | str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, panel: int | Sequence[int] | bool = False, diff --git a/pygmt/src/grdview.py b/pygmt/src/grdview.py index 3e37d1015f9..1a13f4ef6e3 100644 --- a/pygmt/src/grdview.py +++ b/pygmt/src/grdview.py @@ -135,7 +135,7 @@ def grdview( # noqa: PLR0913 zscale: float | str | None = None, zsize: float | str | None = None, region: Sequence[float | str] | str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, panel: int | Sequence[int] | bool = False, diff --git a/pygmt/src/histogram.py b/pygmt/src/histogram.py index c2e55ed7218..71bb1cf8b90 100644 --- a/pygmt/src/histogram.py +++ b/pygmt/src/histogram.py @@ -49,7 +49,7 @@ def histogram( # noqa: PLR0913 bar_offset: float | str | None = None, projection: str | None = None, region: Sequence[float | str] | str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, panel: int | Sequence[int] | bool = False, diff --git a/pygmt/src/image.py b/pygmt/src/image.py index 8d82fe4f568..c37f581d1b0 100644 --- a/pygmt/src/image.py +++ b/pygmt/src/image.py @@ -28,7 +28,7 @@ def image( # noqa: PLR0913 invert: bool = False, projection: str | None = None, region: Sequence[float | str] | str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, panel: int | Sequence[int] | bool = False, diff --git a/pygmt/src/legend.py b/pygmt/src/legend.py index e694234a761..456c08906da 100644 --- a/pygmt/src/legend.py +++ b/pygmt/src/legend.py @@ -27,7 +27,7 @@ def legend( # noqa: PLR0913 scale: float | None = None, projection: str | None = None, region: Sequence[float | str] | str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, panel: int | Sequence[int] | bool = False, diff --git a/pygmt/src/meca.py b/pygmt/src/meca.py index 661082adc74..eb21e88a341 100644 --- a/pygmt/src/meca.py +++ b/pygmt/src/meca.py @@ -148,7 +148,7 @@ def meca( # noqa: PLR0913 event_name: str | Sequence[str] | None = None, no_clip: bool = False, projection: str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, region: Sequence[float | str] | str | None = None, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, diff --git a/pygmt/src/plot.py b/pygmt/src/plot.py index 8f8873bde62..37f76d0a8c4 100644 --- a/pygmt/src/plot.py +++ b/pygmt/src/plot.py @@ -53,7 +53,7 @@ def plot( # noqa: PLR0912, PLR0913 straight_line: bool | Literal["x", "y"] = False, projection: str | None = None, region: Sequence[float | str] | str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, panel: int | Sequence[int] | bool = False, diff --git a/pygmt/src/plot3d.py b/pygmt/src/plot3d.py index c6aa0e93d67..6ad4f31e345 100644 --- a/pygmt/src/plot3d.py +++ b/pygmt/src/plot3d.py @@ -55,7 +55,7 @@ def plot3d( # noqa: PLR0912, PLR0913 zscale: float | str | None = None, zsize: float | str | None = None, region: Sequence[float | str] | str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, panel: int | Sequence[int] | bool = False, diff --git a/pygmt/src/rose.py b/pygmt/src/rose.py index ef819c0685a..e67fcabccbe 100644 --- a/pygmt/src/rose.py +++ b/pygmt/src/rose.py @@ -40,7 +40,7 @@ def rose( # noqa: PLR0913 length=None, azimuth=None, region: Sequence[float | str] | str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, panel: int | Sequence[int] | bool = False, diff --git a/pygmt/src/solar.py b/pygmt/src/solar.py index 4a4ab0dc688..ccaf904fa55 100644 --- a/pygmt/src/solar.py +++ b/pygmt/src/solar.py @@ -23,7 +23,7 @@ def solar( # noqa: PLR0913 pen: str | None = None, projection: str | None = None, region: Sequence[float | str] | str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, panel: int | Sequence[int] | bool = False, diff --git a/pygmt/src/subplot.py b/pygmt/src/subplot.py index 742687b8add..9b54961195d 100644 --- a/pygmt/src/subplot.py +++ b/pygmt/src/subplot.py @@ -145,7 +145,7 @@ def subplot( # noqa: PLR0913 margins: float | str | Sequence[float | str] | None = None, title: str | None = None, projection: str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, region: Sequence[float | str] | str | None = None, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, diff --git a/pygmt/src/ternary.py b/pygmt/src/ternary.py index 127ae54d3a3..3112fbc3344 100644 --- a/pygmt/src/ternary.py +++ b/pygmt/src/ternary.py @@ -20,7 +20,7 @@ def ternary( # noqa: PLR0913 blabel: str | None = None, clabel: str | None = None, region: Sequence[float | str] | str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, panel: int | Sequence[int] | bool = False, diff --git a/pygmt/src/text.py b/pygmt/src/text.py index a82afb4e3c0..8557feab311 100644 --- a/pygmt/src/text.py +++ b/pygmt/src/text.py @@ -47,7 +47,7 @@ def text_( # noqa: PLR0912, PLR0913 no_clip: bool = False, projection: str | None = None, region: Sequence[float | str] | str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, panel: int | Sequence[int] | bool = False, diff --git a/pygmt/src/tilemap.py b/pygmt/src/tilemap.py index 66f7a7216bb..7405c5c7294 100644 --- a/pygmt/src/tilemap.py +++ b/pygmt/src/tilemap.py @@ -31,7 +31,7 @@ def tilemap( # noqa: PLR0913 monochrome: bool = False, no_clip: bool = False, projection: str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, panel: int | Sequence[int] | bool = False, diff --git a/pygmt/src/velo.py b/pygmt/src/velo.py index 346d7e1295e..a07798f2864 100644 --- a/pygmt/src/velo.py +++ b/pygmt/src/velo.py @@ -41,7 +41,7 @@ def velo( # noqa : PLR0913 no_clip: bool = False, projection: str | None = None, region: Sequence[float | str] | str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, panel: int | Sequence[int] | bool = False, diff --git a/pygmt/src/wiggle.py b/pygmt/src/wiggle.py index 603d5339f73..f39305ec0e7 100644 --- a/pygmt/src/wiggle.py +++ b/pygmt/src/wiggle.py @@ -47,7 +47,7 @@ def wiggle( # noqa: PLR0913 negative_fill: str | None = None, projection: str | None = None, region: Sequence[float | str] | str | None = None, - frame: str | Sequence[str] | bool = False, + frame: str | Sequence[str] | Literal["none"] | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, panel: int | Sequence[int] | bool = False, diff --git a/pygmt/tests/baseline/test_basemap_frame_none.png.dvc b/pygmt/tests/baseline/test_basemap_frame_none.png.dvc new file mode 100644 index 00000000000..916fe0405f3 --- /dev/null +++ b/pygmt/tests/baseline/test_basemap_frame_none.png.dvc @@ -0,0 +1,5 @@ +outs: +- md5: fda939936894cb72a785ecf7e1f42488 + size: 7252 + hash: md5 + path: test_basemap_frame_none.png diff --git a/pygmt/tests/test_alias_system.py b/pygmt/tests/test_alias_system.py index f430ded16aa..06952df0f03 100644 --- a/pygmt/tests/test_alias_system.py +++ b/pygmt/tests/test_alias_system.py @@ -23,15 +23,15 @@ def func( A simple function to test the alias system. """ aliasdict = AliasSystem( - R=Alias(region, name="region", sep="/", size=[4, 6]), - B=Alias(frame, name="frame"), U=[ Alias(label, name="label"), Alias(text, name="text", prefix="+t"), Alias(offset, name="offset", prefix="+o", sep="/"), ], ).add_common( + B=frame, J=projection, + R=region, V=verbose, c=panel, ) @@ -100,9 +100,18 @@ def test_alias_system_multiple_aliases_short_form(): func(text="efg", U="efg") +def test_alias_system_common_parameter_frame(): + """ + Test that the alias system works with the 'frame' parameter. + """ + assert func(frame="WSen") == ["-BWSen"] + assert func(frame=["WSen", "xaf", "yaf"]) == ["-BWSen", "-Bxaf", "-Byaf"] + assert func(frame="none") == ["-B+n"] + + def test_alias_system_common_parameter_verbose(): """ - Test that the alias system works with common parameters. + Test that the alias system works with the 'verbose' parameter. """ # Test the verbose parameter. assert func(verbose="quiet") == ["-Vq"] diff --git a/pygmt/tests/test_basemap.py b/pygmt/tests/test_basemap.py index a88f015b0e9..bdd2e6def50 100644 --- a/pygmt/tests/test_basemap.py +++ b/pygmt/tests/test_basemap.py @@ -155,3 +155,17 @@ def test_basemap_frame_sequence_true(): fig = Figure() fig.basemap(region=[0, 10, 0, 10], projection="X10c", frame=[True, "WSen"]) return fig + + +@pytest.mark.mpl_image_compare +def test_basemap_frame_none(): + """ + Test that passing frame="none" works. + """ + fig = Figure() + fig.basemap(region=[0, 5, 0, 2], projection="X5c/2c", frame=True) + fig.colorbar(cmap="google/turbo", frame=True) + fig.shift_origin(xshift=5.5) + fig.basemap(region=[0, 5, 0, 2], projection="X5c/2c", frame="none") + fig.colorbar(cmap="google/turbo", frame="none") + return fig