scikit-spatial 8.1.0__tar.gz → 9.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/HISTORY.rst +17 -1
  2. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/PKG-INFO +10 -2
  3. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/README.md +7 -0
  4. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/plotting.rst +7 -0
  5. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/requirements.txt +1 -1
  6. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/pyproject.toml +4 -2
  7. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/objects/_base_sphere.py +3 -1
  8. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/objects/circle.py +5 -5
  9. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/objects/cylinder.py +1 -2
  10. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/objects/line.py +7 -6
  11. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/objects/line_segment.py +6 -5
  12. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/objects/plane.py +1 -2
  13. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/objects/point.py +6 -5
  14. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/objects/points.py +7 -6
  15. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/objects/sphere.py +1 -2
  16. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/objects/triangle.py +2 -4
  17. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/objects/vector.py +4 -5
  18. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/plotting.py +12 -3
  19. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tox.ini +6 -1
  20. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/uv.lock +7 -3
  21. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/.coveragerc +0 -0
  22. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/.dockerignore +0 -0
  23. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/.github/workflows/main.yml +0 -0
  24. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/.gitignore +0 -0
  25. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/.pre-commit-config.yaml +0 -0
  26. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/.readthedocs.yml +0 -0
  27. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/AUTHORS.rst +0 -0
  28. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/CITATION.cff +0 -0
  29. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/CONTRIBUTING.rst +0 -0
  30. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/LICENSE +0 -0
  31. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/api_reference/skspatial.measurement.rst +0 -0
  32. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/api_reference/skspatial.objects.Circle.rst +0 -0
  33. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/api_reference/skspatial.objects.Cylinder.rst +0 -0
  34. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/api_reference/skspatial.objects.Line.rst +0 -0
  35. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/api_reference/skspatial.objects.LineSegment.rst +0 -0
  36. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/api_reference/skspatial.objects.Plane.rst +0 -0
  37. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/api_reference/skspatial.objects.Point.rst +0 -0
  38. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/api_reference/skspatial.objects.Points.rst +0 -0
  39. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/api_reference/skspatial.objects.Sphere.rst +0 -0
  40. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/api_reference/skspatial.objects.Triangle.rst +0 -0
  41. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/api_reference/skspatial.objects.Vector.rst +0 -0
  42. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/api_reference/skspatial.objects.rst +0 -0
  43. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/api_reference/skspatial.transformation.rst +0 -0
  44. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/api_reference/toc.rst +0 -0
  45. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/conf.py +0 -0
  46. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/images/logo.svg +0 -0
  47. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/index.rst +0 -0
  48. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/objects/circle.rst +0 -0
  49. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/objects/cylinder.rst +0 -0
  50. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/objects/line.rst +0 -0
  51. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/objects/line_segment.rst +0 -0
  52. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/objects/plane.rst +0 -0
  53. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/objects/point_vector.rst +0 -0
  54. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/objects/points.rst +0 -0
  55. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/objects/sphere.rst +0 -0
  56. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/objects/toc.rst +0 -0
  57. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/docs/source/objects/triangle.rst +0 -0
  58. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/README.txt +0 -0
  59. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/fitting/README.txt +0 -0
  60. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/fitting/plot_line_2d.py +0 -0
  61. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/fitting/plot_line_3d.py +0 -0
  62. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/fitting/plot_plane.py +0 -0
  63. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/intersection/README.txt +0 -0
  64. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/intersection/plot_circle_circle.py +0 -0
  65. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/intersection/plot_cylinder_line.py +0 -0
  66. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/intersection/plot_line_circle.py +0 -0
  67. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/intersection/plot_line_line_2d.py +0 -0
  68. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/intersection/plot_line_line_3d.py +0 -0
  69. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/intersection/plot_line_plane.py +0 -0
  70. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/intersection/plot_plane_plane.py +0 -0
  71. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/intersection/plot_sphere_line.py +0 -0
  72. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/projection/README.txt +0 -0
  73. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/projection/plot_line_plane.py +0 -0
  74. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/projection/plot_point_line.py +0 -0
  75. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/projection/plot_point_plane.py +0 -0
  76. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/projection/plot_vector_line.py +0 -0
  77. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/projection/plot_vector_plane.py +0 -0
  78. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/projection/plot_vector_vector.py +0 -0
  79. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/triangle/README.txt +0 -0
  80. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/triangle/plot_normal.py +0 -0
  81. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/examples/triangle/plot_orthocenter.py +0 -0
  82. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/images/logo.svg +0 -0
  83. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/mypy.ini +0 -0
  84. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/__init__.py +0 -0
  85. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/_functions.py +0 -0
  86. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/measurement.py +0 -0
  87. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/objects/__init__.py +0 -0
  88. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/objects/_base_array.py +0 -0
  89. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/objects/_base_line_plane.py +0 -0
  90. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/objects/_base_spatial.py +0 -0
  91. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/objects/_mixins.py +0 -0
  92. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/py.typed +0 -0
  93. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/transformation.py +0 -0
  94. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/src/skspatial/typing.py +0 -0
  95. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/__init__.py +0 -0
  96. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/__init__.py +0 -0
  97. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/objects/__init__.py +0 -0
  98. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/objects/test_all_objects.py +0 -0
  99. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/objects/test_base_array.py +0 -0
  100. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/objects/test_base_array_1d.py +0 -0
  101. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/objects/test_base_array_2d.py +0 -0
  102. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/objects/test_base_line_plane.py +0 -0
  103. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/objects/test_circle.py +0 -0
  104. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/objects/test_cylinder.py +0 -0
  105. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/objects/test_line.py +0 -0
  106. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/objects/test_line_plane.py +0 -0
  107. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/objects/test_line_segment.py +0 -0
  108. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/objects/test_plane.py +0 -0
  109. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/objects/test_point.py +0 -0
  110. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/objects/test_points.py +0 -0
  111. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/objects/test_sphere.py +0 -0
  112. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/objects/test_triangle.py +0 -0
  113. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/objects/test_vector.py +0 -0
  114. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/test_functions.py +0 -0
  115. {scikit_spatial-8.1.0 → scikit_spatial-9.0.1}/tests/unit/test_measurement.py +0 -0
