Skip to content
Open
1 change: 1 addition & 0 deletions doc/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ Class-style Parameters
Box
Frame
Pattern
Perspective
Position

Enums
Expand Down
14 changes: 7 additions & 7 deletions pygmt/helpers/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,22 +277,22 @@
perspective
Select perspective view and set the azimuth and elevation of the viewpoint.

Accepts a single value or a sequence of two or three values: *azimuth*,
(*azimuth*, *elevation*), or (*azimuth*, *elevation*, *zlevel*).
Accepts a :class:`pygmt.params.Perspective` object, a single value
*azimuth*, a sequence of two values (*azimuth*, *elevation*), a sequence of
three values (*azimuth*, *elevation*, *level*).

- *azimuth*: Azimuth angle of the viewpoint in degrees [Default is 180,
i.e., looking from south to north].
- *elevation*: Elevation angle of the viewpoint above the horizon [Default
is 90, i.e., looking straight down at nadir].
- *zlevel*: Z-level at which 2-D elements (e.g., the plot frame) are drawn.
- *level*: Z-level at which 2-D elements (e.g., the plot frame) are drawn.
Only applied when used together with ``zsize`` or ``zscale``. [Default is
at the bottom of the z-axis].
- :class:`pygmt.params.Perspective`: A class-style way for more control over
the perspective parameters.

Alternatively, set ``perspective=True`` to reuse the perspective setting
from the previous plotting method, or pass a string following the full
GMT syntax for finer control (e.g., adding ``+w`` or ``+v`` modifiers to
select an axis location other than the plot origin). See
:gmt-docs:`gmt.html#perspective-full` for details.""",
from the previous plotting method.""",
"projection": r"""
projection
*projcode*\[*projparams*/]\ *width*\|\ *scale*.
Expand Down
1 change: 1 addition & 0 deletions pygmt/params/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
from pygmt.params.box import Box
from pygmt.params.frame import Axis, Frame
from pygmt.params.pattern import Pattern
from pygmt.params.perspective import Perspective
from pygmt.params.position import Position
80 changes: 80 additions & 0 deletions pygmt/params/perspective.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"""
The Perspective class for setting perspective view.
"""

import dataclasses
from typing import Literal

from pygmt.alias import Alias
from pygmt.exceptions import GMTValueError
from pygmt.params.base import BaseParam

__doctest_skip__ = ["Perspective"]


@dataclasses.dataclass(repr=False)
class Perspective(BaseParam):
"""
Class for setting perspective view.

