Skip to content
Merged
Changes from 7 commits
Commits
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
267 changes: 142 additions & 125 deletions pygmt/tests/test_grdview.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,57 @@
"""
import pytest

from .. import Figure, which
from ..datasets import load_earth_relief
from .. import Figure, grdcut, which
from ..exceptions import GMTInvalidInput
from ..helpers import data_kind
from ..helpers import GMTTempFile, data_kind
from ..helpers.testing import check_figures_equal


@pytest.fixture(scope="module", name="region")
def fixture_region():
"Test region as lonmin, lonmax, latmin, latmax"
return (-116, -109, -47, -44)


@pytest.fixture(scope="module", name="gridfile")
def fixture_gridfile(region):
"""
Load the NetCDF grid file from the sample earth_relief file
"""
with GMTTempFile(suffix=".nc") as tmpfile:
grdcut(grid="@earth_relief_01d_g", region=region, outgrid=tmpfile.name)
yield tmpfile.name


@pytest.fixture(scope="module", name="grid")
def fixture_grid():
"Load the grid data from the sample earth_relief file"
return load_earth_relief(registration="gridline").sel(
lat=slice(-49, -42), lon=slice(-118, -107)
)
def fixture_grid(region):
"""
Load the xarray.DataArray grid from the sample earth_relief file
"""
return grdcut(grid="@earth_relief_01d_g", region=region)


@pytest.mark.xfail(
reason="Baseline image generated using Cartesian instead of Geographic coordinates"
)
@pytest.mark.mpl_image_compare
def test_grdview_grid_dataarray(grid):
@check_figures_equal()
def test_grdview_grid_dataarray(gridfile, grid):
"""
Run grdview by passing in a grid as an xarray.DataArray.
"""
fig = Figure()
fig.grdview(grid=grid)
return fig
fig_ref = Figure()
fig_ref.grdview(grid=gridfile)
fig_test = Figure()
fig_test.grdview(grid=grid)
return fig_ref, fig_test


@pytest.mark.xfail(
reason="Baseline image not updated to use earth relief grid in GMT 6.1.0",
)
@pytest.mark.mpl_image_compare
def test_grdview_grid_file_with_region_subset():
def test_grdview_grid_file_with_region_subset(region):
"""
Run grdview by passing in a grid filename, and cropping it to a region.
"""
gridfile = which("@earth_relief_01d_g", download="a")

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


Expand All @@ -57,199 +69,204 @@ def test_grdview_wrong_kind_of_grid(grid):
fig.grdview(grid=dataset)


@pytest.mark.xfail(
reason="Baseline image generated using Cartesian instead of Geographic coordinates"
)
@pytest.mark.mpl_image_compare
def test_grdview_with_perspective(grid):
@check_figures_equal()
def test_grdview_with_perspective(gridfile, 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
fig_ref = Figure()
fig_ref.grdview(grid=gridfile, perspective=[135, 15])
fig_test = Figure()
fig_test.grdview(grid=grid, perspective=[135, 15])
return fig_ref, fig_test


@pytest.mark.xfail(
reason="Baseline image not updated to use earth relief grid in GMT 6.1.0",
)
@pytest.mark.mpl_image_compare
def test_grdview_with_perspective_and_zscale(grid):
@check_figures_equal()
def test_grdview_with_perspective_and_zscale(gridfile, 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
fig_ref = Figure()
fig_ref.grdview(grid=gridfile, perspective=[225, 30], zscale=0.005)
fig_test = Figure()
fig_test.grdview(grid=grid, perspective=[225, 30], zscale=0.005)
return fig_ref, fig_test


@pytest.mark.xfail(
reason="Baseline image not updated to use earth relief grid in GMT 6.1.0",
)
@pytest.mark.mpl_image_compare
def test_grdview_with_perspective_and_zsize(grid):
@check_figures_equal()
def test_grdview_with_perspective_and_zsize(gridfile, 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
fig_ref = Figure()
fig_ref.grdview(grid=gridfile, perspective=[225, 30], zsize="10c")
fig_test = Figure()
fig_test.grdview(grid=grid, perspective=[225, 30], zsize="10c")
return fig_ref, fig_test


@pytest.mark.xfail(
reason="Baseline image not updated to use earth relief grid in GMT 6.1.0",
)
@pytest.mark.mpl_image_compare
def test_grdview_with_cmap_for_image_plot(grid):
@check_figures_equal()
def test_grdview_with_cmap_for_image_plot(gridfile, 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
fig_ref = Figure()
fig_ref.grdview(grid=gridfile, cmap="oleron", surftype="i")
fig_test = Figure()
fig_test.grdview(grid=grid, cmap="oleron", surftype="i")
return fig_ref, fig_test


@pytest.mark.xfail(
reason="Baseline image not updated to use earth relief grid in GMT 6.1.0",
)
@pytest.mark.mpl_image_compare
def test_grdview_with_cmap_for_surface_monochrome_plot(grid):
@check_figures_equal()
def test_grdview_with_cmap_for_surface_monochrome_plot(gridfile, 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
fig_ref = Figure()
fig_ref.grdview(grid=gridfile, cmap="oleron", surftype="s+m")
fig_test = Figure()
fig_test.grdview(grid=grid, cmap="oleron", surftype="s+m")
return fig_ref, fig_test


@pytest.mark.xfail(
reason="Baseline image not updated to use earth relief grid in GMT 6.1.0",
)
@pytest.mark.mpl_image_compare
def test_grdview_with_cmap_for_perspective_surface_plot(grid):
@check_figures_equal()
def test_grdview_with_cmap_for_perspective_surface_plot(gridfile, 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(
fig_ref = Figure()
fig_ref.grdview(
grid=gridfile, cmap="oleron", surftype="s", perspective=[225, 30], zscale=0.005
)
fig_test = Figure()
fig_test.grdview(
grid=grid, cmap="oleron", surftype="s", perspective=[225, 30], zscale=0.005
)
return fig
return fig_ref, fig_test


@pytest.mark.xfail(
reason="Baseline image not updated to use earth relief grid in GMT 6.1.0",
)
@pytest.mark.mpl_image_compare
def test_grdview_on_a_plane(grid):
@check_figures_equal()
def test_grdview_on_a_plane(gridfile, 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
fig_ref = Figure()
fig_ref.grdview(grid=gridfile, plane=-4000, perspective=[225, 30], zscale=0.005)
fig_test = Figure()
fig_test.grdview(grid=grid, plane=-4000, perspective=[225, 30], zscale=0.005)
return fig_ref, fig_test


@pytest.mark.xfail(
reason="Baseline image not updated to use earth relief grid in GMT 6.1.0",
)
@pytest.mark.mpl_image_compare
def test_grdview_on_a_plane_with_colored_frontal_facade(grid):
@check_figures_equal()
def test_grdview_on_a_plane_with_colored_frontal_facade(gridfile, 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
fig_ref = Figure()
fig_ref.grdview(
grid=gridfile, plane="-4000+ggray", perspective=[225, 30], zscale=0.005
)
fig_test = Figure()
fig_test.grdview(
grid=grid, plane="-4000+ggray", perspective=[225, 30], zscale=0.005
)
return fig_ref, fig_test


@pytest.mark.xfail(
reason="Baseline image not updated to use earth relief grid in GMT 6.1.0",
)
@pytest.mark.mpl_image_compare
def test_grdview_with_perspective_and_zaxis_frame(grid):
@check_figures_equal()
def test_grdview_with_perspective_and_zaxis_frame(gridfile, 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
fig_ref = Figure()
fig_ref.grdview(grid=gridfile, perspective=[225, 30], zscale=0.005, frame="zaf")
fig_test = Figure()
fig_test.grdview(grid=grid, perspective=[225, 30], zscale=0.005, frame="zaf")
return fig_ref, fig_test
Copy link
Member Author

@weiji14 weiji14 Sep 7, 2020

Choose a reason for hiding this comment

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

This test_grdview_with_perspective_and_zaxis_frame is a very strange one. It passes when the full test suite is ran using make test, but was failing locally for me everytime I ran pytest --mpl --verbose --doctest-modules pygmt/tests/test_grdview.py. Even weirder is that the problem seems to be on the NetCDF plot rather than the xarray one (now I've seen everything)! The difference is a doubling on the x and y-axis frame, will report this to upstream GMT in a bi (Edit: it's at GenericMappingTools/gmt#4181):

NetCDF (expected, but wrong) xarray.DataArray (test, correct?!!)
test_grdview_with_perspective_and_zaxis_frame-expected test_grdview_with_perspective_and_zaxis_frame

Exact error is:

matplotlib.testing.exceptions.ImageComparisonFailure: Image sizes do not match expected size: (1534, 2664, 3) actual size (1521, 2638, 3)

Copy link
Member

Choose a reason for hiding this comment

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

The xarray.DataArray result is "incorrect", because GMT takes the input xarray grid as a Cartesian grid, although grid.gmt.gtype=1.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, so there's several layers of 'wrong-ness' here it seems? The NetCDF grdview plot is wrong because it has a double frame (without the zebra stripes), and the xarray grid is wrong because it's using the Cartesian plain map frame? But these are 'absolute' wrongs i.e. bugs, and our new @check_figures_equal decorator only does a 'relative' comparison to ensure we're reproducing GMT plots in PyGMT (be it right or wrong).

What I don't understand is why the tests pass when ran using make test (false negative), but fails with pytest --mpl --verbose --doctest-modules pygmt/tests/test_grdview.py. Seems like another flaky test issue.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, it puzzles me, too.



@pytest.mark.xfail(
reason="Baseline image not updated to use earth relief grid in GMT 6.1.0",
)
@pytest.mark.mpl_image_compare
def test_grdview_surface_plot_styled_with_contourpen(grid):
@check_figures_equal()
def test_grdview_surface_plot_styled_with_contourpen(gridfile, 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
fig_ref = Figure()
fig_ref.grdview(
grid=gridfile, cmap="relief", surftype="s", contourpen="0.5p,black,dash"
)
fig_test = Figure()
fig_test.grdview(
grid=grid, cmap="relief", surftype="s", contourpen="0.5p,black,dash"
)
return fig_ref, fig_test


@pytest.mark.xfail(
reason="Baseline image not updated to use earth relief grid in GMT 6.1.0",
)
@pytest.mark.mpl_image_compare
def test_grdview_surface_mesh_plot_styled_with_meshpen(grid):
@check_figures_equal()
def test_grdview_surface_mesh_plot_styled_with_meshpen(gridfile, 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
fig_ref = Figure()
fig_ref.grdview(
grid=gridfile, cmap="relief", surftype="sm", meshpen="0.5p,black,dash"
)
fig_test = Figure()
fig_test.grdview(grid=grid, cmap="relief", surftype="sm", meshpen="0.5p,black,dash")
return fig_ref, fig_test


@pytest.mark.xfail(
reason="Baseline image not updated to use earth relief grid in GMT 6.1.0",
)
@pytest.mark.mpl_image_compare
def test_grdview_on_a_plane_styled_with_facadepen(grid):
@check_figures_equal()
def test_grdview_on_a_plane_styled_with_facadepen(gridfile, 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(
fig_ref = Figure()
fig_ref.grdview(
grid=gridfile,
plane=-4000,
perspective=[225, 30],
zscale=0.005,
facadepen="0.5p,blue,dash",
)
fig_test = Figure()
fig_test.grdview(
grid=grid,
plane=-4000,
perspective=[225, 30],
zscale=0.005,
facadepen="0.5p,blue,dash",
)
return fig
return fig_ref, fig_test


@pytest.mark.xfail(
reason="Baseline image not updated to use earth relief grid in GMT 6.1.0",
)
@pytest.mark.mpl_image_compare
def test_grdview_drapegrid_dataarray(grid):
@check_figures_equal()
def test_grdview_drapegrid_dataarray(gridfile, 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
fig_ref = Figure()
fig_ref.grdview(grid=gridfile, drapegrid=drapegrid, cmap="oleron", surftype="c")
fig_test = Figure()
fig_test.grdview(grid=grid, drapegrid=drapegrid, cmap="oleron", surftype="c")
return fig_ref, fig_test


def test_grdview_wrong_kind_of_drapegrid(grid):
Expand Down