@@ -2,12 +2,28 @@
2
2
  History
3
3
  =======
4
4
 
5
+ 9.0.1 (2025-04-16)
6
+ ------------------
7
+
8
+ Docs
9
+ ~~~~
10
+ - Include single quotes in command: `pip install 'scikit-spatial[plotting]'`
11
+
12
+
13
+ 9.0.0 (2025-04-16)
14
+ ------------------
15
+
16
+ Breaking Changes
17
+ ~~~~~~~~~~~~~~~~
18
+ - Make matplotlib an optional dependency. It can be installed by `pip install 'scikit-spatial[plotting]'`
19
+
20
+
5
21
  8.1.0 (2024-12-23)
6
22
  ------------------
7
23
 
8
24
  Features
9
25
  ~~~~~~~~
10
- - Add optiont to return error for line and plane of best fit.
26
+ - Add option to return error for line and plane of best fit.
11
27
 
12
28
 
13
29
  8.0.0 (2024-10-03)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scikit-spatial
3
- Version: 8.1.0
3
+ Version: 9.0.1
4
4
  Summary: Spatial objects and computations based on NumPy arrays.
5
5
  Project-URL: repository, https://github.com/ajhynes7/scikit-spatial
6
6
  Project-URL: documentation, https://scikit-spatial.readthedocs.io
@@ -20,11 +20,12 @@ Classifier: Programming Language :: Python :: 3.11
20
20
  Classifier: Programming Language :: Python :: 3.12
21
21
  Classifier: Topic :: Scientific/Engineering
22
22
  Requires-Python: >=3.8
23
- Requires-Dist: matplotlib>=3
24
23
  Requires-Dist: numpy>1.24; python_version >= '3.12'
25
24
  Requires-Dist: numpy>=1; python_version < '3.12'
26
25
  Requires-Dist: scipy>1.11; python_version >= '3.12'