Examples
--------
>>> import pygmt
>>> from pygmt.params import Perspective
>>> fig = pygmt.Figure()
>>> fig.basemap(
... region=[0, 10, 0, 10, 0, 20],
... projection="X3c",
... zsize="3c",
... frame=["xafg", "yafg", "zafg", "wSEnZ"],
... perspective=Perspective(azimuth=135, elevation=40, level=10),
... )
>>> fig.show()
"""

#: Azimuth of the viewpoint in degrees. Default is 180.0 (looking from south to
#: north).
azimuth: float | None = None

#: Elevation angle of the viewpoint in degrees. Default is 90.0 (looking straight
#: down at nadir).
elevation: float | None = None

#: The level at which all 2-D material, like the plot frame, is plotted. Only valid
#: when used together with parameters ``zsize``/``zscale``. Default is at the bottom
#: of the z-axis.
level: float | None = None

#: Set which constant-coordinate plane is used as the plotting plane. Use ``"x"``
#: for the x-plane, ``"y"`` for the y-plane, or ``"z"`` for the horizontal z-plane
# [Default is ``"z"``].
plane: Literal["x", "y", "z"] | None = None

def _validate(self):
"""
Post-initialization processing to validate parameters.
"""
# azimuth is required, so it must be set to the default if not specified.
if self.azimuth is None:
self.azimuth = 180.0 # Default azimuth is 180.0

# Set default elevation if level is set but elevation is not.
if self.level is not None and self.elevation is None:
self.elevation = 90.0 # Default elevation is 90.0

if self.plane is not None and self.plane not in {"x", "y", "z"}:
raise GMTValueError(
self.plane, description="plane", choices=["x", "y", "z"]
)

@property
def _aliases(self):
"""
Aliases for the parameters.
"""
return [
Alias(self.plane, name="plane"),
Alias(self.azimuth, name="azimuth"),
Alias(self.elevation, name="elevation", prefix="/"),
Alias(self.level, name="level", prefix="/"),
]
4 changes: 2 additions & 2 deletions pygmt/src/basemap.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from pygmt.alias import Alias, AliasSystem
from pygmt.clib import Session
from pygmt.helpers import build_arg_list, fmt_docstring, is_given, use_alias
from pygmt.params import Axis, Box, Frame
from pygmt.params import Axis, Box, Frame, Perspective


@fmt_docstring
Expand All @@ -28,7 +28,7 @@ def basemap( # noqa: PLR0913
rose: str | None = None,
box: Box | str | bool = False,
panel: int | Sequence[int] | bool = False,
perspective: float | Sequence[float] | str | bool = False,
perspective: Perspective | float | Sequence[float] | bool = False,
transparency: float | None = None,
**kwargs,
):
Expand Down
4 changes: 2 additions & 2 deletions pygmt/src/coast.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from pygmt.clib import Session
from pygmt.exceptions import GMTParameterError
from pygmt.helpers import args_in_kwargs, build_arg_list, fmt_docstring, use_alias
from pygmt.params import Axis, Box, Frame
from pygmt.params import Axis, Box, Frame, Perspective

__doctest_skip__ = ["coast"]

Expand All @@ -34,7 +34,7 @@ def coast( # noqa: PLR0913
verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"]
| bool = False,
panel: int | Sequence[int] | bool = False,
perspective: float | Sequence[float] | str | bool = False,
perspective: Perspective | float | Sequence[float] | bool = False,
transparency: float | None = None,
**kwargs,
):
Expand Down
4 changes: 2 additions & 2 deletions pygmt/src/colorbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from pygmt.exceptions import GMTValueError
from pygmt.helpers import build_arg_list, fmt_docstring, is_given, use_alias
from pygmt.helpers.utils import is_nonstr_iter
from pygmt.params import Axis, Box, Frame, Position
from pygmt.params import Axis, Box, Frame, Perspective, Position
from pygmt.src._common import _parse_position

__doctest_skip__ = ["colorbar"]
Expand Down Expand Up @@ -277,7 +277,7 @@ def colorbar( # noqa: PLR0913
verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"]
| bool = False,
panel: int | Sequence[int] | bool = False,
perspective: float | Sequence[float] | str | bool = False,
perspective: Perspective | float | Sequence[float] | bool = False,
transparency: float | None = None,
**kwargs,
):
Expand Down
4 changes: 2 additions & 2 deletions pygmt/src/contour.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
is_nonstr_iter,
use_alias,
)
from pygmt.params import Axis, Frame
from pygmt.params import Axis, Frame, Perspective


@fmt_docstring
Expand Down Expand Up @@ -46,7 +46,7 @@ def contour( # noqa: PLR0913
| bool = False,
panel: int | Sequence[int] | bool = False,
incols: int | str | Sequence[int | str] | None = None,
perspective: float | Sequence[float] | str | bool = False,
perspective: Perspective | float | Sequence[float] | bool = False,
transparency: float | None = None,
**kwargs,
):
Expand Down
4 changes: 2 additions & 2 deletions pygmt/src/directional_rose.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from pygmt.alias import Alias, AliasSystem
from pygmt.clib import Session
from pygmt.helpers import build_arg_list, fmt_docstring
from pygmt.params import Box, Position
from pygmt.params import Box, Perspective, Position
from pygmt.src._common import _parse_position

__doctest_skip__ = ["directional_rose"]
Expand All @@ -26,7 +26,7 @@ def directional_rose(
verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"]
| bool = False,
panel: int | Sequence[int] | bool = False,
perspective: float | Sequence[float] | str | bool = False,
perspective: Perspective | float | Sequence[float] | bool = False,
transparency: float | None = None,
):
"""
Expand Down
4 changes: 2 additions & 2 deletions pygmt/src/fill_between.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from pygmt.clib import Session
from pygmt.exceptions import GMTValueError
from pygmt.helpers import build_arg_list, fmt_docstring
from pygmt.params import Axis, Frame
from pygmt.params import Axis, Frame, Perspective

__doctest_skip__ = ["fill_between"]

