From 523440073d39d8f2e65a41e129bb75596f44868e Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sun, 19 Apr 2026 10:54:13 +0800 Subject: [PATCH 1/7] Add 3-D Frame modifiers --- pygmt/params/frame.py | 35 +++++++++++++++++++++++++++++++- pygmt/tests/test_params_frame.py | 22 ++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/pygmt/params/frame.py b/pygmt/params/frame.py index 2381ede9670..b5a78335f0e 100644 --- a/pygmt/params/frame.py +++ b/pygmt/params/frame.py @@ -102,17 +102,27 @@ class _Axes(BaseParam): """ axes: str | None = None + box: bool = False title: str | None = None subtitle: str | None = None fill: str | None = None + wall_pen: str | bool = False + yzfill: str | None = None + xzfill: str | None = None + xyfill: str | None = None @property def _aliases(self): return [ Alias(self.axes, name="axes"), + Alias(self.box, name="box", prefix="+b"), Alias(self.fill, name="fill", prefix="+g"), Alias(self.title, name="title", prefix="+t"), Alias(self.subtitle, name="subtitle", prefix="+s"), + Alias(self.wall_pen, name="wall_pen", prefix="+w"), + Alias(self.yzfill, name="yzfill", prefix="+x"), + Alias(self.xzfill, name="xzfill", prefix="+y"), + Alias(self.xyfill, name="xyfill", prefix="+z"), ] @@ -209,6 +219,21 @@ class Frame(BaseParam): #: fill]. fill: str | None = None + #: Draw the foreground lines of a 3-D box. + box: bool = False + + #: Pen for the outlines of the side walls in a 3-D plot. + wall_pen: str | bool = False + + #: Fill for the yz-plane (the plane normal to the x-axis) in a 3-D plot. + yzfill: str | None = None + + #: Fill for the xz-plane (the plane normal to the y-axis) in a 3-D plot. + xzfill: str | None = None + + #: Fill for the xy-plane (the plane normal to the z-axis) in a 3-D plot. + xyfill: str | None = None + #: Specify the attributes for axes by an :class:`Axis` object. #: #: The attributes for x and y axes can be specified in two ways: (1) specifying the @@ -260,7 +285,15 @@ def _aliases(self): # _Axes() maps to an empty string, which becomes '-B' without arguments and is # invalid when combined with individual axis settings (e.g., '-B -Bxaf -Byaf'). frame_settings = _Axes( - axes=self.axes, title=self.title, subtitle=self.subtitle, fill=self.fill + axes=self.axes, + box=self.box, + title=self.title, + subtitle=self.subtitle, + fill=self.fill, + wall_pen=self.wall_pen, + yzfill=self.yzfill, + xzfill=self.xzfill, + xyfill=self.xyfill, ) has_secondary_xy_axis = any([self.axis2, self.xaxis2, self.yaxis2]) return [ diff --git a/pygmt/tests/test_params_frame.py b/pygmt/tests/test_params_frame.py index a90952990f9..5a8f78db397 100644 --- a/pygmt/tests/test_params_frame.py +++ b/pygmt/tests/test_params_frame.py @@ -42,6 +42,28 @@ def test_params_frame_only(): frame = Frame(axes="WSEN", title="My Title", subtitle="My Subtitle", fill="red") assert str(frame) == "WSEN+gred+tMy Title+sMy Subtitle" + frame = Frame(axes="WSrtZ", box=True, wall_pen="1p,red") + assert str(frame) == "WSrtZ+b+w1p,red" + + frame = Frame(axes="WSrtZ", yzfill="red", xzfill="green", xyfill="blue") + assert str(frame) == "WSrtZ+xred+ygreen+zblue" + + frame = Frame( + axes="WSrtZ", + box=True, + title="My Title", + subtitle="My Subtitle", + fill="gray", + wall_pen="0.5p,black", + yzfill="red", + xzfill="green", + xyfill="blue", + ) + assert ( + str(frame) + == "WSrtZ+b+ggray+tMy Title+sMy Subtitle+w0.5p,black+xred+ygreen+zblue" + ) + def test_params_frame_axis(): """ From e7fe3918111686a4addb8bd4bf452415c4658ae4 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sun, 19 Apr 2026 11:09:08 +0800 Subject: [PATCH 2/7] Improve docstrings and simplify tests --- pygmt/params/frame.py | 13 +++++++------ pygmt/tests/test_params_frame.py | 6 +----- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/pygmt/params/frame.py b/pygmt/params/frame.py index b5a78335f0e..06faf0bdf95 100644 --- a/pygmt/params/frame.py +++ b/pygmt/params/frame.py @@ -115,10 +115,10 @@ class _Axes(BaseParam): def _aliases(self): return [ Alias(self.axes, name="axes"), - Alias(self.box, name="box", prefix="+b"), Alias(self.fill, name="fill", prefix="+g"), Alias(self.title, name="title", prefix="+t"), Alias(self.subtitle, name="subtitle", prefix="+s"), + Alias(self.box, name="box", prefix="+b"), Alias(self.wall_pen, name="wall_pen", prefix="+w"), Alias(self.yzfill, name="yzfill", prefix="+x"), Alias(self.xzfill, name="xzfill", prefix="+y"), @@ -219,19 +219,20 @@ class Frame(BaseParam): #: fill]. fill: str | None = None - #: Draw the foreground lines of a 3-D box. + #: Draw the foreground lines of a 3-D box. [For 3-D plots only] box: bool = False - #: Pen for the outlines of the side walls in a 3-D plot. + #: Draw the outlines of the x-z and y-z planes by the specified pen attributes. + #: If ``True``, use the default pen. [For 3-D plots only] wall_pen: str | bool = False - #: Fill for the yz-plane (the plane normal to the x-axis) in a 3-D plot. + #: Fill for the yz-plane (the plane normal to the x-axis). [For 3-D plots only] yzfill: str | None = None - #: Fill for the xz-plane (the plane normal to the y-axis) in a 3-D plot. + #: Fill for the xz-plane (the plane normal to the y-axis). [For 3-D plots only] xzfill: str | None = None - #: Fill for the xy-plane (the plane normal to the z-axis) in a 3-D plot. + #: Fill for the xy-plane (the plane normal to the z-axis). [For 3-D plots only] xyfill: str | None = None #: Specify the attributes for axes by an :class:`Axis` object. diff --git a/pygmt/tests/test_params_frame.py b/pygmt/tests/test_params_frame.py index 5a8f78db397..af0e3b7ce39 100644 --- a/pygmt/tests/test_params_frame.py +++ b/pygmt/tests/test_params_frame.py @@ -52,17 +52,13 @@ def test_params_frame_only(): axes="WSrtZ", box=True, title="My Title", - subtitle="My Subtitle", fill="gray", wall_pen="0.5p,black", yzfill="red", xzfill="green", xyfill="blue", ) - assert ( - str(frame) - == "WSrtZ+b+ggray+tMy Title+sMy Subtitle+w0.5p,black+xred+ygreen+zblue" - ) + assert str(frame) == "WSrtZ+b+ggray+tMy Title+w0.5p,black+xred+ygreen+zblue" def test_params_frame_axis(): From eed7a646501ce51c7fe06875b59ebf1f38404f7a Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sun, 19 Apr 2026 11:24:51 +0800 Subject: [PATCH 3/7] Fix one test --- pygmt/tests/test_params_frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/tests/test_params_frame.py b/pygmt/tests/test_params_frame.py index af0e3b7ce39..5afc8eb9ad3 100644 --- a/pygmt/tests/test_params_frame.py +++ b/pygmt/tests/test_params_frame.py @@ -58,7 +58,7 @@ def test_params_frame_only(): xzfill="green", xyfill="blue", ) - assert str(frame) == "WSrtZ+b+ggray+tMy Title+w0.5p,black+xred+ygreen+zblue" + assert str(frame) == "WSrtZ+ggray+tMy Title+b+w0.5p,black+xred+ygreen+zblue" def test_params_frame_axis(): From 4139d518d5bd812214772aee2deb7733f9de2f09 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sun, 19 Apr 2026 11:25:31 +0800 Subject: [PATCH 4/7] Fix the order --- pygmt/params/frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/params/frame.py b/pygmt/params/frame.py index 06faf0bdf95..deb78bf3392 100644 --- a/pygmt/params/frame.py +++ b/pygmt/params/frame.py @@ -102,10 +102,10 @@ class _Axes(BaseParam): """ axes: str | None = None - box: bool = False title: str | None = None subtitle: str | None = None fill: str | None = None + box: bool = False wall_pen: str | bool = False yzfill: str | None = None xzfill: str | None = None From d749ab7cbe8d6e46a6ea97b7455b266d0645f2de Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sun, 19 Apr 2026 11:32:03 +0800 Subject: [PATCH 5/7] Fix the oder --- pygmt/params/frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/params/frame.py b/pygmt/params/frame.py index deb78bf3392..351831011bc 100644 --- a/pygmt/params/frame.py +++ b/pygmt/params/frame.py @@ -287,10 +287,10 @@ def _aliases(self): # invalid when combined with individual axis settings (e.g., '-B -Bxaf -Byaf'). frame_settings = _Axes( axes=self.axes, - box=self.box, title=self.title, subtitle=self.subtitle, fill=self.fill, + box=self.box, wall_pen=self.wall_pen, yzfill=self.yzfill, xzfill=self.xzfill, From 48c5507f0dbd7cad789b6c074f2c756040076a49 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sat, 2 May 2026 12:30:04 +0800 Subject: [PATCH 6/7] Clarify that fill can be overridden by xyfill/yzfill/xzfill --- pygmt/params/frame.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pygmt/params/frame.py b/pygmt/params/frame.py index 351831011bc..29ce88b49f9 100644 --- a/pygmt/params/frame.py +++ b/pygmt/params/frame.py @@ -216,7 +216,8 @@ class Frame(BaseParam): subtitle: str | None = None #: Fill for the interior of the frame with a color or a pattern [Default is no - #: fill]. + #: fill]. For 3-D plots, it sets the fill for the xy-, yz-, and xz-planes, but can + #: be overridden by ``xyfill``, ``yzfill``, and ``xzfill``. fill: str | None = None #: Draw the foreground lines of a 3-D box. [For 3-D plots only] From 20bc06006e5a38d6cd683f61d6684e3241748bf9 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sat, 2 May 2026 13:19:28 +0800 Subject: [PATCH 7/7] Fix styling --- pygmt/params/frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/params/frame.py b/pygmt/params/frame.py index 29ce88b49f9..9f34a3164f5 100644 --- a/pygmt/params/frame.py +++ b/pygmt/params/frame.py @@ -216,7 +216,7 @@ class Frame(BaseParam): subtitle: str | None = None #: Fill for the interior of the frame with a color or a pattern [Default is no - #: fill]. For 3-D plots, it sets the fill for the xy-, yz-, and xz-planes, but can + #: fill]. For 3-D plots, it sets the fill for the xy-, yz-, and xz-planes, but can #: be overridden by ``xyfill``, ``yzfill``, and ``xzfill``. fill: str | None = None