From 3b76fa96cb5cc2360d46f35911aa513299b74277 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sun, 10 Aug 2025 20:49:23 +0800 Subject: [PATCH 1/4] Figure.image: Refactor using the new alias system --- pygmt/src/image.py | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/pygmt/src/image.py b/pygmt/src/image.py index 57e7d2cf6ae..43788bb167a 100644 --- a/pygmt/src/image.py +++ b/pygmt/src/image.py @@ -2,7 +2,10 @@ image - Plot raster or EPS images. """ -from pygmt._typing import PathLike +from collections.abc import Sequence +from typing import Literal + +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 @@ -21,7 +24,21 @@ t="transparency", ) @kwargs_to_strings(R="sequence", c="sequence_comma", p="sequence") -def image(self, imagefile: PathLike, projection=None, **kwargs): +def image( + self, + imagefile: PathLike, + position: Sequence[float | str] | AnchorCode, + projection=None, + position_type: Literal[ + "mapcoords", "boxcoords", "plotcoords", "inside", "outside" + ] = "mapcoords", + width=None, + height=None, + replicate=None, + dpi=None, + anchor_offset=None, + **kwargs, +): r""" Plot raster or EPS images. @@ -69,10 +86,31 @@ def image(self, imagefile: PathLike, projection=None, **kwargs): {perspective} {transparency} """ + self._activate_figure() + _dimension = (width, height) if height is not None else width + aliasdict = AliasSystem( J=Alias(projection, name="projection"), + D=[ + Alias( + position_type, + name="position_type", + mapping={ + "mapcoords": "g", + "boxcoords": "n", + "plotcoords": "x", + "inside": "j", + "outside": "J", + }, + ), + Alias(position, name="position", 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"), + Alias(anchor_offset, name="anchor_offset", prefix="+o", sep="/", size=2), + ], ).merge(kwargs) with Session() as lib: From f7f491aea141f860443bc596077ca718082af8bb Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sat, 6 Sep 2025 23:46:59 +0800 Subject: [PATCH 2/4] Reformat --- pygmt/src/image.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/pygmt/src/image.py b/pygmt/src/image.py index 43697fd0be4..d480e3049a8 100644 --- a/pygmt/src/image.py +++ b/pygmt/src/image.py @@ -12,13 +12,7 @@ @fmt_docstring -@use_alias( - F="box", - G="bitcolor", - M="monochrome", - R="region", - p="perspective", -) +@use_alias(F="box", G="bitcolor", M="monochrome", R="region", p="perspective") @kwargs_to_strings(R="sequence", p="sequence") def image( # noqa: PLR0913 self, From e5ab4d919319e737e73817180cb11934d0d7d1d5 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Fri, 12 Sep 2025 13:03:40 +0800 Subject: [PATCH 3/4] Update examples and tests --- examples/gallery/images/image.py | 5 +- pygmt/src/image.py | 78 ++++++++++++++++---------------- pygmt/tests/test_image.py | 8 +++- 3 files changed, 49 insertions(+), 42 deletions(-) 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 d480e3049a8..113133941f7 100644 --- a/pygmt/src/image.py +++ b/pygmt/src/image.py @@ -17,17 +17,17 @@ def image( # noqa: PLR0913 self, imagefile: PathLike, - projection=None, - position: Sequence[float | str] | AnchorCode | None = None, + 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, - width: 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, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | bool = False, panel: int | tuple[int, int] | bool = False, @@ -37,8 +37,7 @@ def image( # noqa: PLR0913 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`. @@ -60,39 +59,40 @@ def image( # noqa: PLR0913 {projection} {region} position/position_type - Specify the reference point on the map for the directional rose. The reference - point can be specified in five different ways, which is selected by the - **position_type** parameter. The actual reference point is then given by the - coordinates or code specified by the **position** parameter. - - The **position_type** parameter can be one of the following: - - - ``"mapcoords"``: **position** is given as (*longitude*, *latitude*) in map - coordinates. - - ``"boxcoords"``: **position** is given as (*nx*, *ny*) in normalized - coordinates, i.e., fractional coordinates between 0 and 1 in both the x and y - directions. For example, (0, 0) is the lower-left corner and (1, 1) is the + 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 given as (x, y) in plot coordinates, i.e., - the distances in inches, centimeters, or points from the lower left plot - origin. + - ``"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:`2-character justification codes `, meaning - placing the reference point at specific locations, either inside or outside - the plot bounding box. + :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 - Anchor point of the directional rose, specified by one of the + Specify the anchor point of the image, using one of the :doc:`2-character justification codes `. - The default value depends on the **position_type** parameter. + 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 - *offset* or (*offset_x*, *offset_y*). - Offset the anchor point by *offset_x* and *offset_y*. If a single value *offset* - is given, *offset_y* = *offset_x* = *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. @@ -134,21 +134,19 @@ def image( # noqa: PLR0913 _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( J=Alias(projection, name="projection"), D=[ - Alias( - position_type, - name="position_type", - mapping={ - "mapcoords": "g", - "boxcoords": "n", - "plotcoords": "x", - "inside": "j", - "outside": "J", - }, - ), - Alias(position, name="position", sep="/", size=2), + 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"), 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 From 23993e64dbed0b43784ed2e7f29a10bde2b71f9b Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Mon, 15 Sep 2025 15:16:33 +0800 Subject: [PATCH 4/4] Fix styling --- pygmt/src/image.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pygmt/src/image.py b/pygmt/src/image.py index b1a3a799713..70ebfc0d0ea 100644 --- a/pygmt/src/image.py +++ b/pygmt/src/image.py @@ -6,7 +6,6 @@ from typing import Literal from pygmt._typing import AnchorCode, PathLike -from pygmt._typing import 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