Skip to content

Strange behaviour when using Session.call_module(). #1582

@timrlaw

Description

@timrlaw

Description of the problem

Hi all. I'm having issues related to sessions, and the order in which seemingly unrelated commands are issued affecting the final plot in strange ways. I think this is related to #1242 and #733.

Essentially what I'm trying to do is set the dimensions of an inset figure to match the dimensions of the inset map. Perhaps there is a better way to do this, but the way I've found is to use GMT's mapproject to calculate the height given the width. PyGMT doesn't expose mapproject so I have to use Session.call_module(), see the code below.

The problem is that doing this results in strange behaviour, dependent on where exactly the mapproject call is issued. I have found a way to arrange the code to get the figure I want, but it is very fragile, and the inset options do not work correctly.

Full code that generated the error

This is the "working" sample:

import pygmt
from pygmt.clib import Session
from pygmt.helpers import GMTTempFile


def mapproject_height(region, projection):
    with GMTTempFile() as tmp:
        args = f"-R{region} -J{projection} -Wh ->{tmp.name}"
        with Session() as lib:
            lib.call_module("mapproject", args)
        h = tmp.read().strip()

    return h


region = [-51, -48, -24, -23]
inset_region = [-80, -28, -43, 0]
inset_w = 2

fig = pygmt.Figure()

grid = pygmt.datasets.load_earth_relief(resolution="03s", region=region)
fig.grdimage(grid=grid, projection="M15c", frame=True, cmap="world")

fig.colorbar(frame=["x", "y+lm"], position="JBC+o0c/0.6c+w4.8c")

inset_h = mapproject_height("80W/28W/43S/0S", "M2c")
with fig.inset(position=f"jBL+w{inset_w}c/{inset_h}c+o0.1c", box="+pblack"):
    fig.coast(region=inset_region, projection=f"M{inset_w}c",
            land="gray", shorelines="thin", water="white")

fig.savefig("test.png")

Issues arise when trying to:

  • Plot the colorbar after the inset---it is positioned relative to the inset rather than the main figure despite being outside the with statement.
  • Move the inset to another corner (e.g. TL instead of BL). This results in the inset not being positioned correctly.
  • Moving the mapproject_height call to the beginning, causes the outer figure to use the region boundaries from the inset for some reason.

Basically this only works if the inset is in the bottom-left, and plotted last, and the mapproject_height call is issued right before the with statement. This causes problems when I want to make more complex plots.

Full error message

n/a

System information

PyGMT information:
  version: v0.4.1
System information:
  python: 3.9.7 (default, Sep  3 2021, 12:37:55)  [Clang 12.0.5 (clang-1205.0.22.9)]
  executable: /Users/.../.local/share/virtualenvs/bed-mpQI0RL-/bin/python
  machine: macOS-11.6-x86_64-i386-64bit
Dependency information:
  numpy: 1.21.2
  pandas: 1.3.3
  xarray: 0.19.0
  netCDF4: 1.5.7
  packaging: 21.0
  ghostscript: 9.53.3
  gmt: 6.2.0
GMT library information:
  binary dir: /usr/local/Cellar/python@3.9/3.9.7/Frameworks/Python.framework/Versions/3.9/Resources/Python.app/Contents/MacOS
  cores: 8
  grid layout: rows
  library path: /usr/local/Cellar/gmt/6.2.0_1/lib/libgmt.dylib
  padding: 2
  plugin dir: /usr/local/Cellar/gmt/6.2.0_1/lib/gmt/plugins
  share dir: /usr/local/Cellar/gmt/6.2.0_1/share/gmt
  version: 6.2.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions