diff --git a/examples/gallery/images/image.py b/examples/gallery/images/image.py index 49f0fe757fa..f3759ce4e5c 100644 --- a/examples/gallery/images/image.py +++ b/examples/gallery/images/image.py @@ -22,7 +22,10 @@ # a rectangular border around it fig.image( imagefile="https://oceania.generic-mapping-tools.org/cache/needle.jpg", - position="g1/1+w8c+jCM", + position_type="mapcoords", + position=(1, 1), + width="8c", + anchor="CM", box=True, ) diff --git a/pygmt/src/image.py b/pygmt/src/image.py index f6fdfa71950..70ebfc0d0ea 100644 --- a/pygmt/src/image.py +++ b/pygmt/src/image.py @@ -2,9 +2,10 @@ image - Plot raster or EPS images. """ +from collections.abc import Sequence from typing import Literal -from pygmt._typing import PathLike +from pygmt._typing import AnchorCode, PathLike from pygmt.alias import Alias, AliasSystem from pygmt.clib import Session from pygmt.helpers import build_arg_list, fmt_docstring, kwargs_to_strings, use_alias @@ -12,11 +13,21 @@ @fmt_docstring -@use_alias(D="position", G="bitcolor", M="monochrome", R="region", p="perspective") +@use_alias(G="bitcolor", M="monochrome", R="region", p="perspective") @kwargs_to_strings(R="sequence", p="sequence") -def image( +def image( # noqa: PLR0913 self, imagefile: PathLike, + position: Sequence[str | float] | AnchorCode | None = None, + position_type: Literal[ + "mapcoords", "boxcoords", "plotcoords", "inside", "outside" + ] = "plotcoords", + anchor: AnchorCode | None = None, + anchor_offset: Sequence[float | str] | None = None, + height: float | str | None = None, + width: float | str | None = None, + replicate: int | tuple[int, int] | None = None, + dpi: float | str | None = None, projection=None, box: Box | bool = False, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] @@ -28,12 +39,12 @@ def image( r""" Plot raster or EPS images. - Reads an Encapsulated PostScript file or a raster image file and plots - it on a map. + Reads an Encapsulated PostScript file or a raster image file and plot it on a map. Full GMT docs at :gmt-docs:`image.html`. {aliases} + - D = position/position_type/anchor/anchor_offset/width/height/replicate/dpi - F = box - J = projection - V = verbose @@ -50,11 +61,56 @@ def image( then only EPS files are supported. {projection} {region} - position : str - [**g**\|\ **j**\|\ **J**\|\ **n**\|\ **x**]\ *refpoint*\ **+r**\ *dpi*\ - **+w**\ [**-**]\ *width*\ [/*height*]\ [**+j**\ *justify*]\ - [**+n**\ *nx*\ [/*ny*]]\ [**+o**\ *dx*\ [/*dy*]]. - Set reference point on the map for the image. + position/position_type + Specify the reference point on the plot for the image. The method of defining + the the reference point is controlled by **position_type**, and the exact + location is set by **position**. + + The **position_type** parameter can take one of the following values: + + - ``"mapcoords"``: **position** is specified as (*longitude*, *latitude*) in map + coordinates. Example: (120, -45) places the reference point at 120°E, 45°S. + - ``"boxcoords"``: **position** is specified as (*nx*, *ny*) in normalized + coordinates, i.e., fractional values between 0 and 1 along the x- and y-axes. + Example: (0, 0) corresponds to the lower-left corner, and (1, 1) to the + upper-right corner of the plot bounding box. + - ``"plotcoords"``: **position** is specified as (*x*, *y*) in plot coordinates, + i.e., distances from the lower-left plot origin given in inches, centimeters, + or points. Example: ("1c", "2c") places the reference point 1 cm to the right + and 2 cm above the plot origin. + - ``"inside"`` or ``"outside"``: **position** is one of the nine + :doc:two-character justification codes , + indicating a specific location relative to the plot bounding box. Example: + ``"TL"`` places the reference point at the top-left corner, either inside or + outside the bounding box. + anchor + Specify the anchor point of the image, using one of the + :doc:`2-character justification codes `. + The default value depends on **position_type**. + + - ``position_type="inside"``: **anchor** defaults to the same as **position**. + - ``position_type="outside"``: **anchor** defaults to the mirror opposite of + **position**. + - Otherwise, **anchor** defaults to ``"MC"`` (middle center). + anchor_offset + Specifies an offset for the anchor point as *offset* or + (*offset_x*, *offset_y*). If a single value *offset* is given, both *offset_x* + and *offset_y* are set to *offset*. + dpi + Specify dpi to set the dpi of the image in dots per inch, or append **c** to + indicate this is dots per cm. + replicate + *nx* or (*nx*, *ny*). + Replicate the (scaled) image *nx* times in the horizontal direction, and *ny* + times in the vertical direction. If a single integer *nx* is given, *ny* = *nx*. + [Default is (1, 1)]. + width/height + Width (and height) of the image in plot coordinates (inches, cm, etc.). If + **height** (or **width**) is set to 0, then the original aspect ratio of the + image is maintained. If **width** (or **height**) is negative, the absolute + value is used to interpolate image to the device resolution using the PostScript + image operator. If neither dimensions nor dpi are set then revert to the default + dpi [:gmt-term:`GMT_GRAPHICS_DPU`]. box Draw a background box behind the image. If set to ``True``, a simple rectangular box is drawn using :gmt-term:`MAP_FRAME_PEN`. To customize the box appearance, @@ -76,9 +132,29 @@ def image( {perspective} {transparency} """ + self._activate_figure() + _dimension = (width, height) if height is not None else width + + # Mapping position_type to GMT single-letter code. + _position_type = { + "mapcoords": "g", + "boxcoords": "n", + "plotcoords": "x", + "inside": "j", + "outside": "J", + }[position_type] + aliasdict = AliasSystem( + D=[ + Alias(position, name="position", sep="/", size=2, prefix=_position_type), + Alias(anchor, name="anchor", prefix="+j"), + Alias(anchor_offset, name="anchor_offset", prefix="+o", sep="/", size=2), + Alias(_dimension, name="width/height", prefix="+w"), + Alias(replicate, name="replicate", prefix="+n", sep="/", size=2), + Alias(dpi, name="dpi", prefix="+r"), + ], F=Alias(box, name="box"), ).add_common( J=projection, diff --git a/pygmt/tests/test_image.py b/pygmt/tests/test_image.py index e69a8d71938..d26aedd21ec 100644 --- a/pygmt/tests/test_image.py +++ b/pygmt/tests/test_image.py @@ -13,5 +13,11 @@ def test_image(): Place images on map. """ fig = Figure() - fig.image(imagefile="@circuit.png", position="x0/0+w2c", box=Box(pen="thin,blue")) + fig.image( + imagefile="@circuit.png", + position=(0, 0), + position_type="plotcoords", + width="2c", + box=Box(pen="thin,blue"), + ) return fig