Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow passing xr.DataArray as shading to grdimage #750

Merged
merged 23 commits into from
Jun 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
bb99fa1
Pass xr.DataArray shading to grdimage
seisman Dec 19, 2020
5a689ea
Merge branch 'master' into grdimage-xarray-shading
seisman Dec 19, 2020
00036ee
Merge branch 'master' into grdimage-xarray-shading
seisman Dec 22, 2020
addc673
Merge branch 'master' into grdimage-xarray-shading
seisman Dec 22, 2020
b14140a
Merge branch 'master' into grdimage-xarray-shading
seisman Dec 23, 2020
7c88639
Merge branch 'master' into grdimage-xarray-shading
seisman Dec 29, 2020
c7d8a4d
Merge branch 'master' into grdimage-xarray-shading
seisman Dec 29, 2020
5387549
Merge branch 'master' into grdimage-xarray-shading
seisman Dec 31, 2020
f8184cb
Merge branch 'master' into grdimage-xarray-shading
seisman Jan 5, 2021
31c80b9
Merge branch 'master' into grdimage-xarray-shading
seisman Jan 8, 2021
12116ff
Merge branch 'master' into grdimage-xarray-shading
weiji14 Jan 30, 2021
5c74e0a
Test grdimage with xarray.DataArray input to both grid and shading
weiji14 Jan 30, 2021
38585fc
Update grdimage shading docstring to mention xarray.DataArray input
weiji14 Jan 30, 2021
db94b0c
Merge master branch
seisman Feb 11, 2021
b2fb5f7
Merge branch 'master' into grdimage-xarray-shading
seisman Feb 12, 2021
15d1ebc
Merge branch 'master' into grdimage-xarray-shading
weiji14 May 9, 2021
a2590e7
Merge branch 'master' into grdimage-xarray-shading
weiji14 Jun 3, 2021
d2c2b45
Temporarily add verbosity and colorbar to debug failing test
weiji14 Jun 3, 2021
80dfb50
Mark the grdimage shading test as xfail [skip ci]
seisman Jun 9, 2021
f6da340
Merge branch 'master' into grdimage-xarray-shading
seisman Jun 9, 2021
caf1f2d
Update docstrings
seisman Jun 10, 2021
d09c20d
Fix docstring styles
seisman Jun 10, 2021
2e9fba8
Fix docstrings
seisman Jun 10, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 41 additions & 24 deletions pygmt/src/grdimage.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
"""
grdimage - Plot grids or images.
"""
import contextlib

from pygmt.clib import Session
from pygmt.helpers import build_arg_string, fmt_docstring, kwargs_to_strings, use_alias
from pygmt.helpers import (
build_arg_string,
data_kind,
fmt_docstring,
kwargs_to_strings,
use_alias,
)


@fmt_docstring
Expand Down Expand Up @@ -36,15 +44,17 @@ def grdimage(self, grid, **kwargs):
Project and plot grids or images.

Reads a 2-D grid file and produces a gray-shaded (or colored) map by
building a rectangular image and assigning pixels a gray-shade (or
color) based on the z-value and the CPT file. Optionally, illumination
may be added by providing a file with intensities in the (-1,+1) range
or instructions to derive intensities from the input data grid. Values
outside this range will be clipped. If GMT is built with GDAL support,
``grid`` can be an image file (geo-referenced or not). In this case the
image can optionally be illuminated with the file provided via the
``shading`` parameter. Here, if image has no coordinates then those of the
intensity file will be used.
building a rectangular image and assigning pixels a gray-shade (or color)
based on the z-value and the CPT file. Optionally, illumination may be
added by providing a file with intensities in the (-1,+1) range or
instructions to derive intensities from the input data grid. Values outside
this range will be clipped. Such intensity files can be created from the
grid using :meth:`pygmt.grdgradient` and, optionally, modified by
``grdmath`` or ``grdhisteq``. If GMT is built with GDAL support, ``grid``
can be an image file (geo-referenced or not). In this case the image can
optionally be illuminated with the file provided via the ``shading``
parameter. Here, if image has no coordinates then those of the intensity
file will be used.

