Source code for data_morph.shapes.factory

"""Factory class for generating shape objects."""

from itertools import zip_longest

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.axes import Axes

from ..data.dataset import Dataset
from ..plotting.style import plot_with_custom_style
from . import circles, lines, points, polygons
from .bases.shape import Shape


[docs] class ShapeFactory: """ Factory for generating shape objects based on data. .. plot:: :caption: Target shapes currently available. from data_morph.data.loader import DataLoader from data_morph.shapes.factory import ShapeFactory dataset = DataLoader.load_dataset('panda') _ = ShapeFactory(dataset).plot_available_shapes() Parameters ---------- dataset : Dataset The starting dataset to morph into other shapes. """ _SHAPE_MAPPING: dict = { 'bullseye': circles.Bullseye, 'circle': circles.Circle, 'high_lines': lines.HighLines, 'h_lines': lines.HorizontalLines, 'slant_down': lines.SlantDownLines, 'slant_up': lines.SlantUpLines, 'v_lines': lines.VerticalLines, 'wide_lines': lines.WideLines, 'x': lines.XLines, 'dots': points.DotsGrid, 'down_parab': points.DownParabola, 'heart': points.Heart, 'left_parab': points.LeftParabola, 'scatter': points.Scatter, 'right_parab': points.RightParabola, 'up_parab': points.UpParabola, 'diamond': polygons.Diamond, 'rectangle': polygons.Rectangle, 'rings': circles.Rings, 'star': polygons.Star, } AVAILABLE_SHAPES: list[str] = sorted(_SHAPE_MAPPING.keys()) """list[str]: The list of available shapes, which can be visualized with :meth:`.plot_available_shapes`.""" def __init__(self, dataset: Dataset) -> None: self._dataset: Dataset = dataset
[docs] def generate_shape(self, shape: str, **kwargs) -> Shape: """ Generate the shape object based on the dataset. Parameters ---------- shape : str The desired shape. See :attr:`.AVAILABLE_SHAPES`. **kwargs Additional keyword arguments to pass down when creating the shape. Returns ------- Shape An shape object of the requested type. """ try: return self._SHAPE_MAPPING[shape](self._dataset, **kwargs) except KeyError as err: raise ValueError(f'No such shape as {shape}.') from err
[docs] @plot_with_custom_style def plot_available_shapes(self) -> Axes: """ Plot the available target shapes. Returns ------- matplotlib.axes.Axes The :class:`~matplotlib.axes.Axes` object containing the plot. See Also -------- AVAILABLE_SHAPES The list of available shapes. """ num_cols = 5 num_plots = len(self.AVAILABLE_SHAPES) num_rows = int(np.ceil(num_plots / num_cols)) fig, axs = plt.subplots( num_rows, num_cols, layout='constrained', figsize=(10, 2 * num_rows), ) fig.get_layout_engine().set(w_pad=0.2, h_pad=0.2) for shape, ax in zip_longest(self.AVAILABLE_SHAPES, axs.flatten()): if shape: ax.tick_params( axis='both', which='both', bottom=False, left=False, right=False, labelbottom=False, labelleft=False, ) shape_obj = self.generate_shape(shape) ax = shape_obj.plot(ax=ax).set( xlabel='', ylabel='', title=str(shape_obj) ) else: ax.remove() return axs