|
2 | 2 | shift_origin - Shift plot origin in x and/or y directions.
|
3 | 3 | """
|
4 | 4 |
|
| 5 | +from contextlib import contextmanager |
| 6 | + |
5 | 7 | from pygmt.clib import Session
|
| 8 | +from pygmt.helpers import build_arg_list |
6 | 9 |
|
7 | 10 |
|
8 | 11 | def shift_origin(
|
9 | 12 | self, xshift: float | str | None = None, yshift: float | str | None = None
|
10 | 13 | ):
|
11 | 14 | r"""
|
12 |
| - Shift plot origin in x and/or y directions. |
| 15 | + Shift the plot origin in x and/or y directions. |
| 16 | +
|
| 17 | + The shifts can be temporary or permanent. If used as a context manager, the shifts |
| 18 | + are temporary and only apply to the block of code within the context manager. If |
| 19 | + used as a standalone method, the shifts are permanent and apply to all subsequent |
| 20 | + plots. |
| 21 | +
|
| 22 | + 1. Use as a context manager to shift the plot origin temporarily: |
| 23 | +
|
| 24 | + .. code-block:: python |
| 25 | +
|
| 26 | + with fig.shift_origin(...): |
| 27 | + ... # Other plot commands |
| 28 | + ... |
| 29 | +
|
| 30 | + 2. Use as a standalone method to shift the plot origin permanently: |
| 31 | +
|
| 32 | + .. code-block:: python |
| 33 | +
|
| 34 | + fig.shift_origin(xshift=12) |
| 35 | + ... # Other plot commands |
13 | 36 |
|
14 |
| - This method shifts the plot origin relative to the current origin by *xshift* and |
15 |
| - *yshift* in x and y directions, respectively. Optionally, append the length unit |
| 37 | + The shifts *xshift* and *yshift* in x and y directions are relative to the current |
| 38 | + plot origin. The default unit for shifts is centimeters (**c**) but can be changed |
| 39 | + to other units via :gmt-term:`PROJ_LENGTH_UNIT`. Optionally, append the length unit |
16 | 40 | (**c** for centimeters, **i** for inches, or **p** for points) to the shifts.
|
17 |
| - Default unit if not explicitly given is **c**, but can be changed to other units via |
18 |
| - :gmt-term:`PROJ_LENGTH_UNIT`. |
19 | 41 |
|
20 | 42 | For *xshift*, a special character **w** can also be used, which represents the
|
21 | 43 | bounding box **width** of the previous plot. The full syntax is
|
@@ -44,23 +66,63 @@ def shift_origin(
|
44 | 66 |
|
45 | 67 | Examples
|
46 | 68 | --------
|
| 69 | +
|
| 70 | + Shifting the plot origin permanently: |
| 71 | +
|
47 | 72 | >>> import pygmt
|
48 | 73 | >>> fig = pygmt.Figure()
|
49 |
| - >>> fig.basemap(region=[0, 10, 0, 10], projection="X10c/10c", frame=True) |
50 |
| - >>> # Shift the plot origin in x direction by 12 cm |
51 |
| - >>> fig.shift_origin(xshift=12) |
52 |
| - >>> fig.basemap(region=[0, 10, 0, 10], projection="X14c/10c", frame=True) |
53 |
| - >>> # Shift the plot origin in x direction based on the previous plot width |
54 |
| - >>> # Here, the width is 14 cm, and xshift is 16 cm |
55 |
| - >>> fig.shift_origin(xshift="w+2c") |
| 74 | + >>> fig.basemap(region=[0, 5, 0, 5], projection="X5c/5c", frame=True) |
| 75 | + >>> # Shift the plot origin in x direction by 6 cm |
| 76 | + >>> fig.shift_origin(xshift=6) |
| 77 | + <pygmt.src.shift_origin.shift_origin object at ...> |
| 78 | + >>> fig.basemap(region=[0, 7, 0, 5], projection="X7c/5c", frame=True) |
| 79 | + >>> # Shift the plot origin in x direction based on the previous plot width. |
| 80 | + >>> # Here, the width is 7 cm, and xshift is 8 cm. |
| 81 | + >>> fig.shift_origin(xshift="w+1c") |
| 82 | + <pygmt.src.shift_origin.shift_origin object at ...> |
| 83 | + >>> fig.basemap(region=[0, 10, 0, 5], projection="X10c/5c", frame=True) |
| 84 | + >>> fig.show() |
| 85 | +
|
| 86 | + Shifting the plot origin temporarily: |
| 87 | +
|
| 88 | + >>> fig = pygmt.Figure() |
| 89 | + >>> fig.basemap(region=[0, 5, 0, 5], projection="X5c/5c", frame=True) |
| 90 | + >>> # Shift the plot origin in x direction by 6 cm temporarily. The plot origin will |
| 91 | + >>> # revert back to the original plot origin after the block of code is executed. |
| 92 | + >>> with fig.shift_origin(xshift=6): |
| 93 | + ... fig.basemap(region=[0, 5, 0, 5], projection="X5c/5c", frame=True) |
| 94 | + >>> # Shift the plot origin in y direction by 6 cm temporarily. |
| 95 | + >>> with fig.shift_origin(yshift=6): |
| 96 | + ... fig.basemap(region=[0, 5, 0, 5], projection="X5c/5c", frame=True) |
| 97 | + >>> # Shift the plot origin in x and y directions by 6 cm temporarily. |
| 98 | + >>> with fig.shift_origin(xshift=6, yshift=6): |
| 99 | + ... fig.basemap(region=[0, 5, 0, 5], projection="X5c/5c", frame=True) |
56 | 100 | >>> fig.show()
|
57 | 101 | """
|
58 | 102 | self._preprocess()
|
59 |
| - args = ["-T"] |
60 |
| - if xshift: |
61 |
| - args.append(f"-X{xshift}") |
62 |
| - if yshift: |
63 |
| - args.append(f"-Y{yshift}") |
| 103 | + kwdict = {"T": True, "X": xshift, "Y": yshift} |
64 | 104 |
|
65 | 105 | with Session() as lib:
|
66 |
| - lib.call_module(module="plot", args=args) |
| 106 | + lib.call_module(module="plot", args=build_arg_list(kwdict)) |
| 107 | + _xshift = lib.get_common("X") # False or xshift in inches |
| 108 | + _yshift = lib.get_common("Y") # False or yshift in inches |
| 109 | + |
| 110 | + @contextmanager |
| 111 | + def _shift_origin_context(): |
| 112 | + """ |
| 113 | + An internal context manager to shift the plot origin temporarily. |
| 114 | + """ |
| 115 | + try: |
| 116 | + yield |
| 117 | + finally: |
| 118 | + # Revert the plot origin to the original plot origin by shifting it by |
| 119 | + # -xshift and -yshift in inches. |
| 120 | + kwdict = { |
| 121 | + "T": True, |
| 122 | + "X": f"{-1.0 * _xshift}i" if _xshift else None, |
| 123 | + "Y": f"{-1.0 * _yshift}i" if _yshift else None, |
| 124 | + } |
| 125 | + with Session() as lib: |
| 126 | + lib.call_module(module="plot", args=build_arg_list(kwdict)) |
| 127 | + |
| 128 | + return _shift_origin_context() |
0 commit comments