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