Expand All @@ -36,7 +36,7 @@ def fill_between( # noqa: PLR0913
verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"]
| bool = False,
panel: int | Sequence[int] | bool = False,
perspective: float | Sequence[float] | str | bool = False,
perspective: Perspective | float | Sequence[float] | bool = False,
transparency: float | None = None,
):
"""
Expand Down
4 changes: 2 additions & 2 deletions pygmt/src/grdcontour.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
kwargs_to_strings,
use_alias,
)
from pygmt.params import Axis, Frame
from pygmt.params import Axis, Frame, Perspective

__doctest_skip__ = ["grdcontour"]

Expand Down Expand Up @@ -45,7 +45,7 @@ def grdcontour(
verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"]
| bool = False,
panel: int | Sequence[int] | bool = False,
perspective: float | Sequence[float] | str | bool = False,
perspective: Perspective | float | Sequence[float] | bool = False,
transparency: float | None = None,
**kwargs,
):
Expand Down
4 changes: 2 additions & 2 deletions pygmt/src/grdimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from pygmt.alias import Alias, AliasSystem
from pygmt.clib import Session
from pygmt.helpers import build_arg_list, fmt_docstring, use_alias
from pygmt.params import Axis, Frame
from pygmt.params import Axis, Frame, Perspective

__doctest_skip__ = ["grdimage"]

Expand All @@ -37,7 +37,7 @@ def grdimage( # noqa: PLR0913
verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"]
| bool = False,
panel: int | Sequence[int] | bool = False,
perspective: float | Sequence[float] | str | bool = False,
perspective: Perspective | float | Sequence[float] | bool = False,
transparency: float | None = None,
cores: int | bool = False,
**kwargs,
Expand Down
4 changes: 2 additions & 2 deletions pygmt/src/grdview.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
is_given,
use_alias,
)
from pygmt.params import Axis, Frame
from pygmt.params import Axis, Frame, Perspective
from pygmt.src.grdinfo import grdinfo

__doctest_skip__ = ["grdview"]
Expand Down Expand Up @@ -148,7 +148,7 @@ def grdview( # noqa: PLR0913
verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"]
| bool = False,
panel: int | Sequence[int] | bool = False,
perspective: float | Sequence[float] | str | bool = False,
perspective: Perspective | float | Sequence[float] | bool = False,
transparency: float | None = None,
**kwargs,
):
Expand Down
4 changes: 2 additions & 2 deletions pygmt/src/histogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
kwargs_to_strings,
use_alias,
)
from pygmt.params import Axis, Frame
from pygmt.params import Axis, Frame, Perspective


@fmt_docstring
Expand Down Expand Up @@ -55,7 +55,7 @@ def histogram( # noqa: PLR0913
| bool = False,
panel: int | Sequence[int] | bool = False,
incols: int | str | Sequence[int | str] | None = None,
perspective: float | Sequence[float] | str | bool = False,
perspective: Perspective | float | Sequence[float] | bool = False,
transparency: float | None = None,
**kwargs,
):
Expand Down
3 changes: 2 additions & 1 deletion pygmt/src/hlines.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import numpy as np
from pygmt.exceptions import GMTValueError
from pygmt.params import Perspective

__doctest_skip__ = ["hlines"]

Expand All @@ -18,7 +19,7 @@ def hlines(
pen: str | None = None,
label: str | None = None,
no_clip: bool = False,
perspective: str | bool | None = None,
perspective: Perspective | float | Sequence[float] | bool | None = None,
):
"""
Plot one or multiple horizontal line(s).
Expand Down
4 changes: 2 additions & 2 deletions pygmt/src/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from pygmt.alias import Alias, AliasSystem
from pygmt.clib import Session
from pygmt.helpers import build_arg_list, fmt_docstring, use_alias
from pygmt.params import Axis, Box, Frame, Position
from pygmt.params import Axis, Box, Frame, Perspective, Position
from pygmt.src._common import _parse_position


Expand All @@ -32,7 +32,7 @@ def image( # noqa: PLR0913
verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"]
| bool = False,
panel: int | Sequence[int] | bool = False,
perspective: float | Sequence[float] | str | bool = False,
perspective: Perspective | float | Sequence[float] | bool = False,
transparency: float | None = None,
**kwargs,
):
Expand Down
4 changes: 2 additions & 2 deletions pygmt/src/legend.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from pygmt.clib import Session
from pygmt.exceptions import GMTTypeError
from pygmt.helpers import build_arg_list, data_kind, fmt_docstring, is_nonstr_iter
from pygmt.params import Axis, Box, Frame, Position
from pygmt.params import Axis, Box, Frame, Perspective, Position
from pygmt.src._common import _parse_position


Expand All @@ -31,7 +31,7 @@ def legend( # noqa: PLR0913
verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"]
| bool = False,
panel: int | Sequence[int] | bool = False,
perspective: float | Sequence[float] | str | bool = False,
perspective: Perspective | float | Sequence[float] | bool = False,
transparency: float | None = None,
**kwargs,
):
Expand Down
4 changes: 2 additions & 2 deletions pygmt/src/logo.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
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.params import Box, Perspective, Position
from pygmt.src._common import _parse_position

__doctest_skip__ = ["logo"]
Expand All @@ -29,7 +29,7 @@ def logo( # noqa: PLR0913
verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"]
| bool = False,
panel: int | Sequence[int] | bool = False,
perspective: float | Sequence[float] | str | bool = False,
perspective: Perspective | float | Sequence[float] | bool = False,
transparency: float | None = None,
**kwargs,
):
Expand Down
4 changes: 2 additions & 2 deletions pygmt/src/magnetic_rose.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
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.params import Box, Perspective, Position
from pygmt.src._common import _parse_position

__doctest_skip__ = ["magnetic_rose"]
Expand All @@ -31,7 +31,7 @@ def magnetic_rose( # noqa: PLR0913
verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"]
| bool = False,
panel: int | Sequence[int] | bool = False,
perspective: float | Sequence[float] | str | bool = False,
perspective: Perspective | float | Sequence[float] | bool = False,
transparency: float | None = None,
):
"""
Expand Down
Loading
Loading