Skip to content

Commit 201664b

Browse files
committed
Enable passing in a list of RGB xarray.DataArray grids into grdimage
Extends `grdimage` to accept a list of individual red, green and blue xarray.DataArrays for plotting. Had to revert using the 'sequence_space' decorator as it would not work nicely for multiple grids... Implementation uses the contextlib.ExitStack method to create multiple virtual grid files and enter multiple contexts (similar to 3448972). Also added one test case with dummy data, but could do with more to capture edge cases.
1 parent 424e497 commit 201664b

File tree

3 files changed

+55
-6
lines changed

3 files changed

+55
-6
lines changed

pygmt/base_plotting.py

+30-6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
Base class with plot generating commands.
33
Does not define any special non-GMT methods (savefig, show, etc).
44
"""
5+
import contextlib
56
import csv
67
import os
78
import numpy as np
@@ -288,7 +289,7 @@ def grdcontour(self, grid, **kwargs):
288289

289290
@fmt_docstring
290291
@use_alias(R="region", J="projection", W="pen", B="frame", I="shading", C="cmap")
291-
@kwargs_to_strings(R="sequence", grid="sequence_space")
292+
@kwargs_to_strings(R="sequence")
292293
def grdimage(self, grid, **kwargs):
293294
"""
294295
Project grids or images and plot them on maps.
@@ -304,18 +305,41 @@ def grdimage(self, grid, **kwargs):
304305
----------
305306
grid : str, xarray.DataArray or list
306307
The file name of the input grid or the grid loaded as a DataArray.
307-
A list of red, green, blue grids can also be provided instead.
308+
For plotting RGB grids, pass in a list made up of either file names or
309+
DataArrays to the individual red, green and blue grids.
308310
"""
309311
kwargs = self._preprocess(**kwargs)
310-
kind = data_kind(grid, None, None)
312+
313+
if isinstance(grid, list):
314+
if all([data_kind(g) == "file" for g in grid]):
315+
kind = "file"
316+
grid = " ".join(grid)
317+
elif all([data_kind(g) == "grid" for g in grid]):
318+
kind = "grid"
319+
else:
320+
kind = data_kind(grid)
321+
311322
with Session() as lib:
312323
if kind == "file":
313-
file_context = dummy_context(grid)
324+
file_contexts = [dummy_context(grid)]
314325
elif kind == "grid":
315-
file_context = lib.virtualfile_from_grid(grid)
326+
if isinstance(grid, list):
327+
file_contexts = [
328+
lib.virtualfile_from_grid(grid[0]),
329+
lib.virtualfile_from_grid(grid[1]),
330+
lib.virtualfile_from_grid(grid[2]),
331+
]
332+
else:
333+
file_contexts = [lib.virtualfile_from_grid(grid)]
316334
else:
317335
raise GMTInvalidInput("Unrecognized data type: {}".format(type(grid)))
318-
with file_context as fname:
336+
with contextlib.ExitStack() as stack:
337+
fname = " ".join(
338+
[
339+
stack.enter_context(file_context)
340+
for file_context in file_contexts
341+
]
342+
)
319343
arg_str = " ".join([fname, build_arg_string(kwargs)])
320344
lib.call_module("grdimage", arg_str)
321345

13.7 KB
Loading

pygmt/tests/test_grdimage.py

+25
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44
import numpy as np
55
import pytest
6+
import xarray as xr
67

78
from .. import Figure
89
from ..exceptions import GMTInvalidInput
@@ -49,6 +50,30 @@ def test_grdimage_rgb_files():
4950
return fig
5051

5152

53+
@pytest.mark.mpl_image_compare
54+
def test_grdimage_rgb_grid():
55+
"Plot an image using Red, Green, and Blue xarray.DataArray inputs"
56+
red = xr.DataArray(
57+
data=[[128, 0, 0], [128, 0, 0]],
58+
dims=("lat", "lon"),
59+
coords={"lat": [0, 1], "lon": [2, 3, 4]},
60+
)
61+
green = xr.DataArray(
62+
data=[[0, 128, 0], [0, 128, 0]],
63+
dims=("lat", "lon"),
64+
coords={"lat": [0, 1], "lon": [2, 3, 4]},
65+
)
66+
blue = xr.DataArray(
67+
data=[[0, 0, 128], [0, 0, 128]],
68+
dims=("lat", "lon"),
69+
coords={"lat": [0, 1], "lon": [2, 3, 4]},
70+
)
71+
72+
fig = Figure()
73+
fig.grdimage(grid=[red, green, blue], projection="x5c", frame=True)
74+
return fig
75+
76+
5277
def test_grdimage_fails():
5378
"Should fail for unrecognized input"
5479
fig = Figure()

0 commit comments

Comments
 (0)