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

use image comparison in tests #241

Merged
merged 12 commits into from
Apr 29, 2024
8 changes: 7 additions & 1 deletion .github/workflows/testMaps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,14 @@ jobs:
- name: Test Maps
shell: bash -l {0}
run: |
pip install -e .[all]
pip install -e .[test]
python -m pytest -v --cov=eomaps --cov-report=xml
- name: Upload Image Comparison Artefacts
if: ${{ failure() }}
uses: actions/upload-artifact@v4
with:
name: code-coverage-report
path: img_comparison_results
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
Expand Down
7 changes: 4 additions & 3 deletions docs/examples/example_scalebars.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# EOmaps example: Adding scalebars - what about distances?

from eomaps import Maps

m = Maps(figsize=(9, 5))
Expand All @@ -14,7 +13,9 @@
n=10,
scale_props=dict(width=5, colors=("k", ".25", ".5", ".75", ".95")),
patch_props=dict(offsets=(1, 1.4, 1, 1), fc=(0.7, 0.8, 0.3, 1)),
label_props=dict(offset=0.5, scale=1.4, every=5, weight="bold", family="Calibri"),
label_props=dict(
offset=0.5, scale=1.4, every=5, weight="bold" # , family="Calibri"
),
)

s3 = m.add_scalebar(
Expand All @@ -25,7 +26,7 @@
scale_props=dict(width=3, colors=(*["w", "darkred"] * 2, *["w"] * 5, "darkred")),
patch_props=dict(fc=(0.25, 0.25, 0.25, 0.8), ec="k", lw=0.5, offsets=(1, 1, 1, 2)),
label_props=dict(
every=(1, 4, 10), color="w", rotation=45, weight="bold", family="Impact"
every=(1, 4, 10), color="w", rotation=45, weight="bold" # , family="Impact"
),
line_props=dict(color="w"),
)
Expand Down
9 changes: 9 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ gui = [
"qtpy"
]

test = [
"eomaps[io, classify, wms, shade, gui, test]",
"pytest",
"pytest-mpl"
]

[project.scripts]
eomaps = "eomaps.scripts.open:cli"

Expand All @@ -84,6 +90,9 @@ Documentation = "https://eomaps.readthedocs.io/"
Repository = "https://github.com/raphaelquast/eomaps"

