From c1bb42b0993caf83044e425ea481fbb2c1f40b57 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Wed, 26 Feb 2020 15:38:29 -0700 Subject: [PATCH 01/39] Added a get_points() and assert_points() function to the vector tester. --- matplotcheck/vector.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/matplotcheck/vector.py b/matplotcheck/vector.py index 10610602..c52e4676 100644 --- a/matplotcheck/vector.py +++ b/matplotcheck/vector.py @@ -237,6 +237,27 @@ def assert_collection_sorted_by_markersize(self, df_expected, sort_column): err_msg="Markersize not based on {0} values".format(sort_column), ) + def get_points(self): + """yeet""" + points = self.get_xy(points_only=True).sort_values(by="x") + points.reset_index(inplace=True, drop=True) + return points + + def assert_points(self, points_expected, m="Incorrect Line Data"): + """yote""" + if isinstance(points_expected, gpd.geodataframe.GeoDataFrame): + xy_expected = pd.DataFrame(columns=['x', 'y']) + xy_expected['x'] = points_expected.geometry.x + xy_expected['y'] = points_expected.geometry.y + xy_expected = xy_expected.sort_values(by="x") + xy_expected.reset_index(inplace=True, drop=True) + pd.testing.assert_frame_equal(left=self.get_points(), right=xy_expected) + else: + raise ValueError( + "points_expected is not expected type: GeoDataFrame" + ) + + ### LINES ### def _convert_multilines(self, df, column_title): From 6cd48e3c867e88e445878e941f1844800862ad0a Mon Sep 17 00:00:00 2001 From: nkorinek Date: Wed, 26 Feb 2020 16:43:03 -0700 Subject: [PATCH 02/39] Added in get_points() and assert_points() functions with tests --- matplotcheck/tests/test_vector.py | 56 +++++++++++++++++++++++++++++++ matplotcheck/vector.py | 9 +++-- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/matplotcheck/tests/test_vector.py b/matplotcheck/tests/test_vector.py index e65a0611..6c3b06f5 100644 --- a/matplotcheck/tests/test_vector.py +++ b/matplotcheck/tests/test_vector.py @@ -20,6 +20,28 @@ def poly_geo_plot(basic_polygon_gdf): return VectorTester(axis) +@pytest.fixture +def point_geo_plot(pd_gdf): + """Create a point plot for testing""" + fig, ax = plt.subplots() + + pd_gdf.plot(ax=ax) + ax.set_title("My Plot Title", fontsize=30) + ax.set_xlabel("x label") + ax.set_ylabel("y label") + + axis = plt.gca() + + return VectorTester(axis) + + +@pytest.fixture +def bad_pd_gdf(pd_gdf): + """Create a point geodataframe with slightly wrong values for testing""" + return gpd.GeoDataFrame(geometry=gpd.points_from_xy( + pd_gdf.geometry.x + 1, pd_gdf.geometry.y + 1) + ) + def test_list_of_polygons_check(poly_geo_plot, basic_polygon): """Check that the polygon assert works with a list of polygons.""" x, y = basic_polygon.exterior.coords.xy @@ -85,3 +107,37 @@ def test_polygon_custom_fail_message(poly_geo_plot, basic_polygon): poly_list = [(x[0] + 0.5, x[1]) for x in list(zip(x, y))] poly_geo_plot.assert_polygons(poly_list, m="Test Message") plt.close() + + +def test_point_geometry_pass(point_geo_plot, pd_gdf): + """Check that the point geometry test recognizes correct points.""" + point_geo_plot.assert_points(points_expected=pd_gdf) + + +def test_point_geometry_fail(point_geo_plot, bad_pd_gdf): + """Check that the point geometry test recognizes incorrect points.""" + with pytest.raises(AssertionError, match="Incorrect Point Data"): + point_geo_plot.assert_points(points_expected=bad_pd_gdf) + + +def test_assert_point_fails_list(point_geo_plot, pd_gdf): + """ + Check that the point geometry test fails anything that's not a + GeoDataFrame + """ + list_geo = [list(pd_gdf.geometry.x), list(pd_gdf.geometry.y)] + with pytest.raises(ValueError, match="points_expected is not expected"): + point_geo_plot.assert_points(points_expected=list_geo) + +def test_get_points(point_geo_plot, pd_gdf): + """Tests that get_points returns correct values""" + xy_values = point_geo_plot.get_points() + assert(list(sorted(xy_values.x)) == sorted(list(pd_gdf.geometry.x))) + assert(list(sorted(xy_values.y)) == sorted(list(pd_gdf.geometry.y))) + + +def test_assert_points_custom_message(point_geo_plot, bad_pd_gdf): + """Tests that a custom error message is passed.""" + message = "Test message" + with pytest.raises(AssertionError, match="Test message"): + point_geo_plot.assert_points(points_expected=bad_pd_gdf, m=message) diff --git a/matplotcheck/vector.py b/matplotcheck/vector.py index c52e4676..1242e411 100644 --- a/matplotcheck/vector.py +++ b/matplotcheck/vector.py @@ -243,7 +243,7 @@ def get_points(self): points.reset_index(inplace=True, drop=True) return points - def assert_points(self, points_expected, m="Incorrect Line Data"): + def assert_points(self, points_expected, m="Incorrect Point Data"): """yote""" if isinstance(points_expected, gpd.geodataframe.GeoDataFrame): xy_expected = pd.DataFrame(columns=['x', 'y']) @@ -251,7 +251,12 @@ def assert_points(self, points_expected, m="Incorrect Line Data"): xy_expected['y'] = points_expected.geometry.y xy_expected = xy_expected.sort_values(by="x") xy_expected.reset_index(inplace=True, drop=True) - pd.testing.assert_frame_equal(left=self.get_points(), right=xy_expected) + try: + pd.testing.assert_frame_equal( + left=self.get_points(), right=xy_expected + ) + except AssertionError: + raise AssertionError(m) else: raise ValueError( "points_expected is not expected type: GeoDataFrame" From 5e6a175f29591515af47aeb4f0a025e6685ca1d4 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Wed, 26 Feb 2020 16:47:19 -0700 Subject: [PATCH 03/39] Added proper documentation --- matplotcheck/vector.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/matplotcheck/vector.py b/matplotcheck/vector.py index 1242e411..07384fd6 100644 --- a/matplotcheck/vector.py +++ b/matplotcheck/vector.py @@ -238,13 +238,30 @@ def assert_collection_sorted_by_markersize(self, df_expected, sort_column): ) def get_points(self): - """yeet""" + """Returns a Pandas dataframe with all x, y values for points on axis. + + Returns + ------- + output: DataFrame with columns 'x' and 'y'. Each row represents one + points coordinates. + """ points = self.get_xy(points_only=True).sort_values(by="x") points.reset_index(inplace=True, drop=True) return points def assert_points(self, points_expected, m="Incorrect Point Data"): - """yote""" + """ + Asserts the point data in Axes ax is equal to points_expected data + with error message m. + If points_expected not a GeoDataFrame, test fails. + + Parameters + ---------- + points_expected : GeoDataFrame + GeoDataFrame with the expected points for the axis. + m : string (default = "Incorrect Point Data") + String error message if assertion is not met. + """ if isinstance(points_expected, gpd.geodataframe.GeoDataFrame): xy_expected = pd.DataFrame(columns=['x', 'y']) xy_expected['x'] = points_expected.geometry.x From 408ab38682a71c979e5defed7a3f4bb74528719b Mon Sep 17 00:00:00 2001 From: nkorinek Date: Wed, 26 Feb 2020 16:54:45 -0700 Subject: [PATCH 04/39] Small fix to please codacy --- matplotcheck/tests/test_vector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matplotcheck/tests/test_vector.py b/matplotcheck/tests/test_vector.py index 6c3b06f5..99ac3a95 100644 --- a/matplotcheck/tests/test_vector.py +++ b/matplotcheck/tests/test_vector.py @@ -23,7 +23,7 @@ def poly_geo_plot(basic_polygon_gdf): @pytest.fixture def point_geo_plot(pd_gdf): """Create a point plot for testing""" - fig, ax = plt.subplots() + _, ax = plt.subplots() pd_gdf.plot(ax=ax) ax.set_title("My Plot Title", fontsize=30) From 8325ed9c0bee00f44808baba7bc17cd5e9368f99 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Wed, 26 Feb 2020 17:06:20 -0700 Subject: [PATCH 05/39] black --- matplotcheck/tests/test_vector.py | 14 +++++++++----- matplotcheck/vector.py | 7 +++---- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/matplotcheck/tests/test_vector.py b/matplotcheck/tests/test_vector.py index 99ac3a95..952df150 100644 --- a/matplotcheck/tests/test_vector.py +++ b/matplotcheck/tests/test_vector.py @@ -38,9 +38,12 @@ def point_geo_plot(pd_gdf): @pytest.fixture def bad_pd_gdf(pd_gdf): """Create a point geodataframe with slightly wrong values for testing""" - return gpd.GeoDataFrame(geometry=gpd.points_from_xy( - pd_gdf.geometry.x + 1, pd_gdf.geometry.y + 1) - ) + return gpd.GeoDataFrame( + geometry=gpd.points_from_xy( + pd_gdf.geometry.x + 1, pd_gdf.geometry.y + 1 + ) + ) + def test_list_of_polygons_check(poly_geo_plot, basic_polygon): """Check that the polygon assert works with a list of polygons.""" @@ -129,11 +132,12 @@ def test_assert_point_fails_list(point_geo_plot, pd_gdf): with pytest.raises(ValueError, match="points_expected is not expected"): point_geo_plot.assert_points(points_expected=list_geo) + def test_get_points(point_geo_plot, pd_gdf): """Tests that get_points returns correct values""" xy_values = point_geo_plot.get_points() - assert(list(sorted(xy_values.x)) == sorted(list(pd_gdf.geometry.x))) - assert(list(sorted(xy_values.y)) == sorted(list(pd_gdf.geometry.y))) + assert list(sorted(xy_values.x)) == sorted(list(pd_gdf.geometry.x)) + assert list(sorted(xy_values.y)) == sorted(list(pd_gdf.geometry.y)) def test_assert_points_custom_message(point_geo_plot, bad_pd_gdf): diff --git a/matplotcheck/vector.py b/matplotcheck/vector.py index 07384fd6..988cc677 100644 --- a/matplotcheck/vector.py +++ b/matplotcheck/vector.py @@ -263,9 +263,9 @@ def assert_points(self, points_expected, m="Incorrect Point Data"): String error message if assertion is not met. """ if isinstance(points_expected, gpd.geodataframe.GeoDataFrame): - xy_expected = pd.DataFrame(columns=['x', 'y']) - xy_expected['x'] = points_expected.geometry.x - xy_expected['y'] = points_expected.geometry.y + xy_expected = pd.DataFrame(columns=["x", "y"]) + xy_expected["x"] = points_expected.geometry.x + xy_expected["y"] = points_expected.geometry.y xy_expected = xy_expected.sort_values(by="x") xy_expected.reset_index(inplace=True, drop=True) try: @@ -279,7 +279,6 @@ def assert_points(self, points_expected, m="Incorrect Point Data"): "points_expected is not expected type: GeoDataFrame" ) - ### LINES ### def _convert_multilines(self, df, column_title): From 7ac5d41ac3131913dd7d3dbb8c5fd2e6f571bcc1 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Thu, 27 Feb 2020 10:38:39 -0700 Subject: [PATCH 06/39] Updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index de1bc962..aac3da87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +* Created functions to test point geometries in VectorTester (@nkorinek, #176) ## [0.1.2] * Created a vignette covering the testing of histograms (@ryla5068, #149) From 678fdf418dd1388dbd30e7ed124270580f9c013f Mon Sep 17 00:00:00 2001 From: nkorinek Date: Fri, 6 Mar 2020 17:23:49 -0700 Subject: [PATCH 07/39] First round of tests for vector --- matplotcheck/tests/test_vector.py | 108 ++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/matplotcheck/tests/test_vector.py b/matplotcheck/tests/test_vector.py index 952df150..ed246c2c 100644 --- a/matplotcheck/tests/test_vector.py +++ b/matplotcheck/tests/test_vector.py @@ -2,6 +2,7 @@ import pytest import matplotlib.pyplot as plt import geopandas as gpd +from shapely.geometry import LineString from matplotcheck.vector import VectorTester @@ -45,6 +46,60 @@ def bad_pd_gdf(pd_gdf): ) +@pytest.fixture +def two_line_gdf(): + """ Create Line Objects For Testing """ + linea = LineString([(1, 1), (2, 2), (3, 2), (5, 3)]) + lineb = LineString([(3, 4), (5, 7), (12, 2), (10, 5), (9, 7.5)]) + gdf = gpd.GeoDataFrame([1, 2], geometry=[linea, lineb], crs="epsg:4326") + return gdf + + +@pytest.fixture +def multi_line_gdf(two_line_gdf): + """ Create a multi-line GeoDataFrame. + This has one multi line and another regular line. + """ + # Create a single and multi line object + multiline_feat = two_line_gdf.unary_union + linec = LineString([(2, 1), (3, 1), (4, 1), (5, 2)]) + out_df = gpd.GeoDataFrame( + geometry=gpd.GeoSeries([multiline_feat, linec]), crs="epsg:4326", + ) + out_df["attr"] = ["road", "stream"] + return out_df + + +@pytest.fixture +def poly_line_plot(two_line_gdf): + """Create a line vector tester object.""" + _, ax = plt.subplots() + + two_line_gdf.plot(ax=ax) + ax.set_title("My Plot Title", fontsize=30) + ax.set_xlabel("x label") + ax.set_ylabel("y label") + + axis = plt.gca() + + return VectorTester(axis) + + +@pytest.fixture +def poly_multiline_plot(multi_line_gdf): + """Create a multiline vector tester object.""" + _, ax = plt.subplots() + + multi_line_gdf.plot(ax=ax, column="attr") + ax.set_title("My Plot Title", fontsize=30) + ax.set_xlabel("x label") + ax.set_ylabel("y label") + + axis = plt.gca() + + return VectorTester(axis) + + def test_list_of_polygons_check(poly_geo_plot, basic_polygon): """Check that the polygon assert works with a list of polygons.""" x, y = basic_polygon.exterior.coords.xy @@ -145,3 +200,56 @@ def test_assert_points_custom_message(point_geo_plot, bad_pd_gdf): message = "Test message" with pytest.raises(AssertionError, match="Test message"): point_geo_plot.assert_points(points_expected=bad_pd_gdf, m=message) + + +def test_assert_line_geo(poly_line_plot, two_line_gdf): + """Test that lines are asserted correctly""" + poly_line_plot.assert_lines(two_line_gdf) + plt.close() + + +def test_assert_multiline_geo(poly_multiline_plot, multi_line_gdf): + """Test that multi lines are asserted correctly""" + poly_multiline_plot.assert_lines(multi_line_gdf) + plt.close() + +def test_assert_line_geo_fail(poly_line_plot, multi_line_gdf): + """Test that lines fail correctly""" + with pytest.raises(AssertionError, match="Incorrect Line Data"): + poly_line_plot.assert_lines(multi_line_gdf) + plt.close() + +def test_assert_multiline_geo_fail(poly_multiline_plot, two_line_gdf): + """Test that multi lines fail correctly""" + with pytest.raises(AssertionError, match="Incorrect Line Data"): + poly_multiline_plot.assert_lines(two_line_gdf) + plt.close() + +def test_assert_line_fails_list(poly_line_plot): + """Test that assert_lines fails when passed a list""" + linelist = [ + [(1, 1), (2, 2), (3, 2), (5, 3)], + [(3, 4), (5, 7), (12, 2), (10, 5), (9, 7.5)], + ] + with pytest.raises(ValueError, match="lines_expected is not expected ty"): + poly_line_plot.assert_lines(linelist) + plt.close() + +def test_assert_line_geo_passed_nothing(poly_line_plot): + """Test that assertion passes when passed None""" + poly_line_plot.assert_lines(None) + plt.close() + +def test_get_lines_geometry(poly_line_plot): + """Test that get_lines returns the proper values""" + lines = [(LineString(i[0])) for i in poly_line_plot.get_lines().values] + geometries = gpd.GeoDataFrame(geometry=lines) + poly_line_plot.assert_lines(geometries) + plt.close() + + +# Broken right now, not sure why +# def test_assert_lines_grouped_by_type(poly_multiline_plot, multi_line_gdf): +# """Test that assert works for grouped line plots""" +# poly_multiline_plot.assert_lines_grouped_by_type(multi_line_gdf, "attr") +# plt.close() From 50a93607fc2562042fc2a8f3cb11cb92f9056b95 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Fri, 6 Mar 2020 18:07:11 -0700 Subject: [PATCH 08/39] black --- matplotcheck/tests/test_vector.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/matplotcheck/tests/test_vector.py b/matplotcheck/tests/test_vector.py index ed246c2c..bfed61ec 100644 --- a/matplotcheck/tests/test_vector.py +++ b/matplotcheck/tests/test_vector.py @@ -213,18 +213,21 @@ def test_assert_multiline_geo(poly_multiline_plot, multi_line_gdf): poly_multiline_plot.assert_lines(multi_line_gdf) plt.close() + def test_assert_line_geo_fail(poly_line_plot, multi_line_gdf): """Test that lines fail correctly""" with pytest.raises(AssertionError, match="Incorrect Line Data"): poly_line_plot.assert_lines(multi_line_gdf) plt.close() + def test_assert_multiline_geo_fail(poly_multiline_plot, two_line_gdf): """Test that multi lines fail correctly""" with pytest.raises(AssertionError, match="Incorrect Line Data"): poly_multiline_plot.assert_lines(two_line_gdf) plt.close() + def test_assert_line_fails_list(poly_line_plot): """Test that assert_lines fails when passed a list""" linelist = [ @@ -235,11 +238,13 @@ def test_assert_line_fails_list(poly_line_plot): poly_line_plot.assert_lines(linelist) plt.close() + def test_assert_line_geo_passed_nothing(poly_line_plot): """Test that assertion passes when passed None""" poly_line_plot.assert_lines(None) plt.close() + def test_get_lines_geometry(poly_line_plot): """Test that get_lines returns the proper values""" lines = [(LineString(i[0])) for i in poly_line_plot.get_lines().values] From c75e42152e3ec06d0f8c4feadfca6703edba505d Mon Sep 17 00:00:00 2001 From: nkorinek Date: Mon, 16 Mar 2020 15:41:13 -0600 Subject: [PATCH 09/39] Rough draft for bug fix --- matplotcheck/vector.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/matplotcheck/vector.py b/matplotcheck/vector.py index 45018a68..e6c8e7c4 100644 --- a/matplotcheck/vector.py +++ b/matplotcheck/vector.py @@ -270,11 +270,23 @@ def assert_points(self, points_expected, m="Incorrect Point Data"): String error message if assertion is not met. """ if isinstance(points_expected, gpd.geodataframe.GeoDataFrame): + points = self.get_points() xy_expected = pd.DataFrame(columns=["x", "y"]) xy_expected["x"] = points_expected.geometry.x xy_expected["y"] = points_expected.geometry.y xy_expected = xy_expected.sort_values(by="x") xy_expected.reset_index(inplace=True, drop=True) + if len(points) != len(xy_expected): + points_zeros = (points['x'] == 0) & (points['y'] == 0) + if points_zeros.any(): + expected_zeros = (xy_expected['x'] == 0) & (xy_expected['y'] == 0) + keep = expected_zeros.sum() + zeros_index_vals = points_zeros.index[points_zeros.tolist()] + for i in range(keep): + points_zeros.at[zeros_index_vals[i]] = False + points = points[~points_zeros].reset_index(inplace=True, drop=True) + else: + raise AssertionError("points_expected's length does not match the stored data's length.") try: pd.testing.assert_frame_equal( left=self.get_points(), right=xy_expected From 075052cb53f62b2a63e5addf17ed2c4fda2c32a6 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Mon, 16 Mar 2020 15:57:34 -0600 Subject: [PATCH 10/39] Fixed bug with multiple geometries plotted alongside bug with identical x values causing failure! --- matplotcheck/vector.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/matplotcheck/vector.py b/matplotcheck/vector.py index e6c8e7c4..4b694f2e 100644 --- a/matplotcheck/vector.py +++ b/matplotcheck/vector.py @@ -252,7 +252,7 @@ def get_points(self): output: DataFrame with columns 'x' and 'y'. Each row represents one points coordinates. """ - points = self.get_xy(points_only=True).sort_values(by="x") + points = self.get_xy(points_only=True).sort_values(by=["x", "y"]) points.reset_index(inplace=True, drop=True) return points @@ -274,23 +274,28 @@ def assert_points(self, points_expected, m="Incorrect Point Data"): xy_expected = pd.DataFrame(columns=["x", "y"]) xy_expected["x"] = points_expected.geometry.x xy_expected["y"] = points_expected.geometry.y - xy_expected = xy_expected.sort_values(by="x") + xy_expected = xy_expected.sort_values(by=["x", "y"]) xy_expected.reset_index(inplace=True, drop=True) if len(points) != len(xy_expected): - points_zeros = (points['x'] == 0) & (points['y'] == 0) + points_zeros = (points["x"] == 0) & (points["y"] == 0) if points_zeros.any(): - expected_zeros = (xy_expected['x'] == 0) & (xy_expected['y'] == 0) + expected_zeros = (xy_expected["x"] == 0) & ( + xy_expected["y"] == 0 + ) keep = expected_zeros.sum() - zeros_index_vals = points_zeros.index[points_zeros.tolist()] + zeros_index_vals = points_zeros.index[ + points_zeros.tolist() + ] for i in range(keep): - points_zeros.at[zeros_index_vals[i]] = False - points = points[~points_zeros].reset_index(inplace=True, drop=True) + points_zeros.at[zeros_index_vals[i]] = False + points = points[~points_zeros].reset_index(drop=True) else: - raise AssertionError("points_expected's length does not match the stored data's length.") + raise AssertionError( + "points_expected's length does not match the stored" + "data's length." + ) try: - pd.testing.assert_frame_equal( - left=self.get_points(), right=xy_expected - ) + pd.testing.assert_frame_equal(left=points, right=xy_expected) except AssertionError: raise AssertionError(m) else: From a7927259eaf243458a2e6701f538f3647ae1c4b4 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Mon, 16 Mar 2020 16:00:03 -0600 Subject: [PATCH 11/39] typo --- matplotcheck/vector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matplotcheck/vector.py b/matplotcheck/vector.py index 4b694f2e..a2894079 100644 --- a/matplotcheck/vector.py +++ b/matplotcheck/vector.py @@ -216,7 +216,7 @@ def sort_collection_by_markersize(self): return df def assert_collection_sorted_by_markersize(self, df_expected, sort_column): - """Asserts a collection of points vary in size by column expresse din + """Asserts a collection of points vary in size by column expressed in sort_column Parameters From 6876a504d6c9c3d09ba4b861da600d9a80d71382 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Tue, 17 Mar 2020 13:02:31 -0600 Subject: [PATCH 12/39] Fixed small bug with markersize --- matplotcheck/vector.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/matplotcheck/vector.py b/matplotcheck/vector.py index a2894079..038a4b4d 100644 --- a/matplotcheck/vector.py +++ b/matplotcheck/vector.py @@ -196,22 +196,23 @@ def sort_collection_by_markersize(self): """ df = pd.DataFrame(columns=("x", "y", "markersize")) for c in self.ax.collections: - offsets, markersizes = c.get_offsets(), c.get_sizes() - x_data, y_data = ( - [offset[0] for offset in offsets], - [offset[1] for offset in offsets], - ) - if len(markersizes) == 1: - markersize = [markersizes[0]] * len(offsets) - df2 = pd.DataFrame( - {"x": x_data, "y": y_data, "markersize": markersize} - ) - df = df.append(df2) - elif len(markersizes) == len(offsets): - df2 = pd.DataFrame( - {"x": x_data, "y": y_data, "markersize": markersizes} + if isinstance(c, matplotlib.collections.PathCollection): + offsets, markersizes = c.get_offsets(), c.get_sizes() + x_data, y_data = ( + [offset[0] for offset in offsets], + [offset[1] for offset in offsets], ) - df = df.append(df2) + if len(markersizes) == 1: + markersize = [markersizes[0]] * len(offsets) + df2 = pd.DataFrame( + {"x": x_data, "y": y_data, "markersize": markersize} + ) + df = df.append(df2) + elif len(markersizes) == len(offsets): + df2 = pd.DataFrame( + {"x": x_data, "y": y_data, "markersize": markersizes} + ) + df = df.append(df2) df = df.sort_values(by="markersize").reset_index(drop=True) return df From b73e4ef761fd41d52d5b650f367ec780464c5177 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Tue, 17 Mar 2020 13:20:25 -0600 Subject: [PATCH 13/39] Added comments explaining code --- matplotcheck/vector.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/matplotcheck/vector.py b/matplotcheck/vector.py index 038a4b4d..c7410820 100644 --- a/matplotcheck/vector.py +++ b/matplotcheck/vector.py @@ -277,7 +277,10 @@ def assert_points(self, points_expected, m="Incorrect Point Data"): xy_expected["y"] = points_expected.geometry.y xy_expected = xy_expected.sort_values(by=["x", "y"]) xy_expected.reset_index(inplace=True, drop=True) + # Fix for failure if more than points were plotted in matplotlib if len(points) != len(xy_expected): + # Checks if there are extra 0, 0 coords in the DataFrame + # returned from self.get_points and removes them. points_zeros = (points["x"] == 0) & (points["y"] == 0) if points_zeros.any(): expected_zeros = (xy_expected["x"] == 0) & ( From c53603f352df34acd766348e599511eebd517f53 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Tue, 17 Mar 2020 14:21:11 -0600 Subject: [PATCH 14/39] rough drafts of more tests --- matplotcheck/tests/conftest.py | 21 ++++++++------ matplotcheck/tests/test_vector.py | 47 +++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/matplotcheck/tests/conftest.py b/matplotcheck/tests/conftest.py index 17217454..7ccb1bba 100644 --- a/matplotcheck/tests/conftest.py +++ b/matplotcheck/tests/conftest.py @@ -32,14 +32,14 @@ def pd_gdf(): """Create a geopandas GeoDataFrame for testing""" df = pd.DataFrame( { - "lat": np.random.randint(-85, 85, size=100), - "lon": np.random.randint(-180, 180, size=100), + "lat": np.random.randint(-85, 85, size=5), + "lon": np.random.randint(-180, 180, size=5), } ) gdf = gpd.GeoDataFrame( - {"A": np.arange(100)}, geometry=gpd.points_from_xy(df.lon, df.lat) + {"A": np.arange(5)}, geometry=gpd.points_from_xy(df.lon, df.lat) ) - + gdf["attr"] = ["Tree", "Tree", "Bush", "Bush", "Bush"] return gdf @@ -159,11 +159,16 @@ def pt_time_line_plt(pd_df_timeseries): def pt_geo_plot(pd_gdf): """Create a geo plot for testing""" fig, ax = plt.subplots() + size = 0 + point_symb = {"Tree": "green", "Bush": "brown"} - pd_gdf.plot(ax=ax) - ax.set_title("My Plot Title", fontsize=30) - ax.set_xlabel("x label") - ax.set_ylabel("y label") + for ctype, points in pd_gdf.groupby('attr'): + color = point_symb[ctype] + label = ctype + size += 100 + points.plot(color=color, ax=ax, label=label, markersize=size) + + ax.legend(title="Legend", loc=(1.1, .1)) axis = plt.gca() diff --git a/matplotcheck/tests/test_vector.py b/matplotcheck/tests/test_vector.py index bfed61ec..203aa923 100644 --- a/matplotcheck/tests/test_vector.py +++ b/matplotcheck/tests/test_vector.py @@ -100,6 +100,26 @@ def poly_multiline_plot(multi_line_gdf): return VectorTester(axis) +@pytest.fixture +def pt_geo_plot_bad_legend(pd_gdf): + """Create a geo plot for testing""" + fig, ax = plt.subplots() + size = 0 + point_symb = {"Tree": "green", "Bush": "brown"} + + for ctype, points in pd_gdf.groupby('attr'): + color = point_symb[ctype] + label = ctype + size += 100 + points.plot(color=color, ax=ax, label=label, markersize=size) + + plt.gca().add_artist(ax.legend(title="Legend", loc=(0, .1))) + ax.legend(title="Legend 2", loc=(.1, .1)) + axis = plt.gca() + + return VectorTester(axis) + + def test_list_of_polygons_check(poly_geo_plot, basic_polygon): """Check that the polygon assert works with a list of polygons.""" x, y = basic_polygon.exterior.coords.xy @@ -253,6 +273,33 @@ def test_get_lines_geometry(poly_line_plot): plt.close() +def test_legend_no_overlay_pass(pt_geo_plot): + """Test that no_overlay passes when the legend doesn't overlay""" + pt_geo_plot.assert_legend_no_overlay_content() + + +def test_legend_no_overlay_pass(pt_geo_plot): + """Test that no_overlay passes when the legend doesn't overlay""" + pt_geo_plot.assert_legend_no_overlay_content() + + +def test_legend_no_overlay_fail(pt_geo_plot_bad_legend): + """Test that no_overlay fails when the legends do overlay""" + with pytest.raises(AssertionError, match="Legend overlays plot contents"): + pt_geo_plot_bad_legend.assert_legend_no_overlay_content() + + +def test_legends_no_overlap_pass(pt_geo_plot): + """Test that legends pass if they don't overlay""" + pt_geo_plot.assert_no_legend_overlap() + + +def test_legend_no_overlap_fail(pt_geo_plot_bad_legend): + """Test that legends fail if they overlap""" + with pytest.raises(AssertionError, match="Legends overlap eachother"): + pt_geo_plot_bad_legend.assert_no_legend_overlap() + + # Broken right now, not sure why # def test_assert_lines_grouped_by_type(poly_multiline_plot, multi_line_gdf): # """Test that assert works for grouped line plots""" From 8c6a87da29a2ced4e42923b0497bb893b7bc92cd Mon Sep 17 00:00:00 2001 From: nkorinek Date: Tue, 17 Mar 2020 16:29:35 -0600 Subject: [PATCH 15/39] Added more tests for legends --- matplotcheck/tests/conftest.py | 4 ++-- matplotcheck/tests/test_vector.py | 25 +++++++++++++------------ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/matplotcheck/tests/conftest.py b/matplotcheck/tests/conftest.py index 7ccb1bba..2d628a74 100644 --- a/matplotcheck/tests/conftest.py +++ b/matplotcheck/tests/conftest.py @@ -162,13 +162,13 @@ def pt_geo_plot(pd_gdf): size = 0 point_symb = {"Tree": "green", "Bush": "brown"} - for ctype, points in pd_gdf.groupby('attr'): + for ctype, points in pd_gdf.groupby("attr"): color = point_symb[ctype] label = ctype size += 100 points.plot(color=color, ax=ax, label=label, markersize=size) - ax.legend(title="Legend", loc=(1.1, .1)) + ax.legend(title="Legend", loc=(1.1, 0.1)) axis = plt.gca() diff --git a/matplotcheck/tests/test_vector.py b/matplotcheck/tests/test_vector.py index 203aa923..60d562f4 100644 --- a/matplotcheck/tests/test_vector.py +++ b/matplotcheck/tests/test_vector.py @@ -107,14 +107,14 @@ def pt_geo_plot_bad_legend(pd_gdf): size = 0 point_symb = {"Tree": "green", "Bush": "brown"} - for ctype, points in pd_gdf.groupby('attr'): + for ctype, points in pd_gdf.groupby("attr"): color = point_symb[ctype] label = ctype size += 100 points.plot(color=color, ax=ax, label=label, markersize=size) - plt.gca().add_artist(ax.legend(title="Legend", loc=(0, .1))) - ax.legend(title="Legend 2", loc=(.1, .1)) + plt.gca().add_artist(ax.legend(title="Legend", loc=(0, 0.1))) + plt.gca().add_artist(ax.legend(title="Legend 2", loc=(0.1, 0.1))) axis = plt.gca() return VectorTester(axis) @@ -283,10 +283,11 @@ def test_legend_no_overlay_pass(pt_geo_plot): pt_geo_plot.assert_legend_no_overlay_content() -def test_legend_no_overlay_fail(pt_geo_plot_bad_legend): - """Test that no_overlay fails when the legends do overlay""" - with pytest.raises(AssertionError, match="Legend overlays plot contents"): - pt_geo_plot_bad_legend.assert_legend_no_overlay_content() +# Broken right now, not sure why +# def test_legend_no_overlay_fail(pt_geo_plot_bad_legend): +# """Test that no_overlay fails when the legends do overlay""" +# with pytest.raises(AssertionError, match="Legend overlays plot contents"): +# pt_geo_plot_bad_legend.assert_legend_no_overlay_content() def test_legends_no_overlap_pass(pt_geo_plot): @@ -294,14 +295,14 @@ def test_legends_no_overlap_pass(pt_geo_plot): pt_geo_plot.assert_no_legend_overlap() -def test_legend_no_overlap_fail(pt_geo_plot_bad_legend): - """Test that legends fail if they overlap""" - with pytest.raises(AssertionError, match="Legends overlap eachother"): - pt_geo_plot_bad_legend.assert_no_legend_overlap() +# Broken right now, not sure why +# def test_legend_no_overlap_fail(pt_geo_plot_bad_legend): +# """Test that legends fail if they overlap""" +# with pytest.raises(AssertionError, match="Legends overlap eachother"): +# pt_geo_plot_bad_legend.assert_no_legend_overlap() # Broken right now, not sure why # def test_assert_lines_grouped_by_type(poly_multiline_plot, multi_line_gdf): # """Test that assert works for grouped line plots""" # poly_multiline_plot.assert_lines_grouped_by_type(multi_line_gdf, "attr") -# plt.close() From 89a2adcb9e1e962389e3c13b1a43726740beb782 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Tue, 17 Mar 2020 16:49:28 -0600 Subject: [PATCH 16/39] Added more tests, and took out broken tests --- matplotcheck/tests/test_vector.py | 47 +++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/matplotcheck/tests/test_vector.py b/matplotcheck/tests/test_vector.py index 60d562f4..ab77e1ef 100644 --- a/matplotcheck/tests/test_vector.py +++ b/matplotcheck/tests/test_vector.py @@ -101,7 +101,7 @@ def poly_multiline_plot(multi_line_gdf): @pytest.fixture -def pt_geo_plot_bad_legend(pd_gdf): +def pt_geo_plot(pd_gdf): """Create a geo plot for testing""" fig, ax = plt.subplots() size = 0 @@ -113,8 +113,18 @@ def pt_geo_plot_bad_legend(pd_gdf): size += 100 points.plot(color=color, ax=ax, label=label, markersize=size) - plt.gca().add_artist(ax.legend(title="Legend", loc=(0, 0.1))) - plt.gca().add_artist(ax.legend(title="Legend 2", loc=(0.1, 0.1))) + ax.legend(title="Legend", loc=(1.1, 0.1)) + + axis = plt.gca() + + return VectorTester(axis) + + +@pytest.fixture +def pt_geo_plot_bad(pd_gdf): + """Create a geo plot for testing""" + fig, ax = plt.subplots() + pd_gdf.plot(ax=ax, column="attr") axis = plt.gca() return VectorTester(axis) @@ -273,14 +283,15 @@ def test_get_lines_geometry(poly_line_plot): plt.close() -def test_legend_no_overlay_pass(pt_geo_plot): - """Test that no_overlay passes when the legend doesn't overlay""" - pt_geo_plot.assert_legend_no_overlay_content() +# def test_legend_no_overlay_pass(pt_geo_plot): +# """Test that no_overlay passes when the legend doesn't overlay""" +# pt_geo_plot.assert_legend_no_overlay_content() -def test_legend_no_overlay_pass(pt_geo_plot): - """Test that no_overlay passes when the legend doesn't overlay""" - pt_geo_plot.assert_legend_no_overlay_content() +# Broken right now, not sure why +# def test_legend_no_overlay_pass(pt_geo_plot): +# """Test that no_overlay passes when the legend doesn't overlay""" +# pt_geo_plot.assert_legend_no_overlay_content() # Broken right now, not sure why @@ -290,9 +301,10 @@ def test_legend_no_overlay_pass(pt_geo_plot): # pt_geo_plot_bad_legend.assert_legend_no_overlay_content() -def test_legends_no_overlap_pass(pt_geo_plot): - """Test that legends pass if they don't overlay""" - pt_geo_plot.assert_no_legend_overlap() +# Broken right now, not sure why +# def test_legends_no_overlap_pass(pt_geo_plot): +# """Test that legends pass if they don't overlay""" +# pt_geo_plot.assert_no_legend_overlap() # Broken right now, not sure why @@ -306,3 +318,14 @@ def test_legends_no_overlap_pass(pt_geo_plot): # def test_assert_lines_grouped_by_type(poly_multiline_plot, multi_line_gdf): # """Test that assert works for grouped line plots""" # poly_multiline_plot.assert_lines_grouped_by_type(multi_line_gdf, "attr") + + +def test_points_sorted_by_markersize_pass(pt_geo_plot, pd_gdf): + """Test points sorted by size of attribute pass""" + pt_geo_plot.assert_collection_sorted_by_markersize(pd_gdf, "attr") + + +def test_points_sorted_by_markersize_fail(pt_geo_plot_bad, pd_gdf): + """Test points sorted by size of attribute""" + with pytest.raises(AssertionError, match="Markersize not based on"): + pt_geo_plot_bad.assert_collection_sorted_by_markersize(pd_gdf, "attr") From e70c887cf3e8d2716e1c43b1798218ed85478e81 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Tue, 17 Mar 2020 16:52:07 -0600 Subject: [PATCH 17/39] small codacy fix --- matplotcheck/tests/test_vector.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/matplotcheck/tests/test_vector.py b/matplotcheck/tests/test_vector.py index ab77e1ef..a8c1f41a 100644 --- a/matplotcheck/tests/test_vector.py +++ b/matplotcheck/tests/test_vector.py @@ -103,7 +103,7 @@ def poly_multiline_plot(multi_line_gdf): @pytest.fixture def pt_geo_plot(pd_gdf): """Create a geo plot for testing""" - fig, ax = plt.subplots() + _, ax = plt.subplots() size = 0 point_symb = {"Tree": "green", "Bush": "brown"} @@ -123,7 +123,7 @@ def pt_geo_plot(pd_gdf): @pytest.fixture def pt_geo_plot_bad(pd_gdf): """Create a geo plot for testing""" - fig, ax = plt.subplots() + _, ax = plt.subplots() pd_gdf.plot(ax=ax, column="attr") axis = plt.gca() From 7cf2ec7843379d8c8ceb478543e6fb400e837759 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Wed, 18 Mar 2020 10:13:22 -0600 Subject: [PATCH 18/39] Fixed test! --- matplotcheck/tests/test_vector.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/matplotcheck/tests/test_vector.py b/matplotcheck/tests/test_vector.py index a8c1f41a..be496d89 100644 --- a/matplotcheck/tests/test_vector.py +++ b/matplotcheck/tests/test_vector.py @@ -4,6 +4,8 @@ import geopandas as gpd from shapely.geometry import LineString from matplotcheck.vector import VectorTester +import matplotlib +matplotlib.use('Agg') @pytest.fixture @@ -314,10 +316,9 @@ def test_get_lines_geometry(poly_line_plot): # pt_geo_plot_bad_legend.assert_no_legend_overlap() -# Broken right now, not sure why -# def test_assert_lines_grouped_by_type(poly_multiline_plot, multi_line_gdf): -# """Test that assert works for grouped line plots""" -# poly_multiline_plot.assert_lines_grouped_by_type(multi_line_gdf, "attr") +def test_assert_lines_grouped_by_type(poly_multiline_plot, multi_line_gdf): + """Test that assert works for grouped line plots""" + poly_multiline_plot.assert_lines_grouped_by_type(multi_line_gdf, "attr") def test_points_sorted_by_markersize_pass(pt_geo_plot, pd_gdf): From d2a1972736d60a9feb2c279fac762731f41e1abd Mon Sep 17 00:00:00 2001 From: nkorinek Date: Wed, 18 Mar 2020 10:15:01 -0600 Subject: [PATCH 19/39] Taking out redundant tests --- matplotcheck/vector.py | 57 ------------------------------------------ 1 file changed, 57 deletions(-) diff --git a/matplotcheck/vector.py b/matplotcheck/vector.py index c7410820..655a1e6c 100644 --- a/matplotcheck/vector.py +++ b/matplotcheck/vector.py @@ -21,63 +21,6 @@ def __init__(self, ax): """Initialize the vector tester""" super(VectorTester, self).__init__(ax) - def assert_legend_no_overlay_content( - self, m="Legend overlays plot contents" - ): - """Asserts that each legend does not overlay plot contents with error - message m - - Parameters - --------- - m: string - error message if assertion is not met - """ - plot_extent = self.ax.get_window_extent().get_points() - legends = self.get_legends() - for leg in legends: - leg_extent = leg.get_window_extent().get_points() - legend_left = leg_extent[1][0] < plot_extent[0][0] - legend_right = leg_extent[0][0] > plot_extent[1][0] - legend_below = leg_extent[1][1] < plot_extent[0][1] - assert legend_left or legend_right or legend_below, m - - def _legends_overlap(self, b1, b2): - """Helper function for assert_no_legend_overlap - Boolean value if points of window extents for b1 and b2 overlap - - Parameters - ---------- - b1: bounding box of window extents - b2: bounding box of window extents - - Returns - ------ - boolean value that says if bounding boxes b1 and b2 overlap - """ - x_overlap = (b1[0][0] <= b2[1][0] and b1[0][0] >= b2[0][0]) or ( - b1[1][0] <= b2[1][0] and b1[1][0] >= b2[0][0] - ) - y_overlap = (b1[0][1] <= b2[1][1] and b1[0][1] >= b2[0][1]) or ( - b1[1][1] <= b2[1][1] and b1[1][1] >= b2[0][1] - ) - return x_overlap and y_overlap - - def assert_no_legend_overlap(self, m="Legends overlap eachother"): - """Asserts there are no two legends in Axes ax that overlap each other - with error message m - - Parameters - ---------- - m: string error message if assertion is not met - """ - legends = self.get_legends() - n = len(legends) - for i in range(n - 1): - leg_extent1 = legends[i].get_window_extent().get_points() - for j in range(i + 1, n): - leg_extent2 = legends[j].get_window_extent().get_points() - assert not self._legends_overlap(leg_extent1, leg_extent2), m - """ Check Data """ def _convert_length(self, arr, n): From 46804dbdefbb4fb22057fa8f0c6fae61840c0dba Mon Sep 17 00:00:00 2001 From: nkorinek Date: Wed, 18 Mar 2020 10:21:33 -0600 Subject: [PATCH 20/39] Took out unneccesary tests --- matplotcheck/tests/test_vector.py | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/matplotcheck/tests/test_vector.py b/matplotcheck/tests/test_vector.py index be496d89..b5f7a7a9 100644 --- a/matplotcheck/tests/test_vector.py +++ b/matplotcheck/tests/test_vector.py @@ -285,37 +285,6 @@ def test_get_lines_geometry(poly_line_plot): plt.close() -# def test_legend_no_overlay_pass(pt_geo_plot): -# """Test that no_overlay passes when the legend doesn't overlay""" -# pt_geo_plot.assert_legend_no_overlay_content() - - -# Broken right now, not sure why -# def test_legend_no_overlay_pass(pt_geo_plot): -# """Test that no_overlay passes when the legend doesn't overlay""" -# pt_geo_plot.assert_legend_no_overlay_content() - - -# Broken right now, not sure why -# def test_legend_no_overlay_fail(pt_geo_plot_bad_legend): -# """Test that no_overlay fails when the legends do overlay""" -# with pytest.raises(AssertionError, match="Legend overlays plot contents"): -# pt_geo_plot_bad_legend.assert_legend_no_overlay_content() - - -# Broken right now, not sure why -# def test_legends_no_overlap_pass(pt_geo_plot): -# """Test that legends pass if they don't overlay""" -# pt_geo_plot.assert_no_legend_overlap() - - -# Broken right now, not sure why -# def test_legend_no_overlap_fail(pt_geo_plot_bad_legend): -# """Test that legends fail if they overlap""" -# with pytest.raises(AssertionError, match="Legends overlap eachother"): -# pt_geo_plot_bad_legend.assert_no_legend_overlap() - - def test_assert_lines_grouped_by_type(poly_multiline_plot, multi_line_gdf): """Test that assert works for grouped line plots""" poly_multiline_plot.assert_lines_grouped_by_type(multi_line_gdf, "attr") From ccd3ba3856a965e884085dbe0256d16bd9d778a4 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Wed, 18 Mar 2020 10:24:12 -0600 Subject: [PATCH 21/39] Added plt.close --- matplotcheck/tests/test_vector.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/matplotcheck/tests/test_vector.py b/matplotcheck/tests/test_vector.py index b5f7a7a9..51f97a8d 100644 --- a/matplotcheck/tests/test_vector.py +++ b/matplotcheck/tests/test_vector.py @@ -5,7 +5,8 @@ from shapely.geometry import LineString from matplotcheck.vector import VectorTester import matplotlib -matplotlib.use('Agg') + +matplotlib.use("Agg") @pytest.fixture @@ -202,12 +203,14 @@ def test_polygon_custom_fail_message(poly_geo_plot, basic_polygon): def test_point_geometry_pass(point_geo_plot, pd_gdf): """Check that the point geometry test recognizes correct points.""" point_geo_plot.assert_points(points_expected=pd_gdf) + plt.close() def test_point_geometry_fail(point_geo_plot, bad_pd_gdf): """Check that the point geometry test recognizes incorrect points.""" with pytest.raises(AssertionError, match="Incorrect Point Data"): point_geo_plot.assert_points(points_expected=bad_pd_gdf) + plt.close() def test_assert_point_fails_list(point_geo_plot, pd_gdf): @@ -218,6 +221,7 @@ def test_assert_point_fails_list(point_geo_plot, pd_gdf): list_geo = [list(pd_gdf.geometry.x), list(pd_gdf.geometry.y)] with pytest.raises(ValueError, match="points_expected is not expected"): point_geo_plot.assert_points(points_expected=list_geo) + plt.close() def test_get_points(point_geo_plot, pd_gdf): @@ -225,6 +229,7 @@ def test_get_points(point_geo_plot, pd_gdf): xy_values = point_geo_plot.get_points() assert list(sorted(xy_values.x)) == sorted(list(pd_gdf.geometry.x)) assert list(sorted(xy_values.y)) == sorted(list(pd_gdf.geometry.y)) + plt.close() def test_assert_points_custom_message(point_geo_plot, bad_pd_gdf): @@ -232,6 +237,7 @@ def test_assert_points_custom_message(point_geo_plot, bad_pd_gdf): message = "Test message" with pytest.raises(AssertionError, match="Test message"): point_geo_plot.assert_points(points_expected=bad_pd_gdf, m=message) + plt.close() def test_assert_line_geo(poly_line_plot, two_line_gdf): @@ -288,14 +294,17 @@ def test_get_lines_geometry(poly_line_plot): def test_assert_lines_grouped_by_type(poly_multiline_plot, multi_line_gdf): """Test that assert works for grouped line plots""" poly_multiline_plot.assert_lines_grouped_by_type(multi_line_gdf, "attr") + plt.close() def test_points_sorted_by_markersize_pass(pt_geo_plot, pd_gdf): """Test points sorted by size of attribute pass""" pt_geo_plot.assert_collection_sorted_by_markersize(pd_gdf, "attr") + plt.close() def test_points_sorted_by_markersize_fail(pt_geo_plot_bad, pd_gdf): """Test points sorted by size of attribute""" with pytest.raises(AssertionError, match="Markersize not based on"): pt_geo_plot_bad.assert_collection_sorted_by_markersize(pd_gdf, "attr") + plt.close() From 4c30c508d22f274abc802946f9557e793ef2e509 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Wed, 18 Mar 2020 12:35:56 -0600 Subject: [PATCH 22/39] Added more tests --- matplotcheck/tests/test_vector.py | 118 ++++++++++++++++++------------ matplotcheck/vector.py | 2 +- 2 files changed, 72 insertions(+), 48 deletions(-) diff --git a/matplotcheck/tests/test_vector.py b/matplotcheck/tests/test_vector.py index 51f97a8d..356e1b5d 100644 --- a/matplotcheck/tests/test_vector.py +++ b/matplotcheck/tests/test_vector.py @@ -9,36 +9,6 @@ matplotlib.use("Agg") -@pytest.fixture -def poly_geo_plot(basic_polygon_gdf): - """Create a polygon vector tester object.""" - _, ax = plt.subplots() - - basic_polygon_gdf.plot(ax=ax) - ax.set_title("My Plot Title", fontsize=30) - ax.set_xlabel("x label") - ax.set_ylabel("y label") - - axis = plt.gca() - - return VectorTester(axis) - - -@pytest.fixture -def point_geo_plot(pd_gdf): - """Create a point plot for testing""" - _, ax = plt.subplots() - - pd_gdf.plot(ax=ax) - ax.set_title("My Plot Title", fontsize=30) - ax.set_xlabel("x label") - ax.set_ylabel("y label") - - axis = plt.gca() - - return VectorTester(axis) - - @pytest.fixture def bad_pd_gdf(pd_gdf): """Create a point geodataframe with slightly wrong values for testing""" @@ -79,9 +49,6 @@ def poly_line_plot(two_line_gdf): _, ax = plt.subplots() two_line_gdf.plot(ax=ax) - ax.set_title("My Plot Title", fontsize=30) - ax.set_xlabel("x label") - ax.set_ylabel("y label") axis = plt.gca() @@ -94,9 +61,18 @@ def poly_multiline_plot(multi_line_gdf): _, ax = plt.subplots() multi_line_gdf.plot(ax=ax, column="attr") - ax.set_title("My Plot Title", fontsize=30) - ax.set_xlabel("x label") - ax.set_ylabel("y label") + + axis = plt.gca() + + return VectorTester(axis) + + +@pytest.fixture +def poly_multiline_plot_bad(multi_line_gdf): + """Create a multiline vector tester object.""" + _, ax = plt.subplots() + + multi_line_gdf.plot(ax=ax) axis = plt.gca() @@ -127,7 +103,31 @@ def pt_geo_plot(pd_gdf): def pt_geo_plot_bad(pd_gdf): """Create a geo plot for testing""" _, ax = plt.subplots() - pd_gdf.plot(ax=ax, column="attr") + pd_gdf.plot(ax=ax) + axis = plt.gca() + + return VectorTester(axis) + + +@pytest.fixture +def poly_geo_plot(basic_polygon_gdf): + """Create a polygon vector tester object.""" + _, ax = plt.subplots() + + basic_polygon_gdf.plot(ax=ax) + + axis = plt.gca() + + return VectorTester(axis) + + +@pytest.fixture +def point_geo_plot(pd_gdf): + """Create a point plot for testing""" + _, ax = plt.subplots() + + pd_gdf.plot(ax=ax) + axis = plt.gca() return VectorTester(axis) @@ -200,6 +200,32 @@ def test_polygon_custom_fail_message(poly_geo_plot, basic_polygon): plt.close() +def test_points_sorted_by_markersize_pass(pt_geo_plot, pd_gdf): + """Test points sorted by size of attribute pass""" + pt_geo_plot.assert_collection_sorted_by_markersize(pd_gdf, "attr") + plt.close() + + +def test_points_sorted_by_markersize_fail(pt_geo_plot_bad, pd_gdf): + """Test points sorted by size of attribute fails""" + with pytest.raises(AssertionError, match="Markersize not based on"): + pt_geo_plot_bad.assert_collection_sorted_by_markersize(pd_gdf, "attr") + plt.close() + + +def test_points_grouped_by_type(pt_geo_plot, pd_gdf): + """Tests that points grouped by type passes""" + pt_geo_plot.assert_points_grouped_by_type(pd_gdf, "attr") + plt.close() + + +def test_points_grouped_by_type_fail(pt_geo_plot_bad, pd_gdf): + """Tests that points grouped by type passes""" + with pytest.raises(AssertionError, match="Point attributes not accurate"): + pt_geo_plot_bad.assert_points_grouped_by_type(pd_gdf, "attr") + plt.close() + + def test_point_geometry_pass(point_geo_plot, pd_gdf): """Check that the point geometry test recognizes correct points.""" point_geo_plot.assert_points(points_expected=pd_gdf) @@ -297,14 +323,12 @@ def test_assert_lines_grouped_by_type(poly_multiline_plot, multi_line_gdf): plt.close() -def test_points_sorted_by_markersize_pass(pt_geo_plot, pd_gdf): - """Test points sorted by size of attribute pass""" - pt_geo_plot.assert_collection_sorted_by_markersize(pd_gdf, "attr") - plt.close() - - -def test_points_sorted_by_markersize_fail(pt_geo_plot_bad, pd_gdf): - """Test points sorted by size of attribute""" - with pytest.raises(AssertionError, match="Markersize not based on"): - pt_geo_plot_bad.assert_collection_sorted_by_markersize(pd_gdf, "attr") +def test_assert_lines_grouped_by_type_fail( + poly_multiline_plot_bad, multi_line_gdf +): + """Test that assert fails for incorrectly grouped line plots""" + with pytest.raises(AssertionError, match="Line attributes not accurate "): + poly_multiline_plot_bad.assert_lines_grouped_by_type( + multi_line_gdf, "attr" + ) plt.close() diff --git a/matplotcheck/vector.py b/matplotcheck/vector.py index 655a1e6c..61f9c00c 100644 --- a/matplotcheck/vector.py +++ b/matplotcheck/vector.py @@ -103,7 +103,7 @@ def get_points_by_attributes(self): return sorted([sorted(p) for p in points_grouped]) def assert_points_grouped_by_type( - self, data_exp, sort_column, m="Point attribtues not accurate by type" + self, data_exp, sort_column, m="Point attributes not accurate by type" ): """Asserts that the points on Axes ax display attributes based on their type with error message m From 7e59d4779ab905a67dcce2a900f886616c3b62cd Mon Sep 17 00:00:00 2001 From: nkorinek Date: Wed, 18 Mar 2020 12:36:45 -0600 Subject: [PATCH 23/39] Typo --- matplotcheck/vector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matplotcheck/vector.py b/matplotcheck/vector.py index 655a1e6c..61f9c00c 100644 --- a/matplotcheck/vector.py +++ b/matplotcheck/vector.py @@ -103,7 +103,7 @@ def get_points_by_attributes(self): return sorted([sorted(p) for p in points_grouped]) def assert_points_grouped_by_type( - self, data_exp, sort_column, m="Point attribtues not accurate by type" + self, data_exp, sort_column, m="Point attributes not accurate by type" ): """Asserts that the points on Axes ax display attributes based on their type with error message m From 601a96dfcf447b572f2c0b2642effacf422fe54d Mon Sep 17 00:00:00 2001 From: nkorinek Date: Wed, 18 Mar 2020 13:33:06 -0600 Subject: [PATCH 24/39] more tests for uncovered parts of the vector file --- matplotcheck/tests/test_vector.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/matplotcheck/tests/test_vector.py b/matplotcheck/tests/test_vector.py index 356e1b5d..f13ece52 100644 --- a/matplotcheck/tests/test_vector.py +++ b/matplotcheck/tests/test_vector.py @@ -133,6 +133,19 @@ def point_geo_plot(pd_gdf): return VectorTester(axis) +@pytest.fixture +def mixed_type_geo_plot(pd_gdf, multi_line_gdf): + """Create a point plot for testing""" + _, ax = plt.subplots() + + pd_gdf.plot(ax=ax) + multi_line_gdf.plot(ax=ax) + + axis = plt.gca() + + return VectorTester(axis) + + def test_list_of_polygons_check(poly_geo_plot, basic_polygon): """Check that the polygon assert works with a list of polygons.""" x, y = basic_polygon.exterior.coords.xy @@ -332,3 +345,15 @@ def test_assert_lines_grouped_by_type_fail( multi_line_gdf, "attr" ) plt.close() + + +def test_mixed_type_passes(mixed_type_geo_plot, pd_gdf): + """Tests that points passes with a mixed type plot""" + mixed_type_geo_plot.assert_points(pd_gdf) + plt.close() + +def test_wrong_length_points_expected(pt_geo_plot, pd_gdf, bad_pd_gdf): + """Tests that error is thrown for incorrect lenght of a gdf""" + with pytest.raises(AssertionError, match="points_expected's length does "): + pt_geo_plot.assert_points(bad_pd_gdf.append(pd_gdf), "attr") + plt.close() From bc81a2548435bd5f12b826cd61584709e8e6bf16 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Wed, 18 Mar 2020 14:17:18 -0600 Subject: [PATCH 25/39] black --- matplotcheck/tests/test_vector.py | 1 + 1 file changed, 1 insertion(+) diff --git a/matplotcheck/tests/test_vector.py b/matplotcheck/tests/test_vector.py index f13ece52..1ea07ddd 100644 --- a/matplotcheck/tests/test_vector.py +++ b/matplotcheck/tests/test_vector.py @@ -352,6 +352,7 @@ def test_mixed_type_passes(mixed_type_geo_plot, pd_gdf): mixed_type_geo_plot.assert_points(pd_gdf) plt.close() + def test_wrong_length_points_expected(pt_geo_plot, pd_gdf, bad_pd_gdf): """Tests that error is thrown for incorrect lenght of a gdf""" with pytest.raises(AssertionError, match="points_expected's length does "): From 80f7e77a2b8a005b68511963561131923128b278 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Wed, 18 Mar 2020 14:29:32 -0600 Subject: [PATCH 26/39] Fixed issues with vector checking truth value of dataframe, and added tests --- matplotcheck/tests/test_vector.py | 31 ++++++++++++++++++++++++------- matplotcheck/vector.py | 2 +- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/matplotcheck/tests/test_vector.py b/matplotcheck/tests/test_vector.py index 1ea07ddd..a591042e 100644 --- a/matplotcheck/tests/test_vector.py +++ b/matplotcheck/tests/test_vector.py @@ -279,6 +279,13 @@ def test_assert_points_custom_message(point_geo_plot, bad_pd_gdf): plt.close() +def test_wrong_length_points_expected(pt_geo_plot, pd_gdf, bad_pd_gdf): + """Tests that error is thrown for incorrect lenght of a gdf""" + with pytest.raises(AssertionError, match="points_expected's length does "): + pt_geo_plot.assert_points(bad_pd_gdf.append(pd_gdf), "attr") + plt.close() + + def test_assert_line_geo(poly_line_plot, two_line_gdf): """Test that lines are asserted correctly""" poly_line_plot.assert_lines(two_line_gdf) @@ -347,14 +354,24 @@ def test_assert_lines_grouped_by_type_fail( plt.close() -def test_mixed_type_passes(mixed_type_geo_plot, pd_gdf): - """Tests that points passes with a mixed type plot""" - mixed_type_geo_plot.assert_points(pd_gdf) +def test_assert_lines_grouped_by_type_passes_with_none(poly_multiline_plot): + """Test that assert passes if nothing is passed into it""" + poly_multiline_plot.assert_lines_grouped_by_type(None, None) plt.close() -def test_wrong_length_points_expected(pt_geo_plot, pd_gdf, bad_pd_gdf): - """Tests that error is thrown for incorrect lenght of a gdf""" - with pytest.raises(AssertionError, match="points_expected's length does "): - pt_geo_plot.assert_points(bad_pd_gdf.append(pd_gdf), "attr") +def test_assert_lines_grouped_by_type_fails_non_gdf( + poly_multiline_plot, multi_line_gdf +): + """Test that assert fails if a list is passed into it""" + with pytest.raises(ValueError, match="lines_expected is not of expected "): + poly_multiline_plot.assert_lines_grouped_by_type( + multi_line_gdf.to_numpy(), "attr" + ) plt.close() + + +def test_mixed_type_passes(mixed_type_geo_plot, pd_gdf): + """Tests that points passes with a mixed type plot""" + mixed_type_geo_plot.assert_points(pd_gdf) + plt.close() diff --git a/matplotcheck/vector.py b/matplotcheck/vector.py index 61f9c00c..ab77c8da 100644 --- a/matplotcheck/vector.py +++ b/matplotcheck/vector.py @@ -455,7 +455,7 @@ def assert_lines_grouped_by_type( grouped_exp = sorted([sorted(l) for l in grouped_exp]) plt.close(fig) np.testing.assert_equal(groups, grouped_exp, m) - elif not lines_expected: + elif lines_expected is None: pass else: raise ValueError( From 3b8a20b91cd72ab4faf72879ff0fe3ae0eedab91 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Wed, 18 Mar 2020 14:30:27 -0600 Subject: [PATCH 27/39] Fixing how vector checks for truth value of a dataframe --- matplotcheck/vector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matplotcheck/vector.py b/matplotcheck/vector.py index 61f9c00c..ab77c8da 100644 --- a/matplotcheck/vector.py +++ b/matplotcheck/vector.py @@ -455,7 +455,7 @@ def assert_lines_grouped_by_type( grouped_exp = sorted([sorted(l) for l in grouped_exp]) plt.close(fig) np.testing.assert_equal(groups, grouped_exp, m) - elif not lines_expected: + elif lines_expected is None: pass else: raise ValueError( From dca38afd75eb9c8d43df2c65c4ef7b25af1d9083 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Wed, 18 Mar 2020 14:58:27 -0600 Subject: [PATCH 28/39] Added more coverage! --- matplotcheck/tests/test_vector.py | 54 ++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/matplotcheck/tests/test_vector.py b/matplotcheck/tests/test_vector.py index a591042e..119ec32f 100644 --- a/matplotcheck/tests/test_vector.py +++ b/matplotcheck/tests/test_vector.py @@ -2,7 +2,7 @@ import pytest import matplotlib.pyplot as plt import geopandas as gpd -from shapely.geometry import LineString +from shapely.geometry import LineString, Polygon from matplotcheck.vector import VectorTester import matplotlib @@ -43,6 +43,24 @@ def multi_line_gdf(two_line_gdf): return out_df +@pytest.fixture +def multi_polygon_gdf(basic_polygon): + """ + A GeoDataFrame containing the basic polygon geometry. + Returns + ------- + GeoDataFrame containing the basic_polygon polygon. + """ + poly_a = Polygon([(3, 5), (2, 3.25), (5.25, 6), (2.25, 2), (2, 2)]) + gdf = gpd.GeoDataFrame( + [1, 2], geometry=[poly_a, basic_polygon], crs="epsg:4326", + ) + multi_gdf = gpd.GeoDataFrame( + geometry=gpd.GeoSeries(gdf.unary_union), crs="epsg:4326" + ) + return multi_gdf + + @pytest.fixture def poly_line_plot(two_line_gdf): """Create a line vector tester object.""" @@ -103,7 +121,9 @@ def pt_geo_plot(pd_gdf): def pt_geo_plot_bad(pd_gdf): """Create a geo plot for testing""" _, ax = plt.subplots() + pd_gdf.plot(ax=ax) + axis = plt.gca() return VectorTester(axis) @@ -121,6 +141,18 @@ def poly_geo_plot(basic_polygon_gdf): return VectorTester(axis) +@pytest.fixture +def multi_poly_geo_plot(multi_polygon_gdf): + """Create a mutlipolygon vector tester object.""" + _, ax = plt.subplots() + + multi_polygon_gdf.plot(ax=ax) + + axis = plt.gca() + + return VectorTester(axis) + + @pytest.fixture def point_geo_plot(pd_gdf): """Create a point plot for testing""" @@ -213,6 +245,12 @@ def test_polygon_custom_fail_message(poly_geo_plot, basic_polygon): plt.close() +def test_multi_polygon_pass(multi_poly_geo_plot, multi_polygon_gdf): + """Check a multipolygon passes""" + multi_poly_geo_plot.assert_polygons(multi_polygon_gdf) + plt.close() + + def test_points_sorted_by_markersize_pass(pt_geo_plot, pd_gdf): """Test points sorted by size of attribute pass""" pt_geo_plot.assert_collection_sorted_by_markersize(pd_gdf, "attr") @@ -375,3 +413,17 @@ def test_mixed_type_passes(mixed_type_geo_plot, pd_gdf): """Tests that points passes with a mixed type plot""" mixed_type_geo_plot.assert_points(pd_gdf) plt.close() + + +def test_get_lines_by_collection(poly_multiline_plot): + """Test that get_lines_by_collection returns the correct values""" + lines_list = [ + [ + [(1, 1), (2, 2), (3, 2), (5, 3)], + [(3, 4), (5, 7), (12, 2), (10, 5), (9, 7.5)], + [(2, 1), (3, 1), (4, 1), (5, 2)], + ] + ] + sorted_lines_list = sorted([sorted(l) for l in lines_list]) + assert sorted_lines_list == poly_multiline_plot.get_lines_by_collection() + plt.close() From f48961394422fa9a36581e26de5561b7321a5fff Mon Sep 17 00:00:00 2001 From: nkorinek Date: Thu, 19 Mar 2020 14:16:51 -0600 Subject: [PATCH 29/39] Broke tests up into individual files --- matplotcheck/tests/test_lines.py | 187 ++++++++++++ matplotcheck/tests/test_points.py | 135 +++++++++ matplotcheck/tests/test_polygons.py | 162 ++++++++++ matplotcheck/tests/test_vector.py | 454 ---------------------------- 4 files changed, 484 insertions(+), 454 deletions(-) create mode 100644 matplotcheck/tests/test_lines.py create mode 100644 matplotcheck/tests/test_points.py create mode 100644 matplotcheck/tests/test_polygons.py delete mode 100644 matplotcheck/tests/test_vector.py diff --git a/matplotcheck/tests/test_lines.py b/matplotcheck/tests/test_lines.py new file mode 100644 index 00000000..7c54db5f --- /dev/null +++ b/matplotcheck/tests/test_lines.py @@ -0,0 +1,187 @@ +"""Tests for the vector module""" +import pytest +import matplotlib.pyplot as plt +import geopandas as gpd +from shapely.geometry import LineString +from matplotcheck.vector import VectorTester +import matplotlib + +matplotlib.use("Agg") + + +@pytest.fixture +def two_line_gdf(): + """ Create Line Objects For Testing """ + linea = LineString([(1, 1), (2, 2), (3, 2), (5, 3)]) + lineb = LineString([(3, 4), (5, 7), (12, 2), (10, 5), (9, 7.5)]) + gdf = gpd.GeoDataFrame([1, 2], geometry=[linea, lineb], crs="epsg:4326") + return gdf + + +@pytest.fixture +def multi_line_gdf(two_line_gdf): + """ Create a multi-line GeoDataFrame. + This has one multi line and another regular line. + """ + # Create a single and multi line object + multiline_feat = two_line_gdf.unary_union + linec = LineString([(2, 1), (3, 1), (4, 1), (5, 2)]) + out_df = gpd.GeoDataFrame( + geometry=gpd.GeoSeries([multiline_feat, linec]), crs="epsg:4326", + ) + out_df["attr"] = ["road", "stream"] + return out_df + + +@pytest.fixture +def mixed_type_geo_plot(pd_gdf, multi_line_gdf): + """Create a point plot for testing""" + _, ax = plt.subplots() + + pd_gdf.plot(ax=ax) + multi_line_gdf.plot(ax=ax) + + axis = plt.gca() + + return VectorTester(axis) + + +@pytest.fixture +def poly_line_plot(two_line_gdf): + """Create a line vector tester object.""" + _, ax = plt.subplots() + + two_line_gdf.plot(ax=ax) + + axis = plt.gca() + + return VectorTester(axis) + + +@pytest.fixture +def poly_multiline_plot(multi_line_gdf): + """Create a multiline vector tester object.""" + _, ax = plt.subplots() + + multi_line_gdf.plot(ax=ax, column="attr") + + axis = plt.gca() + + return VectorTester(axis) + + +@pytest.fixture +def poly_multiline_plot_bad(multi_line_gdf): + """Create a multiline vector tester object.""" + _, ax = plt.subplots() + + multi_line_gdf.plot(ax=ax) + + axis = plt.gca() + + return VectorTester(axis) + + +def test_assert_line_geo(poly_line_plot, two_line_gdf): + """Test that lines are asserted correctly""" + poly_line_plot.assert_lines(two_line_gdf) + plt.close('all') + + +def test_assert_multiline_geo(poly_multiline_plot, multi_line_gdf): + """Test that multi lines are asserted correctly""" + poly_multiline_plot.assert_lines(multi_line_gdf) + plt.close('all') + + +def test_assert_line_geo_fail(poly_line_plot, multi_line_gdf): + """Test that lines fail correctly""" + with pytest.raises(AssertionError, match="Incorrect Line Data"): + poly_line_plot.assert_lines(multi_line_gdf) + plt.close('all') + + +def test_assert_multiline_geo_fail(poly_multiline_plot, two_line_gdf): + """Test that multi lines fail correctly""" + with pytest.raises(AssertionError, match="Incorrect Line Data"): + poly_multiline_plot.assert_lines(two_line_gdf) + plt.close('all') + + +def test_assert_line_fails_list(poly_line_plot): + """Test that assert_lines fails when passed a list""" + linelist = [ + [(1, 1), (2, 2), (3, 2), (5, 3)], + [(3, 4), (5, 7), (12, 2), (10, 5), (9, 7.5)], + ] + with pytest.raises(ValueError, match="lines_expected is not expected ty"): + poly_line_plot.assert_lines(linelist) + plt.close('all') + + +def test_assert_line_geo_passed_nothing(poly_line_plot): + """Test that assertion passes when passed None""" + poly_line_plot.assert_lines(None) + plt.close('all') + + +def test_get_lines_geometry(poly_line_plot): + """Test that get_lines returns the proper values""" + lines = [(LineString(i[0])) for i in poly_line_plot.get_lines().values] + geometries = gpd.GeoDataFrame(geometry=lines) + poly_line_plot.assert_lines(geometries) + plt.close('all') + + +def test_assert_lines_grouped_by_type(poly_multiline_plot, multi_line_gdf): + """Test that assert works for grouped line plots""" + poly_multiline_plot.assert_lines_grouped_by_type(multi_line_gdf, "attr") + plt.close('all') + + +def test_assert_lines_grouped_by_type_fail( + poly_multiline_plot_bad, multi_line_gdf +): + """Test that assert fails for incorrectly grouped line plots""" + with pytest.raises(AssertionError, match="Line attributes not accurate "): + poly_multiline_plot_bad.assert_lines_grouped_by_type( + multi_line_gdf, "attr" + ) + plt.close('all') + + +def test_assert_lines_grouped_by_type_passes_with_none(poly_multiline_plot): + """Test that assert passes if nothing is passed into it""" + poly_multiline_plot.assert_lines_grouped_by_type(None, None) + plt.close('all') + + +def test_assert_lines_grouped_by_type_fails_non_gdf( + poly_multiline_plot, multi_line_gdf +): + """Test that assert fails if a list is passed into it""" + with pytest.raises(ValueError, match="lines_expected is not of expected "): + poly_multiline_plot.assert_lines_grouped_by_type( + multi_line_gdf.to_numpy(), "attr" + ) + plt.close('all') + + +def test_mixed_type_passes(mixed_type_geo_plot, pd_gdf): + """Tests that points passes with a mixed type plot""" + mixed_type_geo_plot.assert_points(pd_gdf) + plt.close('all') + + +def test_get_lines_by_collection(poly_multiline_plot): + """Test that get_lines_by_collection returns the correct values""" + lines_list = [ + [ + [(1, 1), (2, 2), (3, 2), (5, 3)], + [(3, 4), (5, 7), (12, 2), (10, 5), (9, 7.5)], + [(2, 1), (3, 1), (4, 1), (5, 2)], + ] + ] + sorted_lines_list = sorted([sorted(l) for l in lines_list]) + assert sorted_lines_list == poly_multiline_plot.get_lines_by_collection() + plt.close('all') diff --git a/matplotcheck/tests/test_points.py b/matplotcheck/tests/test_points.py new file mode 100644 index 00000000..69cd3ce7 --- /dev/null +++ b/matplotcheck/tests/test_points.py @@ -0,0 +1,135 @@ +"""Tests for the vector module""" +import pytest +import matplotlib.pyplot as plt +import geopandas as gpd +from matplotcheck.vector import VectorTester +import matplotlib + +matplotlib.use("Agg") + + +@pytest.fixture +def bad_pd_gdf(pd_gdf): + """Create a point geodataframe with slightly wrong values for testing""" + return gpd.GeoDataFrame( + geometry=gpd.points_from_xy( + pd_gdf.geometry.x + 1, pd_gdf.geometry.y + 1 + ) + ) + + +@pytest.fixture +def pt_geo_plot(pd_gdf): + """Create a geo plot for testing""" + _, ax = plt.subplots() + size = 0 + point_symb = {"Tree": "green", "Bush": "brown"} + + for ctype, points in pd_gdf.groupby("attr"): + color = point_symb[ctype] + label = ctype + size += 100 + points.plot(color=color, ax=ax, label=label, markersize=size) + + ax.legend(title="Legend", loc=(1.1, 0.1)) + + axis = plt.gca() + + return VectorTester(axis) + + +@pytest.fixture +def pt_geo_plot_bad(pd_gdf): + """Create a geo plot for testing""" + _, ax = plt.subplots() + + pd_gdf.plot(ax=ax) + + axis = plt.gca() + + return VectorTester(axis) + + +@pytest.fixture +def point_geo_plot(pd_gdf): + """Create a point plot for testing""" + _, ax = plt.subplots() + + pd_gdf.plot(ax=ax) + + axis = plt.gca() + + return VectorTester(axis) + + +def test_points_sorted_by_markersize_pass(pt_geo_plot, pd_gdf): + """Test points sorted by size of attribute pass""" + pt_geo_plot.assert_collection_sorted_by_markersize(pd_gdf, "attr") + plt.close('all') + + +def test_points_sorted_by_markersize_fail(pt_geo_plot_bad, pd_gdf): + """Test points sorted by size of attribute fails""" + with pytest.raises(AssertionError, match="Markersize not based on"): + pt_geo_plot_bad.assert_collection_sorted_by_markersize(pd_gdf, "attr") + plt.close('all') + + +def test_points_grouped_by_type(pt_geo_plot, pd_gdf): + """Tests that points grouped by type passes""" + pt_geo_plot.assert_points_grouped_by_type(pd_gdf, "attr") + plt.close('all') + + +def test_points_grouped_by_type_fail(pt_geo_plot_bad, pd_gdf): + """Tests that points grouped by type passes""" + with pytest.raises(AssertionError, match="Point attributes not accurate"): + pt_geo_plot_bad.assert_points_grouped_by_type(pd_gdf, "attr") + plt.close('all') + + +def test_point_geometry_pass(point_geo_plot, pd_gdf): + """Check that the point geometry test recognizes correct points.""" + point_geo_plot.assert_points(points_expected=pd_gdf) + plt.close('all') + + +def test_point_geometry_fail(point_geo_plot, bad_pd_gdf): + """Check that the point geometry test recognizes incorrect points.""" + with pytest.raises(AssertionError, match="Incorrect Point Data"): + point_geo_plot.assert_points(points_expected=bad_pd_gdf) + plt.close('all') + + +def test_assert_point_fails_list(point_geo_plot, pd_gdf): + """ + Check that the point geometry test fails anything that's not a + GeoDataFrame + """ + list_geo = [list(pd_gdf.geometry.x), list(pd_gdf.geometry.y)] + with pytest.raises(ValueError, match="points_expected is not expected"): + point_geo_plot.assert_points(points_expected=list_geo) + plt.close('all') + + +def test_get_points(point_geo_plot, pd_gdf): + """Tests that get_points returns correct values""" + xy_values = point_geo_plot.get_points() + assert list(sorted(xy_values.x)) == sorted(list(pd_gdf.geometry.x)) + assert list(sorted(xy_values.y)) == sorted(list(pd_gdf.geometry.y)) + plt.close('all') + + +def test_assert_points_custom_message(point_geo_plot, bad_pd_gdf): + """Tests that a custom error message is passed.""" + message = "Test message" + with pytest.raises(AssertionError, match="Test message"): + point_geo_plot.assert_points(points_expected=bad_pd_gdf, m=message) + plt.close('all') + + +def test_wrong_length_points_expected(pt_geo_plot, pd_gdf, bad_pd_gdf): + """Tests that error is thrown for incorrect lenght of a gdf""" + with pytest.raises(AssertionError, match="points_expected's length does "): + pt_geo_plot.assert_points(bad_pd_gdf.append(pd_gdf), "attr") + plt.close('all') diff --git a/matplotcheck/tests/test_polygons.py b/matplotcheck/tests/test_polygons.py new file mode 100644 index 00000000..3627e01c --- /dev/null +++ b/matplotcheck/tests/test_polygons.py @@ -0,0 +1,162 @@ +"""Tests for the vector module""" +import pytest +import matplotlib.pyplot as plt +import geopandas as gpd +from shapely.geometry import Polygon +from matplotcheck.vector import VectorTester +import matplotlib + +matplotlib.use("Agg") + + +@pytest.fixture +def multi_polygon_gdf(basic_polygon): + """ + A GeoDataFrame containing the basic polygon geometry. + Returns + ------- + GeoDataFrame containing the basic_polygon polygon. + """ + poly_a = Polygon([(3, 5), (2, 3.25), (5.25, 6), (2.25, 2), (2, 2)]) + gdf = gpd.GeoDataFrame( + [1, 2], geometry=[poly_a, basic_polygon], crs="epsg:4326", + ) + multi_gdf = gpd.GeoDataFrame( + geometry=gpd.GeoSeries(gdf.unary_union), crs="epsg:4326" + ) + return multi_gdf + + + +@pytest.fixture +def poly_line_plot(two_line_gdf): + """Create a line vector tester object.""" + _, ax = plt.subplots() + + two_line_gdf.plot(ax=ax) + + axis = plt.gca() + + return VectorTester(axis) + + +@pytest.fixture +def poly_multiline_plot(multi_line_gdf): + """Create a multiline vector tester object.""" + _, ax = plt.subplots() + + multi_line_gdf.plot(ax=ax, column="attr") + + axis = plt.gca() + + return VectorTester(axis) + + +@pytest.fixture +def poly_multiline_plot_bad(multi_line_gdf): + """Create a multiline vector tester object.""" + _, ax = plt.subplots() + + multi_line_gdf.plot(ax=ax) + + axis = plt.gca() + + return VectorTester(axis) + + +@pytest.fixture +def poly_geo_plot(basic_polygon_gdf): + """Create a polygon vector tester object.""" + _, ax = plt.subplots() + + basic_polygon_gdf.plot(ax=ax) + + axis = plt.gca() + + return VectorTester(axis) + + +@pytest.fixture +def multi_poly_geo_plot(multi_polygon_gdf): + """Create a mutlipolygon vector tester object.""" + _, ax = plt.subplots() + + multi_polygon_gdf.plot(ax=ax) + + axis = plt.gca() + + return VectorTester(axis) + + + +def test_list_of_polygons_check(poly_geo_plot, basic_polygon): + """Check that the polygon assert works with a list of polygons.""" + x, y = basic_polygon.exterior.coords.xy + poly_list = [list(zip(x, y))] + poly_geo_plot.assert_polygons(poly_list) + plt.close('all') + + +def test_polygon_geodataframe_check(poly_geo_plot, basic_polygon_gdf): + """Check that the polygon assert works with a polygon geodataframe""" + poly_geo_plot.assert_polygons(basic_polygon_gdf) + plt.close('all') + + +def test_empty_list_polygon_check(poly_geo_plot): + """Check that the polygon assert fails an empty list.""" + with pytest.raises(ValueError, match="Empty list or GeoDataFrame "): + poly_geo_plot.assert_polygons([]) + plt.close('all') + + +def test_empty_list_entry_polygon_check(poly_geo_plot): + """Check that the polygon assert fails a list with an empty entry.""" + with pytest.raises(ValueError, match="Empty list or GeoDataFrame "): + poly_geo_plot.assert_polygons([[]]) + plt.close('all') + + +def test_empty_gdf_polygon_check(poly_geo_plot): + """Check that the polygon assert fails an empty GeoDataFrame.""" + with pytest.raises(ValueError, match="Empty list or GeoDataFrame "): + poly_geo_plot.assert_polygons(gpd.GeoDataFrame([])) + plt.close('all') + + +def test_polygon_dec_check(poly_geo_plot, basic_polygon): + """ + Check that the polygon assert passes when the polygon is off by less than + the maximum decimal precision. + """ + x, y = basic_polygon.exterior.coords.xy + poly_list = [[(x[0] + 0.1, x[1]) for x in list(zip(x, y))]] + poly_geo_plot.assert_polygons(poly_list, dec=1) + plt.close('all') + + +def test_polygon_dec_check_fail(poly_geo_plot, basic_polygon): + """ + Check that the polygon assert fails when the polygon is off by more than + the maximum decimal precision. + """ + with pytest.raises(AssertionError, match="Incorrect Polygon"): + x, y = basic_polygon.exterior.coords.xy + poly_list = [(x[0] + 0.5, x[1]) for x in list(zip(x, y))] + poly_geo_plot.assert_polygons(poly_list, dec=1) + plt.close('all') + + +def test_polygon_custom_fail_message(poly_geo_plot, basic_polygon): + """Check that the corrct error message is raised when polygons fail""" + with pytest.raises(AssertionError, match="Test Message"): + x, y = basic_polygon.exterior.coords.xy + poly_list = [(x[0] + 0.5, x[1]) for x in list(zip(x, y))] + poly_geo_plot.assert_polygons(poly_list, m="Test Message") + plt.close('all') + + +def test_multi_polygon_pass(multi_poly_geo_plot, multi_polygon_gdf): + """Check a multipolygon passes""" + multi_poly_geo_plot.assert_polygons(multi_polygon_gdf) + plt.close('all') diff --git a/matplotcheck/tests/test_vector.py b/matplotcheck/tests/test_vector.py deleted file mode 100644 index 623d093f..00000000 --- a/matplotcheck/tests/test_vector.py +++ /dev/null @@ -1,454 +0,0 @@ -"""Tests for the vector module""" -import pytest -import matplotlib.pyplot as plt -import geopandas as gpd -from shapely.geometry import LineString, Polygon -from matplotcheck.vector import VectorTester -import matplotlib - -matplotlib.use("Agg") - - -@pytest.fixture -def bad_pd_gdf(pd_gdf): - """Create a point geodataframe with slightly wrong values for testing""" - return gpd.GeoDataFrame( - geometry=gpd.points_from_xy( - pd_gdf.geometry.x + 1, pd_gdf.geometry.y + 1 - ) - ) - - -@pytest.fixture -def two_line_gdf(): - """ Create Line Objects For Testing """ - linea = LineString([(1, 1), (2, 2), (3, 2), (5, 3)]) - lineb = LineString([(3, 4), (5, 7), (12, 2), (10, 5), (9, 7.5)]) - gdf = gpd.GeoDataFrame([1, 2], geometry=[linea, lineb], crs="epsg:4326") - return gdf - - -@pytest.fixture -def multi_line_gdf(two_line_gdf): - """ Create a multi-line GeoDataFrame. - This has one multi line and another regular line. - """ - # Create a single and multi line object - multiline_feat = two_line_gdf.unary_union - linec = LineString([(2, 1), (3, 1), (4, 1), (5, 2)]) - out_df = gpd.GeoDataFrame( - geometry=gpd.GeoSeries([multiline_feat, linec]), crs="epsg:4326", - ) - out_df["attr"] = ["road", "stream"] - return out_df - - -@pytest.fixture -def multi_polygon_gdf(basic_polygon): - """ - A GeoDataFrame containing the basic polygon geometry. - Returns - ------- - GeoDataFrame containing the basic_polygon polygon. - """ - poly_a = Polygon([(3, 5), (2, 3.25), (5.25, 6), (2.25, 2), (2, 2)]) - gdf = gpd.GeoDataFrame( - [1, 2], geometry=[poly_a, basic_polygon], crs="epsg:4326", - ) - multi_gdf = gpd.GeoDataFrame( - geometry=gpd.GeoSeries(gdf.unary_union), crs="epsg:4326" - ) - return multi_gdf - - -@pytest.fixture -def poly_line_plot(two_line_gdf): - """Create a line vector tester object.""" - _, ax = plt.subplots() - - two_line_gdf.plot(ax=ax) - - axis = plt.gca() - - return VectorTester(axis) - - -@pytest.fixture -def poly_multiline_plot(multi_line_gdf): - """Create a multiline vector tester object.""" - _, ax = plt.subplots() - - multi_line_gdf.plot(ax=ax, column="attr") - - axis = plt.gca() - - return VectorTester(axis) - - -@pytest.fixture -def poly_multiline_plot_bad(multi_line_gdf): - """Create a multiline vector tester object.""" - _, ax = plt.subplots() - - multi_line_gdf.plot(ax=ax) - - axis = plt.gca() - - return VectorTester(axis) - - -@pytest.fixture -def pt_geo_plot(pd_gdf): - """Create a geo plot for testing""" - _, ax = plt.subplots() - size = 0 - point_symb = {"Tree": "green", "Bush": "brown"} - - for ctype, points in pd_gdf.groupby("attr"): - color = point_symb[ctype] - label = ctype - size += 100 - points.plot(color=color, ax=ax, label=label, markersize=size) - - ax.legend(title="Legend", loc=(1.1, 0.1)) - - axis = plt.gca() - - return VectorTester(axis) - - -@pytest.fixture -def pt_geo_plot_bad(pd_gdf): - """Create a geo plot for testing""" - _, ax = plt.subplots() - - pd_gdf.plot(ax=ax) - - axis = plt.gca() - - return VectorTester(axis) - - -@pytest.fixture -def poly_geo_plot(basic_polygon_gdf): - """Create a polygon vector tester object.""" - _, ax = plt.subplots() - - basic_polygon_gdf.plot(ax=ax) - - axis = plt.gca() - - return VectorTester(axis) - - -@pytest.fixture -def multi_poly_geo_plot(multi_polygon_gdf): - """Create a mutlipolygon vector tester object.""" - _, ax = plt.subplots() - - multi_polygon_gdf.plot(ax=ax) - - axis = plt.gca() - - return VectorTester(axis) - - -@pytest.fixture -def point_geo_plot(pd_gdf): - """Create a point plot for testing""" - _, ax = plt.subplots() - - pd_gdf.plot(ax=ax) - - axis = plt.gca() - - return VectorTester(axis) - - -@pytest.fixture -def mixed_type_geo_plot(pd_gdf, multi_line_gdf): - """Create a point plot for testing""" - _, ax = plt.subplots() - - pd_gdf.plot(ax=ax) - multi_line_gdf.plot(ax=ax) - - axis = plt.gca() - - return VectorTester(axis) - - -@pytest.fixture -def point_geo_plot(pd_gdf): - """Create a point plot for testing""" - _, ax = plt.subplots() - - pd_gdf.plot(ax=ax) - ax.set_title("My Plot Title", fontsize=30) - ax.set_xlabel("x label") - ax.set_ylabel("y label") - - axis = plt.gca() - - return VectorTester(axis) - - -@pytest.fixture -def bad_pd_gdf(pd_gdf): - """Create a point geodataframe with slightly wrong values for testing""" - return gpd.GeoDataFrame( - geometry=gpd.points_from_xy( - pd_gdf.geometry.x + 1, pd_gdf.geometry.y + 1 - ) - ) - - -def test_list_of_polygons_check(poly_geo_plot, basic_polygon): - """Check that the polygon assert works with a list of polygons.""" - x, y = basic_polygon.exterior.coords.xy - poly_list = [list(zip(x, y))] - poly_geo_plot.assert_polygons(poly_list) - plt.close() - - -def test_polygon_geodataframe_check(poly_geo_plot, basic_polygon_gdf): - """Check that the polygon assert works with a polygon geodataframe""" - poly_geo_plot.assert_polygons(basic_polygon_gdf) - plt.close() - - -def test_empty_list_polygon_check(poly_geo_plot): - """Check that the polygon assert fails an empty list.""" - with pytest.raises(ValueError, match="Empty list or GeoDataFrame "): - poly_geo_plot.assert_polygons([]) - plt.close() - - -def test_empty_list_entry_polygon_check(poly_geo_plot): - """Check that the polygon assert fails a list with an empty entry.""" - with pytest.raises(ValueError, match="Empty list or GeoDataFrame "): - poly_geo_plot.assert_polygons([[]]) - plt.close() - - -def test_empty_gdf_polygon_check(poly_geo_plot): - """Check that the polygon assert fails an empty GeoDataFrame.""" - with pytest.raises(ValueError, match="Empty list or GeoDataFrame "): - poly_geo_plot.assert_polygons(gpd.GeoDataFrame([])) - plt.close() - - -def test_polygon_dec_check(poly_geo_plot, basic_polygon): - """ - Check that the polygon assert passes when the polygon is off by less than - the maximum decimal precision. - """ - x, y = basic_polygon.exterior.coords.xy - poly_list = [[(x[0] + 0.1, x[1]) for x in list(zip(x, y))]] - poly_geo_plot.assert_polygons(poly_list, dec=1) - plt.close() - - -def test_polygon_dec_check_fail(poly_geo_plot, basic_polygon): - """ - Check that the polygon assert fails when the polygon is off by more than - the maximum decimal precision. - """ - with pytest.raises(AssertionError, match="Incorrect Polygon"): - x, y = basic_polygon.exterior.coords.xy - poly_list = [(x[0] + 0.5, x[1]) for x in list(zip(x, y))] - poly_geo_plot.assert_polygons(poly_list, dec=1) - plt.close() - - -def test_polygon_custom_fail_message(poly_geo_plot, basic_polygon): - """Check that the corrct error message is raised when polygons fail""" - with pytest.raises(AssertionError, match="Test Message"): - x, y = basic_polygon.exterior.coords.xy - poly_list = [(x[0] + 0.5, x[1]) for x in list(zip(x, y))] - poly_geo_plot.assert_polygons(poly_list, m="Test Message") - plt.close() - - -def test_multi_polygon_pass(multi_poly_geo_plot, multi_polygon_gdf): - """Check a multipolygon passes""" - multi_poly_geo_plot.assert_polygons(multi_polygon_gdf) - plt.close() - - -def test_points_sorted_by_markersize_pass(pt_geo_plot, pd_gdf): - """Test points sorted by size of attribute pass""" - pt_geo_plot.assert_collection_sorted_by_markersize(pd_gdf, "attr") - plt.close() - - -def test_points_sorted_by_markersize_fail(pt_geo_plot_bad, pd_gdf): - """Test points sorted by size of attribute fails""" - with pytest.raises(AssertionError, match="Markersize not based on"): - pt_geo_plot_bad.assert_collection_sorted_by_markersize(pd_gdf, "attr") - plt.close() - - -def test_points_grouped_by_type(pt_geo_plot, pd_gdf): - """Tests that points grouped by type passes""" - pt_geo_plot.assert_points_grouped_by_type(pd_gdf, "attr") - plt.close() - - -def test_points_grouped_by_type_fail(pt_geo_plot_bad, pd_gdf): - """Tests that points grouped by type passes""" - with pytest.raises(AssertionError, match="Point attributes not accurate"): - pt_geo_plot_bad.assert_points_grouped_by_type(pd_gdf, "attr") - plt.close() - - -def test_point_geometry_pass(point_geo_plot, pd_gdf): - """Check that the point geometry test recognizes correct points.""" - point_geo_plot.assert_points(points_expected=pd_gdf) - plt.close() - - -def test_point_geometry_fail(point_geo_plot, bad_pd_gdf): - """Check that the point geometry test recognizes incorrect points.""" - with pytest.raises(AssertionError, match="Incorrect Point Data"): - point_geo_plot.assert_points(points_expected=bad_pd_gdf) - plt.close() - - -def test_assert_point_fails_list(point_geo_plot, pd_gdf): - """ - Check that the point geometry test fails anything that's not a - GeoDataFrame - """ - list_geo = [list(pd_gdf.geometry.x), list(pd_gdf.geometry.y)] - with pytest.raises(ValueError, match="points_expected is not expected"): - point_geo_plot.assert_points(points_expected=list_geo) - plt.close() - - -def test_get_points(point_geo_plot, pd_gdf): - """Tests that get_points returns correct values""" - xy_values = point_geo_plot.get_points() - assert list(sorted(xy_values.x)) == sorted(list(pd_gdf.geometry.x)) - assert list(sorted(xy_values.y)) == sorted(list(pd_gdf.geometry.y)) - plt.close() - - -def test_assert_points_custom_message(point_geo_plot, bad_pd_gdf): - """Tests that a custom error message is passed.""" - message = "Test message" - with pytest.raises(AssertionError, match="Test message"): - point_geo_plot.assert_points(points_expected=bad_pd_gdf, m=message) - plt.close() - - -def test_wrong_length_points_expected(pt_geo_plot, pd_gdf, bad_pd_gdf): - """Tests that error is thrown for incorrect lenght of a gdf""" - with pytest.raises(AssertionError, match="points_expected's length does "): - pt_geo_plot.assert_points(bad_pd_gdf.append(pd_gdf), "attr") - plt.close() - - -def test_assert_line_geo(poly_line_plot, two_line_gdf): - """Test that lines are asserted correctly""" - poly_line_plot.assert_lines(two_line_gdf) - plt.close() - - -def test_assert_multiline_geo(poly_multiline_plot, multi_line_gdf): - """Test that multi lines are asserted correctly""" - poly_multiline_plot.assert_lines(multi_line_gdf) - plt.close() - - -def test_assert_line_geo_fail(poly_line_plot, multi_line_gdf): - """Test that lines fail correctly""" - with pytest.raises(AssertionError, match="Incorrect Line Data"): - poly_line_plot.assert_lines(multi_line_gdf) - plt.close() - - -def test_assert_multiline_geo_fail(poly_multiline_plot, two_line_gdf): - """Test that multi lines fail correctly""" - with pytest.raises(AssertionError, match="Incorrect Line Data"): - poly_multiline_plot.assert_lines(two_line_gdf) - plt.close() - - -def test_assert_line_fails_list(poly_line_plot): - """Test that assert_lines fails when passed a list""" - linelist = [ - [(1, 1), (2, 2), (3, 2), (5, 3)], - [(3, 4), (5, 7), (12, 2), (10, 5), (9, 7.5)], - ] - with pytest.raises(ValueError, match="lines_expected is not expected ty"): - poly_line_plot.assert_lines(linelist) - plt.close() - - -def test_assert_line_geo_passed_nothing(poly_line_plot): - """Test that assertion passes when passed None""" - poly_line_plot.assert_lines(None) - plt.close() - - -def test_get_lines_geometry(poly_line_plot): - """Test that get_lines returns the proper values""" - lines = [(LineString(i[0])) for i in poly_line_plot.get_lines().values] - geometries = gpd.GeoDataFrame(geometry=lines) - poly_line_plot.assert_lines(geometries) - plt.close() - - -def test_assert_lines_grouped_by_type(poly_multiline_plot, multi_line_gdf): - """Test that assert works for grouped line plots""" - poly_multiline_plot.assert_lines_grouped_by_type(multi_line_gdf, "attr") - plt.close() - - -def test_assert_lines_grouped_by_type_fail( - poly_multiline_plot_bad, multi_line_gdf -): - """Test that assert fails for incorrectly grouped line plots""" - with pytest.raises(AssertionError, match="Line attributes not accurate "): - poly_multiline_plot_bad.assert_lines_grouped_by_type( - multi_line_gdf, "attr" - ) - plt.close() - - -def test_assert_lines_grouped_by_type_passes_with_none(poly_multiline_plot): - """Test that assert passes if nothing is passed into it""" - poly_multiline_plot.assert_lines_grouped_by_type(None, None) - plt.close() - - -def test_assert_lines_grouped_by_type_fails_non_gdf( - poly_multiline_plot, multi_line_gdf -): - """Test that assert fails if a list is passed into it""" - with pytest.raises(ValueError, match="lines_expected is not of expected "): - poly_multiline_plot.assert_lines_grouped_by_type( - multi_line_gdf.to_numpy(), "attr" - ) - plt.close() - - -def test_mixed_type_passes(mixed_type_geo_plot, pd_gdf): - """Tests that points passes with a mixed type plot""" - mixed_type_geo_plot.assert_points(pd_gdf) - plt.close() - - -def test_get_lines_by_collection(poly_multiline_plot): - """Test that get_lines_by_collection returns the correct values""" - lines_list = [ - [ - [(1, 1), (2, 2), (3, 2), (5, 3)], - [(3, 4), (5, 7), (12, 2), (10, 5), (9, 7.5)], - [(2, 1), (3, 1), (4, 1), (5, 2)], - ] - ] - sorted_lines_list = sorted([sorted(l) for l in lines_list]) - assert sorted_lines_list == poly_multiline_plot.get_lines_by_collection() - plt.close() From b9d9537adc9f394437407633020deee86554b062 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Thu, 19 Mar 2020 14:17:39 -0600 Subject: [PATCH 30/39] black --- matplotcheck/tests/test_lines.py | 26 +++++++++++++------------- matplotcheck/tests/test_points.py | 20 ++++++++++---------- matplotcheck/tests/test_polygons.py | 20 +++++++++----------- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/matplotcheck/tests/test_lines.py b/matplotcheck/tests/test_lines.py index 7c54db5f..1764000a 100644 --- a/matplotcheck/tests/test_lines.py +++ b/matplotcheck/tests/test_lines.py @@ -85,27 +85,27 @@ def poly_multiline_plot_bad(multi_line_gdf): def test_assert_line_geo(poly_line_plot, two_line_gdf): """Test that lines are asserted correctly""" poly_line_plot.assert_lines(two_line_gdf) - plt.close('all') + plt.close("all") def test_assert_multiline_geo(poly_multiline_plot, multi_line_gdf): """Test that multi lines are asserted correctly""" poly_multiline_plot.assert_lines(multi_line_gdf) - plt.close('all') + plt.close("all") def test_assert_line_geo_fail(poly_line_plot, multi_line_gdf): """Test that lines fail correctly""" with pytest.raises(AssertionError, match="Incorrect Line Data"): poly_line_plot.assert_lines(multi_line_gdf) - plt.close('all') + plt.close("all") def test_assert_multiline_geo_fail(poly_multiline_plot, two_line_gdf): """Test that multi lines fail correctly""" with pytest.raises(AssertionError, match="Incorrect Line Data"): poly_multiline_plot.assert_lines(two_line_gdf) - plt.close('all') + plt.close("all") def test_assert_line_fails_list(poly_line_plot): @@ -116,13 +116,13 @@ def test_assert_line_fails_list(poly_line_plot): ] with pytest.raises(ValueError, match="lines_expected is not expected ty"): poly_line_plot.assert_lines(linelist) - plt.close('all') + plt.close("all") def test_assert_line_geo_passed_nothing(poly_line_plot): """Test that assertion passes when passed None""" poly_line_plot.assert_lines(None) - plt.close('all') + plt.close("all") def test_get_lines_geometry(poly_line_plot): @@ -130,13 +130,13 @@ def test_get_lines_geometry(poly_line_plot): lines = [(LineString(i[0])) for i in poly_line_plot.get_lines().values] geometries = gpd.GeoDataFrame(geometry=lines) poly_line_plot.assert_lines(geometries) - plt.close('all') + plt.close("all") def test_assert_lines_grouped_by_type(poly_multiline_plot, multi_line_gdf): """Test that assert works for grouped line plots""" poly_multiline_plot.assert_lines_grouped_by_type(multi_line_gdf, "attr") - plt.close('all') + plt.close("all") def test_assert_lines_grouped_by_type_fail( @@ -147,13 +147,13 @@ def test_assert_lines_grouped_by_type_fail( poly_multiline_plot_bad.assert_lines_grouped_by_type( multi_line_gdf, "attr" ) - plt.close('all') + plt.close("all") def test_assert_lines_grouped_by_type_passes_with_none(poly_multiline_plot): """Test that assert passes if nothing is passed into it""" poly_multiline_plot.assert_lines_grouped_by_type(None, None) - plt.close('all') + plt.close("all") def test_assert_lines_grouped_by_type_fails_non_gdf( @@ -164,13 +164,13 @@ def test_assert_lines_grouped_by_type_fails_non_gdf( poly_multiline_plot.assert_lines_grouped_by_type( multi_line_gdf.to_numpy(), "attr" ) - plt.close('all') + plt.close("all") def test_mixed_type_passes(mixed_type_geo_plot, pd_gdf): """Tests that points passes with a mixed type plot""" mixed_type_geo_plot.assert_points(pd_gdf) - plt.close('all') + plt.close("all") def test_get_lines_by_collection(poly_multiline_plot): @@ -184,4 +184,4 @@ def test_get_lines_by_collection(poly_multiline_plot): ] sorted_lines_list = sorted([sorted(l) for l in lines_list]) assert sorted_lines_list == poly_multiline_plot.get_lines_by_collection() - plt.close('all') + plt.close("all") diff --git a/matplotcheck/tests/test_points.py b/matplotcheck/tests/test_points.py index 69cd3ce7..887d2c91 100644 --- a/matplotcheck/tests/test_points.py +++ b/matplotcheck/tests/test_points.py @@ -65,40 +65,40 @@ def point_geo_plot(pd_gdf): def test_points_sorted_by_markersize_pass(pt_geo_plot, pd_gdf): """Test points sorted by size of attribute pass""" pt_geo_plot.assert_collection_sorted_by_markersize(pd_gdf, "attr") - plt.close('all') + plt.close("all") def test_points_sorted_by_markersize_fail(pt_geo_plot_bad, pd_gdf): """Test points sorted by size of attribute fails""" with pytest.raises(AssertionError, match="Markersize not based on"): pt_geo_plot_bad.assert_collection_sorted_by_markersize(pd_gdf, "attr") - plt.close('all') + plt.close("all") def test_points_grouped_by_type(pt_geo_plot, pd_gdf): """Tests that points grouped by type passes""" pt_geo_plot.assert_points_grouped_by_type(pd_gdf, "attr") - plt.close('all') + plt.close("all") def test_points_grouped_by_type_fail(pt_geo_plot_bad, pd_gdf): """Tests that points grouped by type passes""" with pytest.raises(AssertionError, match="Point attributes not accurate"): pt_geo_plot_bad.assert_points_grouped_by_type(pd_gdf, "attr") - plt.close('all') + plt.close("all") def test_point_geometry_pass(point_geo_plot, pd_gdf): """Check that the point geometry test recognizes correct points.""" point_geo_plot.assert_points(points_expected=pd_gdf) - plt.close('all') + plt.close("all") def test_point_geometry_fail(point_geo_plot, bad_pd_gdf): """Check that the point geometry test recognizes incorrect points.""" with pytest.raises(AssertionError, match="Incorrect Point Data"): point_geo_plot.assert_points(points_expected=bad_pd_gdf) - plt.close('all') + plt.close("all") def test_assert_point_fails_list(point_geo_plot, pd_gdf): @@ -109,7 +109,7 @@ def test_assert_point_fails_list(point_geo_plot, pd_gdf): list_geo = [list(pd_gdf.geometry.x), list(pd_gdf.geometry.y)] with pytest.raises(ValueError, match="points_expected is not expected"): point_geo_plot.assert_points(points_expected=list_geo) - plt.close('all') + plt.close("all") def test_get_points(point_geo_plot, pd_gdf): @@ -117,7 +117,7 @@ def test_get_points(point_geo_plot, pd_gdf): xy_values = point_geo_plot.get_points() assert list(sorted(xy_values.x)) == sorted(list(pd_gdf.geometry.x)) assert list(sorted(xy_values.y)) == sorted(list(pd_gdf.geometry.y)) - plt.close('all') + plt.close("all") def test_assert_points_custom_message(point_geo_plot, bad_pd_gdf): @@ -125,11 +125,11 @@ def test_assert_points_custom_message(point_geo_plot, bad_pd_gdf): message = "Test message" with pytest.raises(AssertionError, match="Test message"): point_geo_plot.assert_points(points_expected=bad_pd_gdf, m=message) - plt.close('all') + plt.close("all") def test_wrong_length_points_expected(pt_geo_plot, pd_gdf, bad_pd_gdf): """Tests that error is thrown for incorrect lenght of a gdf""" with pytest.raises(AssertionError, match="points_expected's length does "): pt_geo_plot.assert_points(bad_pd_gdf.append(pd_gdf), "attr") - plt.close('all') + plt.close("all") diff --git a/matplotcheck/tests/test_polygons.py b/matplotcheck/tests/test_polygons.py index 3627e01c..378e227a 100644 --- a/matplotcheck/tests/test_polygons.py +++ b/matplotcheck/tests/test_polygons.py @@ -27,7 +27,6 @@ def multi_polygon_gdf(basic_polygon): return multi_gdf - @pytest.fixture def poly_line_plot(two_line_gdf): """Create a line vector tester object.""" @@ -88,40 +87,39 @@ def multi_poly_geo_plot(multi_polygon_gdf): return VectorTester(axis) - def test_list_of_polygons_check(poly_geo_plot, basic_polygon): """Check that the polygon assert works with a list of polygons.""" x, y = basic_polygon.exterior.coords.xy poly_list = [list(zip(x, y))] poly_geo_plot.assert_polygons(poly_list) - plt.close('all') + plt.close("all") def test_polygon_geodataframe_check(poly_geo_plot, basic_polygon_gdf): """Check that the polygon assert works with a polygon geodataframe""" poly_geo_plot.assert_polygons(basic_polygon_gdf) - plt.close('all') + plt.close("all") def test_empty_list_polygon_check(poly_geo_plot): """Check that the polygon assert fails an empty list.""" with pytest.raises(ValueError, match="Empty list or GeoDataFrame "): poly_geo_plot.assert_polygons([]) - plt.close('all') + plt.close("all") def test_empty_list_entry_polygon_check(poly_geo_plot): """Check that the polygon assert fails a list with an empty entry.""" with pytest.raises(ValueError, match="Empty list or GeoDataFrame "): poly_geo_plot.assert_polygons([[]]) - plt.close('all') + plt.close("all") def test_empty_gdf_polygon_check(poly_geo_plot): """Check that the polygon assert fails an empty GeoDataFrame.""" with pytest.raises(ValueError, match="Empty list or GeoDataFrame "): poly_geo_plot.assert_polygons(gpd.GeoDataFrame([])) - plt.close('all') + plt.close("all") def test_polygon_dec_check(poly_geo_plot, basic_polygon): @@ -132,7 +130,7 @@ def test_polygon_dec_check(poly_geo_plot, basic_polygon): x, y = basic_polygon.exterior.coords.xy poly_list = [[(x[0] + 0.1, x[1]) for x in list(zip(x, y))]] poly_geo_plot.assert_polygons(poly_list, dec=1) - plt.close('all') + plt.close("all") def test_polygon_dec_check_fail(poly_geo_plot, basic_polygon): @@ -144,7 +142,7 @@ def test_polygon_dec_check_fail(poly_geo_plot, basic_polygon): x, y = basic_polygon.exterior.coords.xy poly_list = [(x[0] + 0.5, x[1]) for x in list(zip(x, y))] poly_geo_plot.assert_polygons(poly_list, dec=1) - plt.close('all') + plt.close("all") def test_polygon_custom_fail_message(poly_geo_plot, basic_polygon): @@ -153,10 +151,10 @@ def test_polygon_custom_fail_message(poly_geo_plot, basic_polygon): x, y = basic_polygon.exterior.coords.xy poly_list = [(x[0] + 0.5, x[1]) for x in list(zip(x, y))] poly_geo_plot.assert_polygons(poly_list, m="Test Message") - plt.close('all') + plt.close("all") def test_multi_polygon_pass(multi_poly_geo_plot, multi_polygon_gdf): """Check a multipolygon passes""" multi_poly_geo_plot.assert_polygons(multi_polygon_gdf) - plt.close('all') + plt.close("all") From 084ffea69813575dfc004ba50302df3ad992b0b6 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Thu, 19 Mar 2020 15:54:26 -0600 Subject: [PATCH 31/39] Added tests for outlier cases --- matplotcheck/tests/conftest.py | 11 +++++- matplotcheck/tests/test_lines.py | 9 ----- matplotcheck/tests/test_points.py | 64 ++++++++++++++++++++++++------- 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/matplotcheck/tests/conftest.py b/matplotcheck/tests/conftest.py index 2d628a74..4e15ace1 100644 --- a/matplotcheck/tests/conftest.py +++ b/matplotcheck/tests/conftest.py @@ -2,7 +2,7 @@ import pytest import pandas as pd import geopandas as gpd -from shapely.geometry import Polygon +from shapely.geometry import Polygon, LineString import numpy as np import matplotlib.pyplot as plt from matplotcheck.base import PlotTester @@ -173,3 +173,12 @@ def pt_geo_plot(pd_gdf): axis = plt.gca() return PlotTester(axis) + + +@pytest.fixture +def two_line_gdf(): + """ Create Line Objects For Testing """ + linea = LineString([(1, 1), (2, 2), (3, 2), (5, 3)]) + lineb = LineString([(3, 4), (5, 7), (12, 2), (10, 5), (9, 7.5)]) + gdf = gpd.GeoDataFrame([1, 2], geometry=[linea, lineb], crs="epsg:4326") + return gdf diff --git a/matplotcheck/tests/test_lines.py b/matplotcheck/tests/test_lines.py index 1764000a..37ba63c3 100644 --- a/matplotcheck/tests/test_lines.py +++ b/matplotcheck/tests/test_lines.py @@ -9,15 +9,6 @@ matplotlib.use("Agg") -@pytest.fixture -def two_line_gdf(): - """ Create Line Objects For Testing """ - linea = LineString([(1, 1), (2, 2), (3, 2), (5, 3)]) - lineb = LineString([(3, 4), (5, 7), (12, 2), (10, 5), (9, 7.5)]) - gdf = gpd.GeoDataFrame([1, 2], geometry=[linea, lineb], crs="epsg:4326") - return gdf - - @pytest.fixture def multi_line_gdf(two_line_gdf): """ Create a multi-line GeoDataFrame. diff --git a/matplotcheck/tests/test_points.py b/matplotcheck/tests/test_points.py index 887d2c91..845d9f66 100644 --- a/matplotcheck/tests/test_points.py +++ b/matplotcheck/tests/test_points.py @@ -4,6 +4,7 @@ import geopandas as gpd from matplotcheck.vector import VectorTester import matplotlib +import numpy as np matplotlib.use("Agg") @@ -18,6 +19,17 @@ def bad_pd_gdf(pd_gdf): ) +@pytest.fixture +def edge_gdf(pd_gdf): + """Create a point geodataframe to test edge cases found in vector code""" + edge_gdf = pd_gdf.append( + gpd.GeoDataFrame(geometry=gpd.points_from_xy([0], [0])) + ) + edge_gdf.reset_index(inplace=True, drop=True) + edge_gdf.loc[edge_gdf.index == 5, "attr"] = "Flower" + return edge_gdf + + @pytest.fixture def pt_geo_plot(pd_gdf): """Create a geo plot for testing""" @@ -51,11 +63,21 @@ def pt_geo_plot_bad(pd_gdf): @pytest.fixture -def point_geo_plot(pd_gdf): - """Create a point plot for testing""" +def pt_geo_plot_edge(edge_gdf, two_line_gdf): + """Create a point plot for edge case testing""" _, ax = plt.subplots() + size = 0 + point_symb = {"Tree": "green", "Bush": "brown", "Flower": "purple"} - pd_gdf.plot(ax=ax) + for ctype, points in edge_gdf.groupby("attr"): + color = point_symb[ctype] + label = ctype + size += 100 + points.plot(color=color, ax=ax, label=label, markersize=size) + + two_line_gdf.plot(ax=ax) + + ax.legend(title="Legend", loc=(1.1, 0.1)) axis = plt.gca() @@ -88,43 +110,43 @@ def test_points_grouped_by_type_fail(pt_geo_plot_bad, pd_gdf): plt.close("all") -def test_point_geometry_pass(point_geo_plot, pd_gdf): +def test_point_geometry_pass(pt_geo_plot, pd_gdf): """Check that the point geometry test recognizes correct points.""" - point_geo_plot.assert_points(points_expected=pd_gdf) + pt_geo_plot.assert_points(points_expected=pd_gdf) plt.close("all") -def test_point_geometry_fail(point_geo_plot, bad_pd_gdf): +def test_point_geometry_fail(pt_geo_plot, bad_pd_gdf): """Check that the point geometry test recognizes incorrect points.""" with pytest.raises(AssertionError, match="Incorrect Point Data"): - point_geo_plot.assert_points(points_expected=bad_pd_gdf) + pt_geo_plot.assert_points(points_expected=bad_pd_gdf) plt.close("all") -def test_assert_point_fails_list(point_geo_plot, pd_gdf): +def test_assert_point_fails_list(pt_geo_plot, pd_gdf): """ Check that the point geometry test fails anything that's not a GeoDataFrame """ list_geo = [list(pd_gdf.geometry.x), list(pd_gdf.geometry.y)] with pytest.raises(ValueError, match="points_expected is not expected"): - point_geo_plot.assert_points(points_expected=list_geo) + pt_geo_plot.assert_points(points_expected=list_geo) plt.close("all") -def test_get_points(point_geo_plot, pd_gdf): +def test_get_points(pt_geo_plot, pd_gdf): """Tests that get_points returns correct values""" - xy_values = point_geo_plot.get_points() + xy_values = pt_geo_plot.get_points() assert list(sorted(xy_values.x)) == sorted(list(pd_gdf.geometry.x)) assert list(sorted(xy_values.y)) == sorted(list(pd_gdf.geometry.y)) plt.close("all") -def test_assert_points_custom_message(point_geo_plot, bad_pd_gdf): +def test_assert_points_custom_message(pt_geo_plot, bad_pd_gdf): """Tests that a custom error message is passed.""" message = "Test message" with pytest.raises(AssertionError, match="Test message"): - point_geo_plot.assert_points(points_expected=bad_pd_gdf, m=message) + pt_geo_plot.assert_points(points_expected=bad_pd_gdf, m=message) plt.close("all") @@ -133,3 +155,19 @@ def test_wrong_length_points_expected(pt_geo_plot, pd_gdf, bad_pd_gdf): with pytest.raises(AssertionError, match="points_expected's length does "): pt_geo_plot.assert_points(bad_pd_gdf.append(pd_gdf), "attr") plt.close("all") + + +def test_convert_length_error(pt_geo_plot): + """Test that the convert lenght function throws an error""" + with pytest.raises(ValueError, match="Input array length is not: 1 or 9"): + pt_geo_plot._convert_length(np.array([1, 2, 3, 4]), 9) + + +def test_point_gdf_with_zeros(pt_geo_plot_edge, edge_gdf): + """Test that assert_points works when there's a zero point in the gdf""" + pt_geo_plot_edge.assert_points(edge_gdf) + + +def test_point_gdf_with_more_marker_sizes(pt_geo_plot_edge, edge_gdf): + """Test that markersize works for many sizes""" + pt_geo_plot_edge.assert_points(edge_gdf, "attr") From 6ce798ccb03452a4f89cf00afa04f27d06f63f0e Mon Sep 17 00:00:00 2001 From: Nathan Korinek Date: Thu, 19 Mar 2020 16:57:41 -0600 Subject: [PATCH 32/39] Update matplotcheck/tests/test_points.py typo Co-Authored-By: Leah Wasser --- matplotcheck/tests/test_points.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matplotcheck/tests/test_points.py b/matplotcheck/tests/test_points.py index 845d9f66..4f411282 100644 --- a/matplotcheck/tests/test_points.py +++ b/matplotcheck/tests/test_points.py @@ -151,7 +151,7 @@ def test_assert_points_custom_message(pt_geo_plot, bad_pd_gdf): def test_wrong_length_points_expected(pt_geo_plot, pd_gdf, bad_pd_gdf): - """Tests that error is thrown for incorrect lenght of a gdf""" + """Tests that error is thrown for incorrect length of a gdf""" with pytest.raises(AssertionError, match="points_expected's length does "): pt_geo_plot.assert_points(bad_pd_gdf.append(pd_gdf), "attr") plt.close("all") From 71e804036c2e1683f02311a3c8beb2a1102420d9 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Thu, 19 Mar 2020 16:58:18 -0600 Subject: [PATCH 33/39] took plt.gca() out of tests --- CHANGELOG.md | 1 + matplotcheck/tests/conftest.py | 42 +++++++++++------------------ matplotcheck/tests/test_lines.py | 16 +++-------- matplotcheck/tests/test_points.py | 12 +++------ matplotcheck/tests/test_polygons.py | 20 ++++---------- 5 files changed, 28 insertions(+), 63 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86f7f067..4cdaeded 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +* Created test for the vector module (@nkorinek, #209) * Created functions to test point geometries in VectorTester (@nkorinek, #176) * made `assert_string_contains()` accept correct strings with spaces in them (@nkorinek, #182) * added contributors file and updated README to remove that information (@nkorinek, #121) diff --git a/matplotcheck/tests/conftest.py b/matplotcheck/tests/conftest.py index 4e15ace1..9dc7c4c2 100644 --- a/matplotcheck/tests/conftest.py +++ b/matplotcheck/tests/conftest.py @@ -68,6 +68,15 @@ def basic_polygon_gdf(basic_polygon): return gdf +@pytest.fixture +def two_line_gdf(): + """ Create Line Objects For Testing """ + linea = LineString([(1, 1), (2, 2), (3, 2), (5, 3)]) + lineb = LineString([(3, 4), (5, 7), (12, 2), (10, 5), (9, 7.5)]) + gdf = gpd.GeoDataFrame([1, 2], geometry=[linea, lineb], crs="epsg:4326") + return gdf + + @pytest.fixture def pd_xlabels(): """Create a DataFrame which uses the column labels as x-data.""" @@ -85,9 +94,7 @@ def pt_scatter_plt(pd_df): ax.set_xlabel("x label") ax.set_ylabel("y label") - axis = plt.gca() - - return PlotTester(axis) + return PlotTester(ax) @pytest.fixture @@ -110,9 +117,7 @@ def pt_line_plt(pd_df): ax_position.ymax - 0.25, ax_position.ymin - 0.075, "Figure Caption" ) - axis = plt.gca() - - return PlotTester(axis) + return PlotTester(ax) @pytest.fixture @@ -123,9 +128,7 @@ def pt_multi_line_plt(pd_df): ax.set_ylim((0, 140)) ax.legend(loc="center left", title="Legend", bbox_to_anchor=(1, 0.5)) - axis = plt.gca() - - return PlotTester(axis) + return PlotTester(ax) @pytest.fixture @@ -138,9 +141,7 @@ def pt_bar_plt(pd_df): ax.set_xlabel("x label") ax.set_ylabel("y label") - axis = plt.gca() - - return PlotTester(axis) + return PlotTester(ax) @pytest.fixture @@ -150,9 +151,7 @@ def pt_time_line_plt(pd_df_timeseries): pd_df_timeseries.plot("time", "A", kind="line", ax=ax) - axis = plt.gca() - - return PlotTester(axis) + return PlotTester(ax) @pytest.fixture @@ -170,15 +169,4 @@ def pt_geo_plot(pd_gdf): ax.legend(title="Legend", loc=(1.1, 0.1)) - axis = plt.gca() - - return PlotTester(axis) - - -@pytest.fixture -def two_line_gdf(): - """ Create Line Objects For Testing """ - linea = LineString([(1, 1), (2, 2), (3, 2), (5, 3)]) - lineb = LineString([(3, 4), (5, 7), (12, 2), (10, 5), (9, 7.5)]) - gdf = gpd.GeoDataFrame([1, 2], geometry=[linea, lineb], crs="epsg:4326") - return gdf + return PlotTester(ax) diff --git a/matplotcheck/tests/test_lines.py b/matplotcheck/tests/test_lines.py index 37ba63c3..c6fb4b29 100644 --- a/matplotcheck/tests/test_lines.py +++ b/matplotcheck/tests/test_lines.py @@ -32,9 +32,7 @@ def mixed_type_geo_plot(pd_gdf, multi_line_gdf): pd_gdf.plot(ax=ax) multi_line_gdf.plot(ax=ax) - axis = plt.gca() - - return VectorTester(axis) + return VectorTester(ax) @pytest.fixture @@ -44,9 +42,7 @@ def poly_line_plot(two_line_gdf): two_line_gdf.plot(ax=ax) - axis = plt.gca() - - return VectorTester(axis) + return VectorTester(ax) @pytest.fixture @@ -56,9 +52,7 @@ def poly_multiline_plot(multi_line_gdf): multi_line_gdf.plot(ax=ax, column="attr") - axis = plt.gca() - - return VectorTester(axis) + return VectorTester(ax) @pytest.fixture @@ -68,9 +62,7 @@ def poly_multiline_plot_bad(multi_line_gdf): multi_line_gdf.plot(ax=ax) - axis = plt.gca() - - return VectorTester(axis) + return VectorTester(ax) def test_assert_line_geo(poly_line_plot, two_line_gdf): diff --git a/matplotcheck/tests/test_points.py b/matplotcheck/tests/test_points.py index 845d9f66..52b64ece 100644 --- a/matplotcheck/tests/test_points.py +++ b/matplotcheck/tests/test_points.py @@ -45,9 +45,7 @@ def pt_geo_plot(pd_gdf): ax.legend(title="Legend", loc=(1.1, 0.1)) - axis = plt.gca() - - return VectorTester(axis) + return VectorTester(ax) @pytest.fixture @@ -57,9 +55,7 @@ def pt_geo_plot_bad(pd_gdf): pd_gdf.plot(ax=ax) - axis = plt.gca() - - return VectorTester(axis) + return VectorTester(ax) @pytest.fixture @@ -79,9 +75,7 @@ def pt_geo_plot_edge(edge_gdf, two_line_gdf): ax.legend(title="Legend", loc=(1.1, 0.1)) - axis = plt.gca() - - return VectorTester(axis) + return VectorTester(ax) def test_points_sorted_by_markersize_pass(pt_geo_plot, pd_gdf): diff --git a/matplotcheck/tests/test_polygons.py b/matplotcheck/tests/test_polygons.py index 378e227a..243c4d41 100644 --- a/matplotcheck/tests/test_polygons.py +++ b/matplotcheck/tests/test_polygons.py @@ -34,9 +34,7 @@ def poly_line_plot(two_line_gdf): two_line_gdf.plot(ax=ax) - axis = plt.gca() - - return VectorTester(axis) + return VectorTester(ax) @pytest.fixture @@ -46,9 +44,7 @@ def poly_multiline_plot(multi_line_gdf): multi_line_gdf.plot(ax=ax, column="attr") - axis = plt.gca() - - return VectorTester(axis) + return VectorTester(ax) @pytest.fixture @@ -58,9 +54,7 @@ def poly_multiline_plot_bad(multi_line_gdf): multi_line_gdf.plot(ax=ax) - axis = plt.gca() - - return VectorTester(axis) + return VectorTester(ax) @pytest.fixture @@ -70,9 +64,7 @@ def poly_geo_plot(basic_polygon_gdf): basic_polygon_gdf.plot(ax=ax) - axis = plt.gca() - - return VectorTester(axis) + return VectorTester(ax) @pytest.fixture @@ -82,9 +74,7 @@ def multi_poly_geo_plot(multi_polygon_gdf): multi_polygon_gdf.plot(ax=ax) - axis = plt.gca() - - return VectorTester(axis) + return VectorTester(ax) def test_list_of_polygons_check(poly_geo_plot, basic_polygon): From 7de3c095e6e9fb9a0f087d50669b521c05ab0782 Mon Sep 17 00:00:00 2001 From: nkorinek Date: Fri, 20 Mar 2020 11:27:36 -0600 Subject: [PATCH 34/39] Added changes suggested on GitHub --- matplotcheck/tests/test_lines.py | 59 +++++++++++++++-------------- matplotcheck/tests/test_points.py | 56 ++++++++++++--------------- matplotcheck/tests/test_polygons.py | 33 +--------------- 3 files changed, 57 insertions(+), 91 deletions(-) diff --git a/matplotcheck/tests/test_lines.py b/matplotcheck/tests/test_lines.py index c6fb4b29..96132da2 100644 --- a/matplotcheck/tests/test_lines.py +++ b/matplotcheck/tests/test_lines.py @@ -1,10 +1,11 @@ """Tests for the vector module""" +import matplotlib import pytest import matplotlib.pyplot as plt import geopandas as gpd from shapely.geometry import LineString + from matplotcheck.vector import VectorTester -import matplotlib matplotlib.use("Agg") @@ -36,7 +37,7 @@ def mixed_type_geo_plot(pd_gdf, multi_line_gdf): @pytest.fixture -def poly_line_plot(two_line_gdf): +def line_geo_plot(two_line_gdf): """Create a line vector tester object.""" _, ax = plt.subplots() @@ -46,7 +47,7 @@ def poly_line_plot(two_line_gdf): @pytest.fixture -def poly_multiline_plot(multi_line_gdf): +def multiline_geo_plot(multi_line_gdf): """Create a multiline vector tester object.""" _, ax = plt.subplots() @@ -56,7 +57,7 @@ def poly_multiline_plot(multi_line_gdf): @pytest.fixture -def poly_multiline_plot_bad(multi_line_gdf): +def multiline_geo_plot_bad(multi_line_gdf): """Create a multiline vector tester object.""" _, ax = plt.subplots() @@ -65,86 +66,86 @@ def poly_multiline_plot_bad(multi_line_gdf): return VectorTester(ax) -def test_assert_line_geo(poly_line_plot, two_line_gdf): +def test_assert_line_geo(line_geo_plot, two_line_gdf): """Test that lines are asserted correctly""" - poly_line_plot.assert_lines(two_line_gdf) + line_geo_plot.assert_lines(two_line_gdf) plt.close("all") -def test_assert_multiline_geo(poly_multiline_plot, multi_line_gdf): +def test_assert_multiline_geo(multiline_geo_plot, multi_line_gdf): """Test that multi lines are asserted correctly""" - poly_multiline_plot.assert_lines(multi_line_gdf) + multiline_geo_plot.assert_lines(multi_line_gdf) plt.close("all") -def test_assert_line_geo_fail(poly_line_plot, multi_line_gdf): +def test_assert_line_geo_fail(line_geo_plot, multi_line_gdf): """Test that lines fail correctly""" with pytest.raises(AssertionError, match="Incorrect Line Data"): - poly_line_plot.assert_lines(multi_line_gdf) + line_geo_plot.assert_lines(multi_line_gdf) plt.close("all") -def test_assert_multiline_geo_fail(poly_multiline_plot, two_line_gdf): +def test_assert_multiline_geo_fail(multiline_geo_plot, two_line_gdf): """Test that multi lines fail correctly""" with pytest.raises(AssertionError, match="Incorrect Line Data"): - poly_multiline_plot.assert_lines(two_line_gdf) + multiline_geo_plot.assert_lines(two_line_gdf) plt.close("all") -def test_assert_line_fails_list(poly_line_plot): +def test_assert_line_fails_list(line_geo_plot): """Test that assert_lines fails when passed a list""" linelist = [ [(1, 1), (2, 2), (3, 2), (5, 3)], [(3, 4), (5, 7), (12, 2), (10, 5), (9, 7.5)], ] with pytest.raises(ValueError, match="lines_expected is not expected ty"): - poly_line_plot.assert_lines(linelist) + line_geo_plot.assert_lines(linelist) plt.close("all") -def test_assert_line_geo_passed_nothing(poly_line_plot): +def test_assert_line_geo_passed_nothing(line_geo_plot): """Test that assertion passes when passed None""" - poly_line_plot.assert_lines(None) + line_geo_plot.assert_lines(None) plt.close("all") -def test_get_lines_geometry(poly_line_plot): +def test_get_lines_geometry(line_geo_plot): """Test that get_lines returns the proper values""" - lines = [(LineString(i[0])) for i in poly_line_plot.get_lines().values] + lines = [(LineString(i[0])) for i in line_geo_plot.get_lines().values] geometries = gpd.GeoDataFrame(geometry=lines) - poly_line_plot.assert_lines(geometries) + line_geo_plot.assert_lines(geometries) plt.close("all") -def test_assert_lines_grouped_by_type(poly_multiline_plot, multi_line_gdf): +def test_assert_lines_grouped_by_type(multiline_geo_plot, multi_line_gdf): """Test that assert works for grouped line plots""" - poly_multiline_plot.assert_lines_grouped_by_type(multi_line_gdf, "attr") + multiline_geo_plot.assert_lines_grouped_by_type(multi_line_gdf, "attr") plt.close("all") def test_assert_lines_grouped_by_type_fail( - poly_multiline_plot_bad, multi_line_gdf + multiline_geo_plot_bad, multi_line_gdf ): """Test that assert fails for incorrectly grouped line plots""" with pytest.raises(AssertionError, match="Line attributes not accurate "): - poly_multiline_plot_bad.assert_lines_grouped_by_type( + multiline_geo_plot_bad.assert_lines_grouped_by_type( multi_line_gdf, "attr" ) plt.close("all") -def test_assert_lines_grouped_by_type_passes_with_none(poly_multiline_plot): +def test_assert_lines_grouped_by_type_passes_with_none(multiline_geo_plot): """Test that assert passes if nothing is passed into it""" - poly_multiline_plot.assert_lines_grouped_by_type(None, None) + multiline_geo_plot.assert_lines_grouped_by_type(None, None) plt.close("all") def test_assert_lines_grouped_by_type_fails_non_gdf( - poly_multiline_plot, multi_line_gdf + multiline_geo_plot, multi_line_gdf ): """Test that assert fails if a list is passed into it""" with pytest.raises(ValueError, match="lines_expected is not of expected "): - poly_multiline_plot.assert_lines_grouped_by_type( + multiline_geo_plot.assert_lines_grouped_by_type( multi_line_gdf.to_numpy(), "attr" ) plt.close("all") @@ -156,7 +157,7 @@ def test_mixed_type_passes(mixed_type_geo_plot, pd_gdf): plt.close("all") -def test_get_lines_by_collection(poly_multiline_plot): +def test_get_lines_by_collection(multiline_geo_plot): """Test that get_lines_by_collection returns the correct values""" lines_list = [ [ @@ -166,5 +167,5 @@ def test_get_lines_by_collection(poly_multiline_plot): ] ] sorted_lines_list = sorted([sorted(l) for l in lines_list]) - assert sorted_lines_list == poly_multiline_plot.get_lines_by_collection() + assert sorted_lines_list == multiline_geo_plot.get_lines_by_collection() plt.close("all") diff --git a/matplotcheck/tests/test_points.py b/matplotcheck/tests/test_points.py index 2f9eb547..9415028b 100644 --- a/matplotcheck/tests/test_points.py +++ b/matplotcheck/tests/test_points.py @@ -1,10 +1,11 @@ """Tests for the vector module""" +import numpy as np +import matplotlib import pytest import matplotlib.pyplot as plt import geopandas as gpd + from matplotcheck.vector import VectorTester -import matplotlib -import numpy as np matplotlib.use("Agg") @@ -20,14 +21,15 @@ def bad_pd_gdf(pd_gdf): @pytest.fixture -def edge_gdf(pd_gdf): - """Create a point geodataframe to test edge cases found in vector code""" - edge_gdf = pd_gdf.append( +def origin_pt_gdf(pd_gdf): + """Create a point geodataframe to test assert_points when a point at the + origin of the plot (0, 0) is present in the dataframe. This checks + for a specific bug fix that was added to the assert_points function.""" + origin_pt_gdf = pd_gdf.append( gpd.GeoDataFrame(geometry=gpd.points_from_xy([0], [0])) ) - edge_gdf.reset_index(inplace=True, drop=True) - edge_gdf.loc[edge_gdf.index == 5, "attr"] = "Flower" - return edge_gdf + origin_pt_gdf.reset_index(inplace=True, drop=True) + return origin_pt_gdf @pytest.fixture @@ -59,33 +61,28 @@ def pt_geo_plot_bad(pd_gdf): @pytest.fixture -def pt_geo_plot_edge(edge_gdf, two_line_gdf): - """Create a point plot for edge case testing""" +def pt_geo_plot_origin(origin_pt_gdf, two_line_gdf): + """Create a point plot for testing assert_points with a point at the + origin""" _, ax = plt.subplots() - size = 0 - point_symb = {"Tree": "green", "Bush": "brown", "Flower": "purple"} - for ctype, points in edge_gdf.groupby("attr"): - color = point_symb[ctype] - label = ctype - size += 100 - points.plot(color=color, ax=ax, label=label, markersize=size) + origin_pt_gdf.plot(ax=ax) two_line_gdf.plot(ax=ax) - ax.legend(title="Legend", loc=(1.1, 0.1)) - return VectorTester(ax) def test_points_sorted_by_markersize_pass(pt_geo_plot, pd_gdf): - """Test points sorted by size of attribute pass""" + """Tests that points are plotted as different sizes based on an attribute + value passes""" pt_geo_plot.assert_collection_sorted_by_markersize(pd_gdf, "attr") plt.close("all") def test_points_sorted_by_markersize_fail(pt_geo_plot_bad, pd_gdf): - """Test points sorted by size of attribute fails""" + """Tests that points are plotted as different sizes based on an attribute + value fails""" with pytest.raises(AssertionError, match="Markersize not based on"): pt_geo_plot_bad.assert_collection_sorted_by_markersize(pd_gdf, "attr") plt.close("all") @@ -151,17 +148,14 @@ def test_wrong_length_points_expected(pt_geo_plot, pd_gdf, bad_pd_gdf): plt.close("all") -def test_convert_length_error(pt_geo_plot): - """Test that the convert lenght function throws an error""" +def test_convert_length_function_error(pt_geo_plot): + """Test that the convert length function throws an error when given + incorrect inputs""" with pytest.raises(ValueError, match="Input array length is not: 1 or 9"): pt_geo_plot._convert_length(np.array([1, 2, 3, 4]), 9) -def test_point_gdf_with_zeros(pt_geo_plot_edge, edge_gdf): - """Test that assert_points works when there's a zero point in the gdf""" - pt_geo_plot_edge.assert_points(edge_gdf) - - -def test_point_gdf_with_more_marker_sizes(pt_geo_plot_edge, edge_gdf): - """Test that markersize works for many sizes""" - pt_geo_plot_edge.assert_points(edge_gdf, "attr") +def test_point_gdf_with_point_at_origin(pt_geo_plot_origin, origin_pt_gdf): + """Test that assert_points works when there's a point at the origin in the + gdf""" + pt_geo_plot_origin.assert_points(origin_pt_gdf) diff --git a/matplotcheck/tests/test_polygons.py b/matplotcheck/tests/test_polygons.py index 243c4d41..efca744a 100644 --- a/matplotcheck/tests/test_polygons.py +++ b/matplotcheck/tests/test_polygons.py @@ -1,10 +1,11 @@ """Tests for the vector module""" +import matplotlib import pytest import matplotlib.pyplot as plt import geopandas as gpd from shapely.geometry import Polygon + from matplotcheck.vector import VectorTester -import matplotlib matplotlib.use("Agg") @@ -27,36 +28,6 @@ def multi_polygon_gdf(basic_polygon): return multi_gdf -@pytest.fixture -def poly_line_plot(two_line_gdf): - """Create a line vector tester object.""" - _, ax = plt.subplots() - - two_line_gdf.plot(ax=ax) - - return VectorTester(ax) - - -@pytest.fixture -def poly_multiline_plot(multi_line_gdf): - """Create a multiline vector tester object.""" - _, ax = plt.subplots() - - multi_line_gdf.plot(ax=ax, column="attr") - - return VectorTester(ax) - - -@pytest.fixture -def poly_multiline_plot_bad(multi_line_gdf): - """Create a multiline vector tester object.""" - _, ax = plt.subplots() - - multi_line_gdf.plot(ax=ax) - - return VectorTester(ax) - - @pytest.fixture def poly_geo_plot(basic_polygon_gdf): """Create a polygon vector tester object.""" From fd63fe411a8dc9566e221549c0f9936a858dd6c3 Mon Sep 17 00:00:00 2001 From: Leah Wasser Date: Fri, 20 Mar 2020 16:09:46 -0600 Subject: [PATCH 35/39] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cdaeded..af32256c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] -* Created test for the vector module (@nkorinek, #209) +* Created tests for the vector module (@nkorinek, #209) * Created functions to test point geometries in VectorTester (@nkorinek, #176) * made `assert_string_contains()` accept correct strings with spaces in them (@nkorinek, #182) * added contributors file and updated README to remove that information (@nkorinek, #121) From dd50a4a07a1c0aa248f2c92d9ac1a7ef9ccaa88b Mon Sep 17 00:00:00 2001 From: Leah Wasser Date: Fri, 20 Mar 2020 16:11:45 -0600 Subject: [PATCH 36/39] fix import order --- matplotcheck/tests/test_polygons.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matplotcheck/tests/test_polygons.py b/matplotcheck/tests/test_polygons.py index efca744a..d626de3a 100644 --- a/matplotcheck/tests/test_polygons.py +++ b/matplotcheck/tests/test_polygons.py @@ -1,7 +1,7 @@ """Tests for the vector module""" import matplotlib -import pytest import matplotlib.pyplot as plt +import pytest import geopandas as gpd from shapely.geometry import Polygon From e7a8ea6f2aa5d1dc35976cbddf6426d83d9ce4a5 Mon Sep 17 00:00:00 2001 From: Leah Wasser Date: Fri, 20 Mar 2020 16:12:22 -0600 Subject: [PATCH 37/39] import order fix --- matplotcheck/tests/conftest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/matplotcheck/tests/conftest.py b/matplotcheck/tests/conftest.py index 9dc7c4c2..0bad338a 100644 --- a/matplotcheck/tests/conftest.py +++ b/matplotcheck/tests/conftest.py @@ -1,10 +1,10 @@ """Pytest fixtures for matplotcheck tests""" import pytest +import numpy as np +import matplotlib.pyplot as plt import pandas as pd import geopandas as gpd from shapely.geometry import Polygon, LineString -import numpy as np -import matplotlib.pyplot as plt from matplotcheck.base import PlotTester From 3fc791e31197b1a953c9c551ed30ecd0afc52e2d Mon Sep 17 00:00:00 2001 From: Leah Wasser Date: Fri, 20 Mar 2020 16:12:53 -0600 Subject: [PATCH 38/39] import order --- matplotcheck/tests/test_lines.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matplotcheck/tests/test_lines.py b/matplotcheck/tests/test_lines.py index 96132da2..14d68c12 100644 --- a/matplotcheck/tests/test_lines.py +++ b/matplotcheck/tests/test_lines.py @@ -1,7 +1,7 @@ """Tests for the vector module""" import matplotlib -import pytest import matplotlib.pyplot as plt +import pytest import geopandas as gpd from shapely.geometry import LineString From 44f43343e50ccbc2af905e1df6299ae35eb3b2f5 Mon Sep 17 00:00:00 2001 From: Leah Wasser Date: Fri, 20 Mar 2020 16:13:16 -0600 Subject: [PATCH 39/39] import order --- matplotcheck/tests/test_points.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matplotcheck/tests/test_points.py b/matplotcheck/tests/test_points.py index 9415028b..f2ead5f7 100644 --- a/matplotcheck/tests/test_points.py +++ b/matplotcheck/tests/test_points.py @@ -1,8 +1,8 @@ """Tests for the vector module""" import numpy as np import matplotlib -import pytest import matplotlib.pyplot as plt +import pytest import geopandas as gpd from matplotcheck.vector import VectorTester