27
26
  Requires-Dist: scipy>=1; python_version < '3.12'
27
+ Provides-Extra: plotting
28
+ Requires-Dist: matplotlib>=3; extra == 'plotting'
28
29
  Description-Content-Type: text/markdown
29
30
 
30
31
  ![](images/logo.svg)
@@ -179,6 +180,13 @@ $ conda install scikit-spatial -c conda-forge
179
180
 
180
181
  ```
181
182
 
183
+ The `matplotlib` dependency is optional. To enable plotting, you can install scikit-spatial with the extra `plotting`.
184
+
185
+ ```bash
186
+ $ pip install 'scikit-spatial[plotting]'
187
+
188
+ ```
189
+
182
190
  # Example Usage
183
191
 
184
192
  ## Measurement
@@ -150,6 +150,13 @@ $ conda install scikit-spatial -c conda-forge
150
150
 
151
151
  ```
152
152
 
153
+ The `matplotlib` dependency is optional. To enable plotting, you can install scikit-spatial with the extra `plotting`.
154
+
155
+ ```bash
156
+ $ pip install 'scikit-spatial[plotting]'
157
+
158
+ ```
159
+
153
160
  # Example Usage
154
161
 
155
162
  ## Measurement
@@ -6,6 +6,13 @@ Plotting
6
6
 
7
7
  This library uses ``matplotlib`` to enable plotting of all of its spatial objects. Each object has a ``plot_2d`` and/or ``plot_3d`` method. For example, a :class:`Point` object can be plotted in 2D or 3D, while a :class:`Sphere` object can only be plotted in 3D.
8
8
 
9
+ The ``matplotlib`` dependency is optional. To install it, you can install scikit-spatial with the extra `plotting`.
10
+
11
+ .. code-block:: console
12
+
13
+ $ pip install 'scikit-spatial[plotting]'
14
+
15
+
9
16
  The ``plot_2d`` methods require an instance of :class:`~matplotlib.axes.Axes` as the first argument, while the ``plot_3d`` methods require an instance of :class:`~mpl_toolkits.mplot3d.axes3d.Axes3D`. This allows for placing multiple spatial objects on the same plot, which is useful for visualizing computations such as projection or intersection.
10
17
 
11
18
  The methods also pass keyword arguments to ``matplotlib`` functions. For example, ``Point.plot_2d`` uses :meth:`~matplotlib.axes.Axes.scatter` under the hood, so any keyword arguments to :meth:`~matplotlib.axes.Axes.scatter` can also be input to the method. Some plotting methods have additional keyword arguments that are not passed to ``matplotlib``, such as ``Line.plot_2d``, which takes parameters ``t_1`` and ``t_2`` to determine the start and end points of the line.
@@ -1,6 +1,6 @@
1
1
  Sphinx==5.3.0
2
2
  numpydoc==1.5.0
3
- scikit-spatial==8.1.0
3
+ scikit-spatial[plotting]==9.0.1
4
4
  setuptools==70.0.0
5
5
  sphinx-bootstrap-theme==0.8.1
6
6
  sphinx-gallery==0.9.0
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "scikit-spatial"
7
- version = "8.1.0"
7
+ version = "9.0.1"
8
8
  description = "Spatial objects and computations based on NumPy arrays."
9
9
 
10
10
  license = { text = "BSD-3-Clause" }