When using map projections, the grid is first resampled on a new
rectangular grid with the same dimensions. Higher resolution images can
Expand Down Expand Up @@ -116,19 +126,20 @@ def grdimage(self, grid, **kwargs):
paint the mask with the given color. Append **+b** to paint the
background pixels (1) or **+f** for the foreground pixels
[Default is **+f**].
shading : str
*intensfile*\|\ *intensity*\|\ *modifiers*.
Give the name of a grid file with intensities in the (-1,+1) range,
or a constant intensity to apply everywhere (affects the ambient
light). Alternatively, derive an intensity grid from the input data
grid via a call to ``grdgradient``; append **+a**\ *azimuth*,
**+n**\ *args*, and **+m**\ *ambient* to specify azimuth,
intensity, and ambient arguments for that module, or just give
**+d** to select the default arguments
[Default is **+a**\ -45\ **+nt**\ 1\ **+m**\ 0]. If you want a more
specific intensity scenario then run ``grdgradient`` separately first.
If we should derive intensities from another file than grid, specify
the file with suitable modifiers [Default is no illumination].
shading : str or xarray.DataArray
[*intensfile*\|\ *intensity*\|\ *modifiers*].
Give the name of a grid file or a DataArray with intensities in the
(-1,+1) range, or a constant intensity to apply everywhere (affects the
ambient light). Alternatively, derive an intensity grid from the input
data grid via a call to :meth:`pygmt.grdgradient`; append
**+a**\ *azimuth*, **+n**\ *args*, and **+m**\ *ambient* to specify
azimuth, intensity, and ambient arguments for that module, or just give
**+d** to select the default arguments (``+a-45+nt1+m0``). If you want
a more specific intensity scenario then run :meth:`pygmt.grdgradient`
separately first. If we should derive intensities from another file
than grid, specify the file with suitable modifiers [Default is no
illumination]. Note: If the input data is an *image* then an
*intensfile* or constant *intensity* must be provided.
{J}
monochrome : bool
Force conversion to monochrome image using the (television) YIQ
Expand All @@ -153,6 +164,12 @@ def grdimage(self, grid, **kwargs):
kwargs = self._preprocess(**kwargs) # pylint: disable=protected-access
with Session() as lib:
file_context = lib.virtualfile_from_data(check_kind="raster", data=grid)
with file_context as fname:
with contextlib.ExitStack() as stack:
# shading using an xr.DataArray
if "I" in kwargs and data_kind(kwargs["I"]) == "grid":
shading_context = lib.virtualfile_from_grid(kwargs["I"])
kwargs["I"] = stack.enter_context(shading_context)

fname = stack.enter_context(file_context)
arg_str = " ".join([fname, build_arg_string(kwargs)])
lib.call_module("grdimage", arg_str)
20 changes: 20 additions & 0 deletions pygmt/tests/test_grdimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,26 @@ def test_grdimage_shading_xarray(grid, shading):
return fig_ref, fig_test


@pytest.mark.xfail(
reason="Incorrect scaling of geo CPT on xarray.DataArray grdimage plot."
"See https://github.com/GenericMappingTools/gmt/issues/5294",
)
@check_figures_equal()
seisman marked this conversation as resolved.
Show resolved Hide resolved
def test_grdimage_grid_and_shading_with_xarray(grid, xrgrid):
"""
Test that shading works well when xarray.DataArray is input to both the
``grid`` and ``shading`` arguments.
"""
fig_ref, fig_test = Figure(), Figure()
fig_ref.grdimage(
grid="@earth_relief_01d_g", region="GL", cmap="geo", shading=xrgrid, verbose="i"
)
fig_ref.colorbar()
fig_test.grdimage(grid=grid, region="GL", cmap="geo", shading=xrgrid, verbose="i")
fig_test.colorbar()
Comment on lines +131 to +136
Copy link
Member

@weiji14 weiji14 Jun 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, I tried using makecpt to get both plots to use the same colormap scale, but the images still differ, appears to be some slight offset in the left-right direction. So it's not just a matter of CPT scaling as reported in GenericMappingTools/gmt#5294, but maybe 2 problems.

Suggested change
fig_ref.grdimage(
grid="@earth_relief_01d_g", region="GL", cmap="geo", shading=xrgrid, verbose="i"
)
fig_ref.colorbar()
fig_test.grdimage(grid=grid, region="GL", cmap="geo", shading=xrgrid, verbose="i")
fig_test.colorbar()
makecpt(cmap="geo", series=(-3900, 3200))
fig_ref.grdimage(
grid="@earth_relief_01d_g", region="GL", cmap=True, shading=xrgrid, verbose="d"
)
fig_ref.colorbar()
fig_test.grdimage(grid=grid, region="GL", cmap=True, shading=xrgrid, verbose="d")
fig_test.colorbar()
Expected (correct) Generated (wrong) Diff
test_grdimage_grid_and_shading_with_xarray png -expected test_grdimage_grid_and_shading_with_xarray png test_grdimage_grid_and_shading_with_xarray png -failed-diff

return fig_ref, fig_test


def test_grdimage_fails():
"""
Should fail for unrecognized input.
Expand Down