Skip to content

Commit

Permalink
Additional vector tests (#212)
Browse files Browse the repository at this point in the history
* Added a get_points() and assert_points() function to the vector tester.

* Added in get_points() and assert_points() functions with tests

* Added proper documentation

* Small fix to please codacy

* black

* Updated changelog

* First round of tests for vector

* black

* Rough draft for bug fix

* Fixed bug with multiple geometries plotted alongside bug with identical x values causing failure!

* typo

* Fixed small bug with markersize

* Added comments explaining code

* rough drafts of more tests

* Added more tests for legends

* Added more tests, and took out broken tests

* small codacy fix

* Fixed test!

* Taking out redundant tests

* Took out unneccesary tests

* Added plt.close

* Added more tests

* Typo

* more tests for uncovered parts of the vector file

* black

* Fixed issues with vector checking truth value of dataframe, and added tests

* Fixing how vector checks for truth value of a dataframe

* Added more coverage!

* Broke tests up into individual files

* black

* Added tests for outlier cases

* Update matplotcheck/tests/test_points.py

typo

Co-Authored-By: Leah Wasser <[email protected]>

* took plt.gca() out of tests

* Added changes suggested on GitHub

* Update CHANGELOG.md

* fix import order

* import order fix

* import order

* import order

Co-authored-by: Leah Wasser <[email protected]>
  • Loading branch information
nkorinek and Leah Wasser authored Mar 23, 2020
1 parent 21a6e8c commit c948af0
Show file tree
Hide file tree
Showing 5 changed files with 404 additions and 95 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 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)
Expand Down
58 changes: 30 additions & 28 deletions matplotcheck/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"""Pytest fixtures for matplotcheck tests"""
import pytest
import pandas as pd
import geopandas as gpd
from shapely.geometry import Polygon
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import geopandas as gpd
from shapely.geometry import Polygon, LineString
from matplotcheck.base import PlotTester


Expand Down Expand Up @@ -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


Expand Down Expand Up @@ -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."""
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -150,21 +151,22 @@ 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
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)

axis = plt.gca()
ax.legend(title="Legend", loc=(1.1, 0.1))

return PlotTester(axis)
return PlotTester(ax)
171 changes: 171 additions & 0 deletions matplotcheck/tests/test_lines.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
"""Tests for the vector module"""
import matplotlib
import matplotlib.pyplot as plt
import pytest
import geopandas as gpd
from shapely.geometry import LineString

from matplotcheck.vector import VectorTester

matplotlib.use("Agg")


@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)

return VectorTester(ax)


@pytest.fixture
def line_geo_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 multiline_geo_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 multiline_geo_plot_bad(multi_line_gdf):
"""Create a multiline vector tester object."""
_, ax = plt.subplots()

multi_line_gdf.plot(ax=ax)

return VectorTester(ax)


def test_assert_line_geo(line_geo_plot, two_line_gdf):
"""Test that lines are asserted correctly"""
line_geo_plot.assert_lines(two_line_gdf)
plt.close("all")


def test_assert_multiline_geo(multiline_geo_plot, multi_line_gdf):
"""Test that multi lines are asserted correctly"""
multiline_geo_plot.assert_lines(multi_line_gdf)
plt.close("all")


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"):
line_geo_plot.assert_lines(multi_line_gdf)
plt.close("all")


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"):
multiline_geo_plot.assert_lines(two_line_gdf)
plt.close("all")


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"):
line_geo_plot.assert_lines(linelist)
plt.close("all")


def test_assert_line_geo_passed_nothing(line_geo_plot):
"""Test that assertion passes when passed None"""
line_geo_plot.assert_lines(None)
plt.close("all")


def test_get_lines_geometry(line_geo_plot):
"""Test that get_lines returns the proper values"""
lines = [(LineString(i[0])) for i in line_geo_plot.get_lines().values]
geometries = gpd.GeoDataFrame(geometry=lines)
line_geo_plot.assert_lines(geometries)
plt.close("all")


def test_assert_lines_grouped_by_type(multiline_geo_plot, multi_line_gdf):
"""Test that assert works for grouped line plots"""
multiline_geo_plot.assert_lines_grouped_by_type(multi_line_gdf, "attr")
plt.close("all")


def test_assert_lines_grouped_by_type_fail(
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 "):
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(multiline_geo_plot):
"""Test that assert passes if nothing is passed into it"""
multiline_geo_plot.assert_lines_grouped_by_type(None, None)
plt.close("all")


def test_assert_lines_grouped_by_type_fails_non_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 "):
multiline_geo_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(multiline_geo_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 == multiline_geo_plot.get_lines_by_collection()
plt.close("all")
Loading

0 comments on commit c948af0

Please sign in to comment.