From 42d40edc6b1074c7436d06578e63287a71d99e1a Mon Sep 17 00:00:00 2001 From: Kunxian Huang Date: Mon, 23 Sep 2024 16:58:12 +0800 Subject: [PATCH 1/4] add spade codes --- src/data_morph/shapes/factory.py | 1 + src/data_morph/shapes/points.py | 63 ++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/src/data_morph/shapes/factory.py b/src/data_morph/shapes/factory.py index 2b2db2af..1e0e5f33 100644 --- a/src/data_morph/shapes/factory.py +++ b/src/data_morph/shapes/factory.py @@ -53,6 +53,7 @@ class ShapeFactory: 'rectangle': polygons.Rectangle, 'rings': circles.Rings, 'star': polygons.Star, + 'spade': points.Spade, } AVAILABLE_SHAPES: list[str] = sorted(_SHAPE_MAPPING.keys()) diff --git a/src/data_morph/shapes/points.py b/src/data_morph/shapes/points.py index 158be2a8..381fe685 100644 --- a/src/data_morph/shapes/points.py +++ b/src/data_morph/shapes/points.py @@ -304,3 +304,66 @@ def distance(self, x: Number, y: Number) -> int: Always returns 0 to allow for scattering of the points. """ return 0 + + +class Spade(PointCollection): + """ + Class for the spade shape. + + .. plot:: + :scale: 75 + :caption: + This shape is generated using the panda dataset. + + from data_morph.data.loader import DataLoader + from data_morph.shapes.points import Spade + + _ = Spade(DataLoader.load_dataset('panda')).plot() + + Parameters + ---------- + dataset : Dataset + The starting dataset to morph into other shapes. + """ + + def __init__(self, dataset: Dataset) -> None: + x_bounds = dataset.data_bounds.x_bounds + y_bounds = dataset.data_bounds.y_bounds + + # make heart points using Heart + heart_stack = Heart(dataset).points + + # Graph heart curve + x_shift = sum(x_bounds) / 2 + y_shift = sum(y_bounds) / 2 + + # vertical flip for heart + heart_y = -1.0 * (heart_stack[:, 1] - y_shift) + y_shift + + # Here, I reference kevinr1299 codes + # Graph line base + line_x = np.linspace(-6, 6, num=12) + line_y = np.repeat(-16, 12) + + # Graph left wing + left_x = np.linspace(-6, 0, num=12) + left_y = 0.278 * np.power(left_x + 6.0, 2) - 16.0 + + # Graph right wing + right_x = np.linspace(0, 6, num=12) + right_y = 0.278 * np.power(right_x - 6.0, 2) - 16.0 + + # shift and scale the base and wing + x = np.concatenate((line_x, left_x, right_x), axis=0) + y = np.concatenate((line_y, left_y, right_y), axis=0) + + # scale by the half the widest width of the spade + scale_factor = (x_bounds[1] - x_shift) / 16 + + x = x * scale_factor + x_shift + y = y * scale_factor + y_shift + + x = np.concatenate((heart_stack[:, 0], x), axis=0) + y = np.concatenate((heart_y, y), axis=0) + + super().__init__(*np.stack([x, y], axis=1)) From 08cdb64db65460174ebfb6fb47d7f79729ac08d6 Mon Sep 17 00:00:00 2001 From: Stefanie Molin <24376333+stefmolin@users.noreply.github.com> Date: Fri, 27 Sep 2024 15:11:45 +0900 Subject: [PATCH 2/4] Clean up spade code from multiple PRs --- src/data_morph/shapes/points.py | 34 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/src/data_morph/shapes/points.py b/src/data_morph/shapes/points.py index 381fe685..5def8bab 100644 --- a/src/data_morph/shapes/points.py +++ b/src/data_morph/shapes/points.py @@ -330,40 +330,36 @@ def __init__(self, dataset: Dataset) -> None: x_bounds = dataset.data_bounds.x_bounds y_bounds = dataset.data_bounds.y_bounds - # make heart points using Heart - heart_stack = Heart(dataset).points - - # Graph heart curve x_shift = sum(x_bounds) / 2 y_shift = sum(y_bounds) / 2 - # vertical flip for heart - heart_y = -1.0 * (heart_stack[:, 1] - y_shift) + y_shift + # graph upside-down heart + heart_points = Heart(dataset).points + heart_points[:, 1] = -heart_points[:, 1] + 2 * y_shift - # Here, I reference kevinr1299 codes - # Graph line base + # line base line_x = np.linspace(-6, 6, num=12) line_y = np.repeat(-16, 12) - # Graph left wing + # left wing left_x = np.linspace(-6, 0, num=12) - left_y = 0.278 * np.power(left_x + 6.0, 2) - 16.0 + left_y = 0.278 * np.power(left_x + 6.0, 2) - 16 - # Graph right wing + # right wing right_x = np.linspace(0, 6, num=12) - right_y = 0.278 * np.power(right_x - 6.0, 2) - 16.0 + right_y = 0.278 * np.power(right_x - 6.0, 2) - 16 # shift and scale the base and wing - x = np.concatenate((line_x, left_x, right_x), axis=0) - y = np.concatenate((line_y, left_y, right_y), axis=0) + base_x = np.concatenate((line_x, left_x, right_x), axis=0) + base_y = np.concatenate((line_y, left_y, right_y), axis=0) # scale by the half the widest width of the spade scale_factor = (x_bounds[1] - x_shift) / 16 + base_x = base_x * scale_factor + x_shift + base_y = base_y * scale_factor + y_shift - x = x * scale_factor + x_shift - y = y * scale_factor + y_shift - - x = np.concatenate((heart_stack[:, 0], x), axis=0) - y = np.concatenate((heart_y, y), axis=0) + # combine the base and the upside-down heart + x = np.concatenate((heart_points[:, 0], base_x), axis=0) + y = np.concatenate((heart_points[:, 1], base_y), axis=0) super().__init__(*np.stack([x, y], axis=1)) From 7dd191d7ea05c0167c302cab6afb65bf9a27a909 Mon Sep 17 00:00:00 2001 From: Stefanie Molin <24376333+stefmolin@users.noreply.github.com> Date: Sat, 5 Oct 2024 16:00:21 -0400 Subject: [PATCH 3/4] Add test for spade shape --- tests/shapes/test_points.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/shapes/test_points.py b/tests/shapes/test_points.py index f156f836..b5275314 100644 --- a/tests/shapes/test_points.py +++ b/tests/shapes/test_points.py @@ -159,3 +159,17 @@ class TestClub(PointsModuleTestBase): [(20, 50), 5.941155], [(10, 80), 10.288055], ] + + +class TestSpade(PointsModuleTestBase): + """Test the Spade class.""" + + shape_name = 'spade' + distance_test_cases = [ + [(19.97189615, 75.43271708), 0], + [(23.75, 55), 0], + [(11.42685318, 59.11304904), 0], + [(20, 75), 0.2037185], + [(0, 0), 57.350348], + [(10, 80), 10.968080], + ] From 849b16ba2a6cff44b3217f7a4a809d92cd2872d9 Mon Sep 17 00:00:00 2001 From: Stefanie Molin <24376333+stefmolin@users.noreply.github.com> Date: Sat, 5 Oct 2024 16:15:53 -0400 Subject: [PATCH 4/4] Use int instead of float --- src/data_morph/shapes/points.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/data_morph/shapes/points.py b/src/data_morph/shapes/points.py index 0d5f7e59..d4013d9d 100644 --- a/src/data_morph/shapes/points.py +++ b/src/data_morph/shapes/points.py @@ -424,11 +424,11 @@ def __init__(self, dataset: Dataset) -> None: # left wing left_x = np.linspace(-6, 0, num=12) - left_y = 0.278 * np.power(left_x + 6.0, 2) - 16 + left_y = 0.278 * np.power(left_x + 6, 2) - 16 # right wing right_x = np.linspace(0, 6, num=12) - right_y = 0.278 * np.power(right_x - 6.0, 2) - 16 + right_y = 0.278 * np.power(right_x - 6, 2) - 16 # shift and scale the base and wing base_x = np.concatenate((line_x, left_x, right_x), axis=0)