Skip to content

Commit

Permalink
Wrap grdview (#330)
Browse files Browse the repository at this point in the history
Wrapping the grdview function raised at #328, to be implemented under base_plotting.py. Original GMT `grdview` documentation can be found at https://docs.generic-mapping-tools.org/latest/grdview.html. Storing sample test cases under test_grdview.py.
  • Loading branch information
weiji14 authored Mar 26, 2020
1 parent d29a1a6 commit 088b0d1
Show file tree
Hide file tree
Showing 18 changed files with 328 additions and 0 deletions.
1 change: 1 addition & 0 deletions doc/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Plotting data and laying out the map:
Figure.contour
Figure.grdcontour
Figure.grdimage
Figure.grdview
Figure.legend
Figure.logo
Figure.image
Expand Down
109 changes: 109 additions & 0 deletions pygmt/base_plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Base class with plot generating commands.
Does not define any special non-GMT methods (savefig, show, etc).
"""
import contextlib
import csv
import os
import numpy as np
Expand Down Expand Up @@ -318,6 +319,114 @@ def grdimage(self, grid, **kwargs):
arg_str = " ".join([fname, build_arg_string(kwargs)])
lib.call_module("grdimage", arg_str)

@fmt_docstring
@use_alias(
R="region",
J="projection",
Jz="zscale",
JZ="zsize",
B="frame",
C="cmap",
G="drapegrid",
N="plane",
Q="surftype",
Wc="contourpen",
Wm="meshpen",
Wf="facadepen",
p="perspective",
)
@kwargs_to_strings(R="sequence", p="sequence")
def grdview(self, grid, **kwargs):
"""
Create 3-D perspective image or surface mesh from a grid.
Reads a 2-D grid file and produces a 3-D perspective plot by drawing a
mesh, painting a colored/gray-shaded surface made up of polygons, or by
scanline conversion of these polygons to a raster image. Options
include draping a data set on top of a surface, plotting of contours on
top of the surface, and apply artificial illumination based on
intensities provided in a separate grid file.
Full option list at :gmt-docs:`grdview.html`
Parameters
----------
grid : str or xarray.DataArray
The file name of the input relief grid or the grid loaded as a
DataArray.
zscale/zsize : float or str
Set z-axis scaling or z-axis size.
cmap : str
The name of the color palette table to use.
drapegrid : str or xarray.DataArray
The file name or a DataArray of the image grid to be draped on top
of the relief provided by grid. [Default determines colors from
grid]. Note that -Jz and -N always refers to the grid. The
drapegrid only provides the information pertaining to colors, which
(if drapegrid is a grid) will be looked-up via the CPT (see -C).
plane : float or str
``level[+gfill]``.
Draws a plane at this z-level. If the optional color is provided
via the +g modifier, and the projection is not oblique, the frontal
facade between the plane and the data perimeter is colored.
surftype : str
Specifies cover type of the grid.
Select one of following settings:
1. 'm' for mesh plot [Default].
2. 'mx' or 'my' for waterfall plots (row or column profiles).
3. 's' for surface plot.
4. 'i' for image plot.
5. 'c'. Same as 'i' but will make nodes with z = NaN transparent.
For any of these choices, you may force a monochrome image by
appending the modifier +m.
contourpen : str
Draw contour lines on top of surface or mesh (not image). Append
pen attributes used for the contours.
meshpen : str
Sets the pen attributes used for the mesh. You must also select -Qm
or -Qsm for meshlines to be drawn.
facadepen :str
Sets the pen attributes used for the facade. You must also select
-N for the facade outline to be drawn.
perspective : list or str
``'[x|y|z]azim[/elev[/zlevel]][+wlon0/lat0[/z0]][+vx0/y0]'``.
Select perspective view.
{aliases}
"""
kwargs = self._preprocess(**kwargs)
kind = data_kind(grid, None, None)
with Session() as lib:
if kind == "file":
file_context = dummy_context(grid)
elif kind == "grid":
file_context = lib.virtualfile_from_grid(grid)
else:
raise GMTInvalidInput(f"Unrecognized data type for grid: {type(grid)}")

with contextlib.ExitStack() as stack:
fname = stack.enter_context(file_context)
if "G" in kwargs:
drapegrid = kwargs["G"]
if data_kind(drapegrid) in ("file", "grid"):
if data_kind(drapegrid) == "grid":
drape_context = lib.virtualfile_from_grid(drapegrid)
drapefile = stack.enter_context(drape_context)
kwargs["G"] = drapefile
else:
raise GMTInvalidInput(
f"Unrecognized data type for drapegrid: {type(drapegrid)}"
)
arg_str = " ".join([fname, build_arg_string(kwargs)])
lib.call_module("grdview", arg_str)

@fmt_docstring
@use_alias(
R="region",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pygmt/tests/baseline/test_grdview_on_a_plane.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
218 changes: 218 additions & 0 deletions pygmt/tests/test_grdview.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
# pylint: disable=redefined-outer-name
"""
Tests grdview
"""
import pytest

from .. import Figure, which
from ..datasets import load_earth_relief
from ..exceptions import GMTInvalidInput
from ..helpers import data_kind


@pytest.fixture(scope="module")
def grid():
"Load the grid data from the sample earth_relief file"
return load_earth_relief().sel(lat=slice(-49, -42), lon=slice(-118, -107))


@pytest.mark.mpl_image_compare
def test_grdview_grid_dataarray(grid):
"""
Run grdview by passing in a grid as an xarray.DataArray.
"""
fig = Figure()
fig.grdview(grid=grid)
return fig


@pytest.mark.mpl_image_compare
def test_grdview_grid_file_with_region_subset():
"""
Run grdview by passing in a grid filename, and cropping it to a region.
"""
gridfile = which("@earth_relief_60m", download="c")

fig = Figure()
fig.grdview(grid=gridfile, region=[-116, -109, -47, -44])
return fig


def test_grdview_wrong_kind_of_grid(grid):
"""
Run grdview using grid input that is not an xarray.DataArray or file.
"""
dataset = grid.to_dataset() # convert xarray.DataArray to xarray.Dataset
assert data_kind(dataset) == "matrix"

fig = Figure()
with pytest.raises(GMTInvalidInput):
fig.grdview(grid=dataset)


@pytest.mark.mpl_image_compare
def test_grdview_with_perspective(grid):
"""
Run grdview by passing in a grid and setting a perspective viewpoint with
an azimuth from the SouthEast and an elevation angle 15 degrees from the
z-plane.
"""
fig = Figure()
fig.grdview(grid=grid, perspective=[135, 15])
return fig


@pytest.mark.mpl_image_compare
def test_grdview_with_perspective_and_zscale(grid):
"""
Run grdview by passing in a grid and setting a perspective viewpoint with
an azimuth from the SouthWest and an elevation angle 30 degrees from the
z-plane, plus a z-axis scaling factor of 0.005.
"""
fig = Figure()
fig.grdview(grid=grid, perspective=[225, 30], zscale=0.005)
return fig


@pytest.mark.mpl_image_compare
def test_grdview_with_perspective_and_zsize(grid):
"""
Run grdview by passing in a grid and setting a perspective viewpoint with
an azimuth from the SouthWest and an elevation angle 30 degrees from the
z-plane, plus a z-axis size of 10cm.
"""
fig = Figure()
fig.grdview(grid=grid, perspective=[225, 30], zsize="10c")
return fig


@pytest.mark.mpl_image_compare
def test_grdview_with_cmap_for_image_plot(grid):
"""
Run grdview by passing in a grid and setting a colormap for producing an
image plot.
"""
fig = Figure()
fig.grdview(grid=grid, cmap="oleron", surftype="i")
return fig


@pytest.mark.mpl_image_compare
def test_grdview_with_cmap_for_surface_monochrome_plot(grid):
"""
Run grdview by passing in a grid and setting a colormap for producing a
surface monochrome plot.
"""
fig = Figure()
fig.grdview(grid=grid, cmap="oleron", surftype="s+m")
return fig


@pytest.mark.mpl_image_compare
def test_grdview_with_cmap_for_perspective_surface_plot(grid):
"""
Run grdview by passing in a grid and setting a colormap for producing a
surface plot with a 3D perspective viewpoint.
"""
fig = Figure()
fig.grdview(
grid=grid, cmap="oleron", surftype="s", perspective=[225, 30], zscale=0.005,
)
return fig


@pytest.mark.mpl_image_compare
def test_grdview_on_a_plane(grid):
"""
Run grdview by passing in a grid and plotting it on a z-plane, while
setting a 3D perspective viewpoint.
"""
fig = Figure()
fig.grdview(grid=grid, plane=-4000, perspective=[225, 30], zscale=0.005)
return fig


@pytest.mark.mpl_image_compare
def test_grdview_on_a_plane_with_colored_frontal_facade(grid):
"""
Run grdview by passing in a grid and plotting it on a z-plane whose frontal
facade is colored gray, while setting a 3D perspective viewpoint.
"""
fig = Figure()
fig.grdview(grid=grid, plane="-4000+ggray", perspective=[225, 30], zscale=0.005)
return fig


@pytest.mark.mpl_image_compare
def test_grdview_with_perspective_and_zaxis_frame(grid):
"""
Run grdview by passing in a grid and plotting an annotated vertical
z-axis frame.
"""
fig = Figure()
fig.grdview(grid=grid, perspective=[225, 30], zscale=0.005, frame="zaf")
return fig


@pytest.mark.mpl_image_compare
def test_grdview_surface_plot_styled_with_contourpen(grid):
"""
Run grdview by passing in a grid with styled contour lines plotted on top
of a surface plot.
"""
fig = Figure()
fig.grdview(grid=grid, cmap="relief", surftype="s", contourpen="0.5p,black,dash")
return fig


@pytest.mark.mpl_image_compare
def test_grdview_surface_mesh_plot_styled_with_meshpen(grid):
"""
Run grdview by passing in a grid with styled mesh lines plotted on top of a
surface mesh plot.
"""
fig = Figure()
fig.grdview(grid=grid, cmap="relief", surftype="sm", meshpen="0.5p,black,dash")
return fig


@pytest.mark.mpl_image_compare
def test_grdview_on_a_plane_styled_with_facadepen(grid):
"""
Run grdview by passing in a grid and plotting it on a z-plane with styled
lines for the frontal facade.
"""
fig = Figure()
fig.grdview(
grid=grid,
plane=-4000,
perspective=[225, 30],
zscale=0.005,
facadepen="0.5p,blue,dash",
)
return fig


@pytest.mark.mpl_image_compare
def test_grdview_drapegrid_dataarray(grid):
"""
Run grdview by passing in both a grid and drapegrid as an xarray.DataArray,
setting a colormap for producing an image plot.
"""
drapegrid = 1.1 * grid

fig = Figure()
fig.grdview(grid=grid, drapegrid=drapegrid, cmap="oleron", surftype="c")
return fig


def test_grdview_wrong_kind_of_drapegrid(grid):
"""
Run grdview using drapegrid input that is not an xarray.DataArray or file.
"""
dataset = grid.to_dataset() # convert xarray.DataArray to xarray.Dataset
assert data_kind(dataset) == "matrix"

fig = Figure()
with pytest.raises(GMTInvalidInput):
fig.grdview(grid=grid, drapegrid=dataset)

0 comments on commit 088b0d1

Please sign in to comment.