[tool.pytest.ini_options]
mpl-use-full-test-name = "True"
mpl-default-style = "default"
mpl-results-path = "img_comparison_results"
filterwarnings = [
"ignore:Downloading*",
"ignore:Passing a SingleBlockManager to Series is deprecated *:DeprecationWarning",
Expand Down
3 changes: 3 additions & 0 deletions tests/_testdata/testfile.csv
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ a,x,y,data
0,1,2,1
1,3,5,3
2,4,6,5
10,23,45,67
4, -17, -67, 20
16, 15, 16, 78
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.
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.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions tests/test_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@
from pathlib import Path
import matplotlib.pyplot as plt
import unittest
import pytest
import numpy as np


def gen_test(name, code):
@pytest.mark.mpl_image_compare()
def test(*args, **kwargs):
try:
np.random.seed(0) # make tests descriptive
exec(code)

return locals()["m"]
except Exception as ex:
raise AssertionError(f"Example '{name}' failed.") from ex
finally:
Expand Down
126 changes: 57 additions & 69 deletions tests/test_from_file.py
Original file line number Diff line number Diff line change
@@ -1,72 +1,60 @@
import matplotlib as mpl

mpl.rcParams["toolbar"] = "None"

import unittest
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

import pytest
from eomaps import Maps
from pathlib import Path


class TestFromFile(unittest.TestCase):
def setUp(self):
self.csvpath = Path(__file__).parent / "_testdata" / "testfile.csv"
self.tiffpath = Path(__file__).parent / "_testdata" / "testfile.tif"
self.netcdfpath = Path(__file__).parent / "_testdata" / "testfile.nc"
pass

def test_CSV(self):
data = Maps.read_file.CSV(
self.csvpath, x="x", y="y", parameter="data", crs=4326
)
m = Maps.from_file.CSV(
self.csvpath, x="x", y="y", parameter="data", data_crs=4326
)

m2 = m.new_layer_from_file.CSV(
self.csvpath,
x="x",
y="y",
parameter="data",
data_crs=4326,
layer="second",
cmap="cividis",
extent=(-20, 20, -56, 78),
)
m.show_layer(m2.layer)

plt.close("all")

def test_GeoTIFF(self):
data = Maps.read_file.GeoTIFF(self.tiffpath)
m = Maps.from_file.GeoTIFF(self.tiffpath)

m2 = m.new_layer_from_file.GeoTIFF(
self.tiffpath,
layer="second",
cmap="cividis",
shape="shade_points",
extent=(7, 9, 41, 42),
)
m.show_layer(m2.layer)
plt.close("all")

def test_NetCDF(self):
data = Maps.read_file.NetCDF(self.netcdfpath, data_crs=4326)
m = Maps.from_file.NetCDF(
self.netcdfpath, data_crs=4326, shape="voronoi_diagram"
)

m2 = m.new_layer_from_file.NetCDF(
self.netcdfpath,
layer="second",
cmap="cividis",
shape="shade_raster",
data_crs=4326,
extent=((7, 9, 41, 42), 4326),
)
m.show_layer(m2.layer)
plt.close("all")
paths = {
"CSV": Path(__file__).parent / "_testdata" / "testfile.csv",
"GeoTIFF": Path(__file__).parent / "_testdata" / "testfile.tif",
"NetCDF": Path(__file__).parent / "_testdata" / "testfile.nc",
}

read_args = {
"CSV": dict(x="x", y="y", parameter="data", crs=4326),
"NetCDF": dict(data_crs=4326),
}

plot_args = {
"CSV": dict(x="x", y="y", parameter="data", data_crs=4326),
"NetCDF": dict(data_crs=4326),
}

style_args = {
"CSV": dict(cmap="cividis", shape="ellipses"),
"GeoTIFF": dict(shape="raster", extent=(7, 9, 41, 42)),
"NetCDF": dict(shape="voronoi_diagram"),
}


@pytest.mark.parametrize("method", ["CSV", "GeoTIFF", "NetCDF"])
def test_read_file(method):
_ = getattr(Maps.read_file, method)(paths[method], **read_args.get(method, {}))


@pytest.mark.parametrize("method", ["CSV", "GeoTIFF", "NetCDF"])
@pytest.mark.mpl_image_compare()
def test_from_file(method):
m = getattr(Maps.from_file, method)(
paths[method], **plot_args.get(method, {}), **style_args.get(method, {})
)
m.add_feature.preset.coastline()
m.add_gridlines(lw=2, auto_n=5)
return m


@pytest.mark.parametrize("method", ["CSV", "GeoTIFF", "NetCDF"])
@pytest.mark.mpl_image_compare()
def test_new_layer_from_file(method):

m = Maps(Maps.CRS.Mollweide(), layer="all")
m.add_feature.preset.coastline()
m.add_gridlines(lw=2, auto_n=5)

m2 = getattr(m.new_layer_from_file, method)(
paths[method],
**plot_args.get(method, {}),
**style_args.get(method, {}),
layer="second",
)
m.show_layer(m2.layer)

return m
31 changes: 23 additions & 8 deletions tests/test_plot_shapes.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@ def close_all():

@pytest.mark.usefixtures("close_all")
@pytest.mark.parametrize("data", testdata, ids=ids)
@pytest.mark.mpl_image_compare()
def test_hexbin(data):
m = Maps(ax=221, figsize=(10, 6))
m.set_data(**data)
m.set_shape.hexbin(size=(10, 5))
m.plot_map()
m.add_colorbar()
cb = m.add_colorbar()

m2 = m.new_map(ax=222, inherit_data=True)
m2.set_shape.hexbin(size=20, aggregator="median")
Expand All @@ -64,9 +65,12 @@ def test_hexbin(data):
m4.plot_map(cmap="RdYlBu")
m4.add_colorbar()

return m


@pytest.mark.usefixtures("close_all")
@pytest.mark.parametrize("data", testdata, ids=ids)
@pytest.mark.mpl_image_compare()
def test_contour(data):
m = Maps(ax=221, figsize=(10, 6))
m.subplots_adjust(left=0.01, right=0.99)
Expand All @@ -89,8 +93,8 @@ def test_contour(data):
)

m3 = m.new_map(ax=224, inherit_data=True)
m3.set_shape.ellipses()
m3.plot_map(alpha=0.25)
m3.set_shape.voronoi_diagram()
m3.plot_map(alpha=0.25, lw=0.25, ec="k")
cb3 = m3.add_colorbar()

m3_1 = m3.new_layer("contours", inherit_data=True)
Expand Down Expand Up @@ -125,30 +129,41 @@ def test_contour(data):

m.show_layer("base", "contours")

return m


@pytest.mark.usefixtures("close_all")
@pytest.mark.parametrize("data", testdata, ids=ids)
@pytest.mark.mpl_image_compare()
def test_shade_points(data):
m = Maps(ax=221, figsize=(10, 6))

m.set_data(**data)
m.set_shape.shade_points(aggregator="mean")
m.set_shade_dpi(100)
m.plot_map()
m.add_colorbar()

m2 = m.new_map(ax=222, inherit_data=True)
m.set_shape.shade_points(aggregator="max")
m2.set_shape.shade_points(aggregator="max")
m2.set_shade_dpi(30)
m2.plot_map(cmap="RdYlBu")
m2.add_colorbar()
m2.set_shade_dpi(10)

m3 = m.new_map(ax=223, inherit_data=True)
m.set_shape.shade_points(aggregator="max")
m3.set_shape.shade_points(aggregator="max")
m3.set_shade_dpi(20)
m3.plot_map(cmap="RdYlBu")
m3.add_colorbar()
m3.set_shade_dpi(50)

m4 = m.new_map(ax=224, inherit_data=True)
m.set_shape.shade_points(aggregator="max")
m4.set_shape.shade_points(aggregator="max")
m4.set_shade_dpi(10)
m4.set_classify.EqualInterval(k=5)
m4.plot_map(cmap="RdYlBu")
m4.add_colorbar()

for mi in [m, m2, m3, m4]:
mi.add_title(f"shade dpi = {mi._shade_dpi}")

return m
Loading