@@ -31,13 +31,15 @@ classifiers = [
31
31
  requires-python = ">=3.8"
32
32
 
33
33
  dependencies = [
34
- "matplotlib>=3",
35
34
  "numpy>1.24; python_version >= '3.12'",
36
35
  "numpy>=1; python_version < '3.12'",
37
36
  "scipy>1.11; python_version >= '3.12'",
38
37
  "scipy>=1; python_version < '3.12'",
39
38
  ]
40
39
 
40
+ [project.optional-dependencies]
41
+ plotting = ["matplotlib>=3"]
42
+
41
43
  [project.urls]
42
44
  repository = "https://github.com/ajhynes7/scikit-spatial"
43
45
  documentation = "https://scikit-spatial.readthedocs.io"
@@ -1,5 +1,7 @@
1
1
  """Module for base class of Circle and Sphere."""
2
2
 
3
+ from typing import cast
4
+
3
5
  import numpy as np
4
6
 
5
7
  from skspatial._functions import _contains_point
@@ -85,4 +87,4 @@ class _BaseSphere(_BaseSpatial):
85
87
 
86
88
  vector_to_point = Vector.from_points(self.point, point)
87
89
 
88
- return self.point + self.radius * vector_to_point.unit()
90
+ return cast(Point, self.point + self.radius * vector_to_point.unit())
@@ -5,9 +5,7 @@ from __future__ import annotations
5
5
  import math
6
6
  from typing import Tuple, cast
7
7
 
8
- import matplotlib.pyplot as plt
9
8
  import numpy as np
10
- from matplotlib.axes import Axes
11
9
 
12
10
  from skspatial._functions import np_float
13
11
  from skspatial.objects._base_sphere import _BaseSphere
@@ -368,8 +366,8 @@ class Circle(_BaseSphere):
368
366
  point_2 = point_1 + line.direction.unit()
369
367
 
370
368
  # Translate the points on the line to mimic the circle being centered on the origin.
371
- point_translated_1: Point = point_1 - self.point
372
- point_translated_2: Point = point_2 - self.point
369
+ point_translated_1 = point_1 - self.point
370
+ point_translated_2 = point_2 - self.point
373
371
 
374
372
  x_1, y_1 = point_translated_1
375
373
  x_2, y_2 = point_translated_2
@@ -465,7 +463,7 @@ class Circle(_BaseSphere):
465
463
 
466
464
  return cls(center, radius)
467
465
 
468
- def plot_2d(self, ax_2d: Axes, **kwargs) -> None:
466
+ def plot_2d(self, ax_2d, **kwargs) -> None:
469
467
  """
470
468
  Plot the circle in 2D.
471
469
 
@@ -493,6 +491,8 @@ class Circle(_BaseSphere):
493
491
  >>> limits = plt.axis([-10, 10, -10, 10])
494
492
 
495
493
  """
494
+ import matplotlib.pyplot as plt
495
+
496
496
  circle = plt.Circle(tuple(self.point), self.radius, **kwargs)
497
497
 
498
498
  ax_2d.add_artist(circle)
@@ -7,7 +7,6 @@ from dataclasses import dataclass
7
7
  from typing import List, Optional, Tuple, cast
8
8
 
9
9
  import numpy as np
10
- from mpl_toolkits.mplot3d import Axes3D
11
10
  from scipy.optimize import minimize
12
11
 
13
12
  from skspatial._functions import _solve_quadratic
@@ -639,7 +638,7 @@ class Cylinder(_BaseSpatial, _ToPointsMixin):
639
638
 
640
639
  return cls(point_a, vector_ab, radius)
641
640
 
642
- def plot_3d(self, ax_3d: Axes3D, n_along_axis: int = 100, n_angles: int = 30, **kwargs) -> None:
641
+ def plot_3d(self, ax_3d, n_along_axis: int = 100, n_angles: int = 30, **kwargs) -> None:
643
642
  """
644
643
  Plot a 3D cylinder.
645
644
 
@@ -5,14 +5,11 @@ from __future__ import annotations
5
5
  from typing import Optional, cast
6
6
 
7
7
  import numpy as np
8
- from matplotlib.axes import Axes
9
- from mpl_toolkits.mplot3d import Axes3D
10
8
 
11
9
  from skspatial.objects._base_line_plane import _BaseLinePlane
12
10
  from skspatial.objects.point import Point
13
11
  from skspatial.objects.points import Points
14
12
  from skspatial.objects.vector import Vector
15
- from skspatial.plotting import _connect_points_2d, _connect_points_3d
16
13
  from skspatial.transformation import transform_coordinates
17
14
  from skspatial.typing import array_like
18
15
 
@@ -265,7 +262,7 @@ class Line(_BaseLinePlane):
265
262
  """
266
263
  vector_along_line = t * self.direction
267
264
 
268
- return self.point + vector_along_line
265
+ return cast(Point, self.point + vector_along_line)
269
266
 
270
267
  def project_point(self, point: array_like) -> Point:
271
268
  """
@@ -787,7 +784,7 @@ class Line(_BaseLinePlane):
787
784
 
788
785
  return column.flatten()
789
786
 
790
- def plot_2d(self, ax_2d: Axes, t_1: float = 0, t_2: float = 1, **kwargs) -> None:
787
+ def plot_2d(self, ax_2d, t_1: float = 0, t_2: float = 1, **kwargs) -> None:
791
788
  """
792
789
  Plot a 2D line.
793
790
 
@@ -821,12 +818,14 @@ class Line(_BaseLinePlane):
821
818
  >>> grid = ax.grid()
822
819
 
823
820
  """
821
+ from skspatial.plotting import _connect_points_2d
822
+
824
823
  point_1 = self.to_point(t_1)
825
824
  point_2 = self.to_point(t_2)
826
825
 
827
826
  _connect_points_2d(ax_2d, point_1, point_2, **kwargs)
828
827
 
829
- def plot_3d(self, ax_3d: Axes3D, t_1: float = 0, t_2: float = 1, **kwargs) -> None:
828
+ def plot_3d(self, ax_3d, t_1: float = 0, t_2: float = 1, **kwargs) -> None:
830
829
  """
831
830
  Plot a 3D line.
832
831
 
@@ -862,6 +861,8 @@ class Line(_BaseLinePlane):
862
861
  >>> line.point.plot_3d(ax, s=100)
863
862
 
864
863
  """
864
+ from skspatial.plotting import _connect_points_3d
865
+
865
866
  point_1 = self.to_point(t_1)
866
867
  point_2 = self.to_point(t_2)
867
868
 
@@ -5,14 +5,11 @@ from __future__ import annotations
5
5
  import math
6
6
 
7
7
  import numpy as np
8
- from matplotlib.axes import Axes
9
- from mpl_toolkits.mplot3d import Axes3D
10
8
 
11
9
  from skspatial.objects._base_spatial import _BaseSpatial
12
10
  from skspatial.objects.line import Line
13
11
  from skspatial.objects.point import Point
14
12
  from skspatial.objects.vector import Vector
15
- from skspatial.plotting import _connect_points_2d, _connect_points_3d
16
13
  from skspatial.typing import array_like
17
14
 
18
15
 
@@ -157,7 +154,7 @@ class LineSegment(_BaseSpatial):
157
154
 
158
155
  return point_intersection
159
156
 
160
- def plot_2d(self, ax_2d: Axes, **kwargs) -> None:
157
+ def plot_2d(self, ax_2d, **kwargs) -> None:
161
158
  """
162
159
  Plot a 2D line segment.
163
160
 
@@ -190,9 +187,11 @@ class LineSegment(_BaseSpatial):
190
187
  >>> grid = ax.grid()
191
188
 
192
189
  """
190
+ from skspatial.plotting import _connect_points_2d
191
+
193
192
  _connect_points_2d(ax_2d, self.point_a, self.point_b, **kwargs)
194
193
 
195
- def plot_3d(self, ax_3d: Axes3D, **kwargs) -> None:
194
+ def plot_3d(self, ax_3d, **kwargs) -> None:
196
195
  """
197
196
  Plot a 3D line segment.
198
197
 
@@ -226,4 +225,6 @@ class LineSegment(_BaseSpatial):
226
225
  >>> segment.plot_3d(ax, c='k')
227
226
 
228
227
  """
228
+ from skspatial.plotting import _connect_points_3d
229
+
229
230
  _connect_points_3d(ax_3d, self.point_a, self.point_b, **kwargs)
@@ -5,7 +5,6 @@ from __future__ import annotations
5
5
  from typing import Optional, Tuple, cast
6
6
 
7
7
  import numpy as np
8
- from mpl_toolkits.mplot3d import Axes3D
9
8
 
10
9
  from skspatial.objects._base_line_plane import _BaseLinePlane
11
10
  from skspatial.objects._mixins import _ToPointsMixin
@@ -853,7 +852,7 @@ class Plane(_BaseLinePlane, _ToPointsMixin):
853
852
 
854
853
  return X, Y, Z
855
854
 
856
- def plot_3d(self, ax_3d: Axes3D, lims_x: array_like = (-1, 1), lims_y: array_like = (-1, 1), **kwargs) -> None:
855
+ def plot_3d(self, ax_3d, lims_x: array_like = (-1, 1), lims_y: array_like = (-1, 1), **kwargs) -> None:
857
856
  """
858
857
  Plot a 3D plane.
859
858
 
@@ -1,12 +1,9 @@
1
1
  """Module for the Point class."""
2
2
 
3
3
  import numpy as np
4
- from matplotlib.axes import Axes
5
- from mpl_toolkits.mplot3d import Axes3D
6
4
 
7
5
  from skspatial.objects._base_array import _BaseArray1D
8
6
  from skspatial.objects.vector import Vector
9
- from skspatial.plotting import _scatter_2d, _scatter_3d
10
7
  from skspatial.typing import array_like
11
8
 
12
9
 
@@ -98,7 +95,7 @@ class Point(_BaseArray1D):
98
95
 
99
96
  return vector.norm()
100
97
 
101
- def plot_2d(self, ax_2d: Axes, **kwargs) -> None:
98
+ def plot_2d(self, ax_2d, **kwargs) -> None:
102
99
  """
103
100
  Plot the point on a 2D scatter plot.
104
101
 
@@ -122,9 +119,11 @@ class Point(_BaseArray1D):
122
119
  >>> Point([1, 2]).plot_2d(ax, c='k', s=100)
123
120
 
124
121
  """
122
+ from skspatial.plotting import _scatter_2d
123
+
125
124
  _scatter_2d(ax_2d, self.reshape(1, -1), **kwargs)
126
125
 
127
- def plot_3d(self, ax_3d: Axes3D, **kwargs) -> None:
126
+ def plot_3d(self, ax_3d, **kwargs) -> None:
128
127
  """
129
128
  Plot the point on a 3D scatter plot.
130
129
 
@@ -151,4 +150,6 @@ class Point(_BaseArray1D):
151
150
  >>> Point([1, 2, 3]).plot_3d(ax, c='k', s=100)
152
151
 
153
152
  """
153
+ from skspatial.plotting import _scatter_3d
154
+
154
155
  _scatter_3d(ax_3d, self.reshape(1, -1), **kwargs)
@@ -5,13 +5,10 @@ from __future__ import annotations
5
5
  from typing import cast
6
6
 
7
7
  import numpy as np
8
- from matplotlib.axes import Axes
9
- from mpl_toolkits.mplot3d import Axes3D
10
8
  from numpy.linalg import matrix_rank
11
9
 
12
10
  from skspatial.objects._base_array import _BaseArray2D
13
11
  from skspatial.objects.point import Point
14
- from skspatial.plotting import _scatter_2d, _scatter_3d
15
12
 
16
13
 
17
14
  class Points(_BaseArray2D):
@@ -149,7 +146,7 @@ class Points(_BaseArray2D):
149
146
 
150
147
  """
151
148
  centroid = self.centroid()
152
- points_centered: Points = self - centroid
149
+ points_centered = self - centroid
153
150
 
154
151
  if return_centroid:
155
152
  return points_centered, centroid
@@ -325,7 +322,7 @@ class Points(_BaseArray2D):
325
322
  """
326
323
  return bool(self.affine_rank(**kwargs) <= 2)
327
324
 
328
- def plot_2d(self, ax_2d: Axes, **kwargs) -> None:
325
+ def plot_2d(self, ax_2d, **kwargs) -> None:
329
326
  """
330
327
  Plot the points on a 2D scatter plot.
331
328
 
@@ -350,9 +347,11 @@ class Points(_BaseArray2D):
350
347
  >>> points.plot_2d(ax, c='k')
351
348
 
352
349
  """
350
+ from skspatial.plotting import _scatter_2d
351
+
353
352
  _scatter_2d(ax_2d, self, **kwargs)
354
353
 
355
- def plot_3d(self, ax_3d: Axes3D, **kwargs) -> None:
354
+ def plot_3d(self, ax_3d, **kwargs) -> None:
356
355
  """
357
356
  Plot the points on a 3D scatter plot.
358
357
 
@@ -380,4 +379,6 @@ class Points(_BaseArray2D):
380
379
  >>> points.plot_3d(ax, s=75, depthshade=False)
381
380
 
382
381
  """
382
+ from skspatial.plotting import _scatter_3d
383
+
383
384
  _scatter_3d(ax_3d, self, **kwargs)
@@ -6,7 +6,6 @@ import math
6
6
  from typing import Tuple
7
7
 
8
8
  import numpy as np
9
- from mpl_toolkits.mplot3d import Axes3D
10
9
 
11
10
  from skspatial._functions import np_float
12
11
  from skspatial.objects._base_sphere import _BaseSphere
@@ -301,7 +300,7 @@ class Sphere(_BaseSphere, _ToPointsMixin):
301
300
 
302
301
  return X, Y, Z
303
302
 
304
- def plot_3d(self, ax_3d: Axes3D, n_angles: int = 30, **kwargs) -> None:
303
+ def plot_3d(self, ax_3d, n_angles: int = 30, **kwargs) -> None:
305
304
  """
306
305
  Plot the sphere in 3D.
307
306
 
@@ -5,8 +5,6 @@ from itertools import combinations
5
5
  from typing import Sequence
6
6
 
7
7
  import numpy as np
8
- from matplotlib.axes import Axes
9
- from mpl_toolkits.mplot3d import Axes3D
10
8
 
11
9
  from skspatial._functions import np_float
12
10
  from skspatial.objects._base_spatial import _BaseSpatial
@@ -631,7 +629,7 @@ class Triangle(_BaseSpatial):
631
629
 
632
630
  return math.isclose(a**2 + b**2, c**2, **kwargs)
633
631
 
634
- def plot_2d(self, ax_2d: Axes, part: str = 'points', **kwargs: str) -> None:
632
+ def plot_2d(self, ax_2d, part: str = 'points', **kwargs: str) -> None:
635
633
  """
636
634
  Plot a triangle in 2D.
637
635
 
@@ -670,7 +668,7 @@ class Triangle(_BaseSpatial):
670
668
  for line in self.multiple('line', 'abc'):
671
669
  line.plot_2d(ax_2d, **kwargs)
672
670
 
673
- def plot_3d(self, ax_3d: Axes3D, part: str = 'points', **kwargs: str) -> None:
671
+ def plot_3d(self, ax_3d, part: str = 'points', **kwargs: str) -> None:
674
672
  """
675
673
  Plot a triangle in 3D.
676
674
 
@@ -6,12 +6,9 @@ import math
6
6
  from typing import cast
7
7
 
8
8
  import numpy as np
9
- from matplotlib.axes import Axes
10
- from mpl_toolkits.mplot3d import Axes3D
11
9
 
12
10
  from skspatial._functions import np_float
13
11
  from skspatial.objects._base_array import _BaseArray1D
14
- from skspatial.plotting import _connect_points_3d
15
12
  from skspatial.typing import array_like
16
13
 
17
14
 
@@ -759,7 +756,7 @@ class Vector(_BaseArray1D):
759
756
 
760
757
  return vector_different_direction
761
758
 
762
- def plot_2d(self, ax_2d: Axes, point: array_like = (0, 0), scalar: float = 1, **kwargs) -> None:
759
+ def plot_2d(self, ax_2d, point: array_like = (0, 0), scalar: float = 1, **kwargs) -> None:
763
760
  """
764
761
  Plot a 2D vector.
765
762
 
@@ -796,7 +793,7 @@ class Vector(_BaseArray1D):
796
793
 
797
794
  ax_2d.arrow(x, y, dx, dy, **kwargs)
798
795
 
799
- def plot_3d(self, ax_3d: Axes3D, point: array_like = (0, 0, 0), scalar: float = 1, **kwargs) -> None:
796
+ def plot_3d(self, ax_3d, point: array_like = (0, 0, 0), scalar: float = 1, **kwargs) -> None:
800
797
  """
801
798
  Plot a 3D vector.
802
799
 
@@ -830,6 +827,8 @@ class Vector(_BaseArray1D):
830
827
  >>> Vector([-1, 1, 1]).plot_3d(ax, point=(1, 2, 3), c='r')
831
828
 
832
829
  """
830
+ from skspatial.plotting import _connect_points_3d
831
+
833
832
  point_2 = np.array(point) + scalar * self
834
833
 
835
834
  _connect_points_3d(ax_3d, point, point_2, **kwargs)
@@ -2,10 +2,19 @@
2
2
 
3
3
  from typing import Callable, Tuple
4
4
 
5
- import matplotlib.pyplot as plt
6
5
  import numpy as np
7
- from matplotlib.axes import Axes
8
- from mpl_toolkits.mplot3d import Axes3D
6
+
7
+ try:
8
+ import matplotlib.pyplot as plt
9
+ from matplotlib.axes import Axes
10
+ from mpl_toolkits.mplot3d import Axes3D
11
+ except ImportError as error:
12
+ raise ImportError(
13
+ "Matplotlib is required for plotting.\n"
14
+ "Install scikit-spatial with plotting support: "
15
+ "pip install 'scikit-spatial[plotting]'",
16
+ ) from error
17
+
9
18
 
10
19
  from skspatial.typing import array_like
11
20
 
@@ -24,7 +24,8 @@ commands =
24
24
 
25
25
  [testenv:type]
26
26
  deps =
27
- mypy==1.11.2
27
+ matplotlib==3.10.1
28
+ mypy==1.15.0
28
29
  commands =
29
30
  mypy src/
30
31
 
@@ -33,12 +34,16 @@ commands =
33
34
  python -m doctest README.md
34
35
 
35
36
  [testenv:doctests]
37
+ deps =
38
+ pytest==8.3.3
39
+ matplotlib==3.10.1
36
40
  commands =
37
41
  pytest --doctest-modules src/
38
42
 
39
43
  [testenv:docs]
40
44
  deps =
41
45
  Sphinx==5.3.0
46
+ matplotlib==3.10.1
42
47
  numpydoc==1.5.0
43
48
  setuptools==69.0.3
44
49
  sphinx-bootstrap-theme==0.8.1
@@ -754,16 +754,20 @@ wheels = [
754
754
 
755
755
  [[package]]
756
756
  name = "scikit-spatial"
757
- version = "8.1.0"
757
+ version = "9.0.1"
758
758
  source = { editable = "." }
759
759
  dependencies = [
760
- { name = "matplotlib" },
761
760
  { name = "numpy", version = "1.24.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" },
762
761
  { name = "numpy", version = "1.26.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
763
762
  { name = "scipy", version = "1.10.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" },
764
763
  { name = "scipy", version = "1.14.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
765
764
  ]
766
765
 
766
+ [package.optional-dependencies]
767
+ plotting = [
768
+ { name = "matplotlib" },
769
+ ]
770
+
767
771
  [package.dev-dependencies]
768
772
  dev = [
769
773
  { name = "mypy" },
@@ -774,7 +778,7 @@ dev = [
774
778
 
775
779
  [package.metadata]
776
780
  requires-dist = [
777
- { name = "matplotlib", specifier = ">=3" },
781
+ { name = "matplotlib", marker = "extra == 'plotting'", specifier = ">=3" },
778
782
  { name = "numpy", marker = "python_full_version < '3.12'", specifier = ">=1" },
779
783
  { name = "numpy", marker = "python_full_version >= '3.12'", specifier = ">1.24" },
780
784
  { name = "scipy", marker = "python_full_version < '3.12'", specifier = ">=1" },
File without changes
File without changes