![](images/logo.svg)
[![image](https://img.shields.io/pypi/v/scikit-spatial.svg)](https://pypi.python.org/pypi/scikit-spatial)
[![image](https://anaconda.org/conda-forge/scikit-spatial/badges/version.svg)](https://anaconda.org/conda-forge/scikit-spatial)
[![image](https://img.shields.io/pypi/pyversions/scikit-spatial.svg)](https://pypi.python.org/pypi/scikit-spatial)
[![image](https://github.com/ajhynes7/scikit-spatial/actions/workflows/main.yml/badge.svg)](https://github.com/ajhynes7/scikit-spatial/actions/workflows/main.yml)
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/ajhynes7/scikit-spatial/master.svg)](https://results.pre-commit.ci/latest/github/ajhynes7/scikit-spatial/master)
[![Documentation Status](https://readthedocs.org/projects/scikit-spatial/badge/?version=latest)](https://scikit-spatial.readthedocs.io/en/latest/?badge=latest)
[![image](https://codecov.io/gh/ajhynes7/scikit-spatial/branch/master/graph/badge.svg)](https://codecov.io/gh/ajhynes7/scikit-spatial)
# Introduction
This package provides spatial objects based on NumPy arrays, as well as
computations using these objects. The package includes computations for
2D, 3D, and higher-dimensional space.
The following spatial objects are provided:
- Point
- Points
- Vector
- Line
- LineSegment
- Plane
- Circle
- Sphere
- Triangle
- Cylinder
Most of the computations fall into the following categories:
- Measurement
- Comparison
- Projection
- Intersection
- Fitting
- Transformation
All spatial objects are equipped with plotting methods based on
`matplotlib`. Both 2D and 3D plotting are supported. Spatial
computations can be easily visualized by plotting multiple objects at
once.
## Why this instead of `scipy.spatial` or `sympy.geometry`?
This package has little to no overlap with the functionality of
`scipy.spatial`. It can be viewed as an object-oriented extension.
While similar spatial objects and computations exist in the
`sympy.geometry` module, `scikit-spatial` is based on NumPy rather than
symbolic math. The primary objects of `scikit-spatial` (`Point`,
`Points`, and `Vector`) are actually subclasses of the NumPy _ndarray_.
This gives them all the regular functionality of the _ndarray_, plus
additional methods from this package.
```py
>>> from skspatial.objects import Vector
>>> vector = Vector([2, 0, 0])
```
Behaviour inherited from NumPy:
```py
>>> vector.size
3
>>> vector.mean().round(3)
np.float64(0.667)
```
Additional methods from `scikit-spatial`:
```py
>>> vector.norm()
np.float64(2.0)
>>> vector.unit()
Vector([1., 0., 0.])
```
Because `Point` and `Vector` are both subclasses of `ndarray`, a `Vector` can be added to a `Point`. This produces a new `Point`.
```py
>>> from skspatial.objects import Point
>>> Point([1, 2]) + Vector([3, 4])
Point([4, 6])
```
`Point` and `Vector` are based on a 1D NumPy array, and `Points` is
based on a 2D NumPy array, where each row represents a point in space.
The `Line` and `Plane` objects have `Point` and `Vector` objects as
attributes.
Note that most methods inherited from NumPy return a regular NumPy object,
instead of the spatial object class.
```py
>>> vector.sum()
np.int64(2)
```
This is to avoid getting a spatial object with a forbidden shape, like a
zero dimension `Vector`. Trying to convert this back to a `Vector`
causes an exception.
```py
>>> Vector(vector.sum())
Traceback (most recent call last):
ValueError: The array must be 1D.
```
Because the computations of `scikit-spatial` are also based on NumPy,
keyword arguments can be passed to NumPy functions. For example, a
tolerance can be specified while testing for collinearity. The `tol`
keyword is passed to `numpy.linalg.matrix_rank`.
```py
>>> from skspatial.objects import Points
>>> points = Points([[1, 2, 3], [4, 5, 6], [7, 8, 8]])
>>> points.are_collinear()
False
>>> points.are_collinear(tol=1)
True
```
# Installation
The package can be installed with pip.
```bash
$ pip install scikit-spatial
```
It can also be installed with conda.
```bash
$ conda install scikit-spatial -c conda-forge
```
# Example Usage
## Measurement
Measure the cosine similarity between two vectors.
```py
>>> from skspatial.objects import Vector
>>> Vector([1, 0]).cosine_similarity([1, 1]).round(3)
np.float64(0.707)
```
## Comparison
Check if multiple points are collinear.
```py
>>> from skspatial.objects import Points
>>> points = Points([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
>>> points.are_collinear()
True
```
## Projection
Project a point onto a line.
```py
>>> from skspatial.objects import Line
>>> line = Line(point=[0, 0, 0], direction=[1, 1, 0])
>>> line.project_point([5, 6, 7])
Point([5.5, 5.5, 0. ])
```
## Intersection
Find the intersection of two planes.
```py
>>> from skspatial.objects import Plane
>>> plane_a = Plane(point=[0, 0, 0], normal=[0, 0, 1])
>>> plane_b = Plane(point=[5, 16, -94], normal=[1, 0, 0])
>>> plane_a.intersect_plane(plane_b)
Line(point=Point([5., 0., 0.]), direction=Vector([0, 1, 0]))
```
An error is raised if the computation is undefined.
```py
>>> plane_b = Plane(point=[0, 0, 1], normal=[0, 0, 1])
>>> plane_a.intersect_plane(plane_b)
Traceback (most recent call last):
ValueError: The planes must not be parallel.
```
## Fitting
Find the plane of best fit for multiple points.
```py
>>> points = [[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0]]
>>> Plane.best_fit(points)
Plane(point=Point([0.5, 0.5, 0. ]), normal=Vector([0., 0., 1.]))
```
## Transformation
Transform multiple points to 1D coordinates along a line.
```py
>>> line = Line(point=[0, 0, 0], direction=[1, 2, 0])
>>> points = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> line.transform_points(points).round(3)
array([ 2.236, 6.261, 10.286])
```
# Acknowledgment
This package was created with [Cookiecutter](https://github.com/audreyr/cookiecutter) and the [audreyr/cookiecutter-pypackage](https://github.com/audreyr/cookiecutter-pypackage) project template.
Raw data
{
"_id": null,
"home_page": null,
"name": "scikit-spatial",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "NumPy, matplotlib, visualization, spatial, linear algebra",
"author": null,
"author_email": "Andrew Hynes <andrewjhynes@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/e6/71/ec54f8d45e2aa2614d1b10255a6c7ed2e38fc4ae2948ab1ffecec1d4de4e/scikit_spatial-8.0.0.tar.gz",
"platform": null,
"description": "![](images/logo.svg)\n\n[![image](https://img.shields.io/pypi/v/scikit-spatial.svg)](https://pypi.python.org/pypi/scikit-spatial)\n[![image](https://anaconda.org/conda-forge/scikit-spatial/badges/version.svg)](https://anaconda.org/conda-forge/scikit-spatial)\n[![image](https://img.shields.io/pypi/pyversions/scikit-spatial.svg)](https://pypi.python.org/pypi/scikit-spatial)\n[![image](https://github.com/ajhynes7/scikit-spatial/actions/workflows/main.yml/badge.svg)](https://github.com/ajhynes7/scikit-spatial/actions/workflows/main.yml)\n[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/ajhynes7/scikit-spatial/master.svg)](https://results.pre-commit.ci/latest/github/ajhynes7/scikit-spatial/master)\n[![Documentation Status](https://readthedocs.org/projects/scikit-spatial/badge/?version=latest)](https://scikit-spatial.readthedocs.io/en/latest/?badge=latest)\n[![image](https://codecov.io/gh/ajhynes7/scikit-spatial/branch/master/graph/badge.svg)](https://codecov.io/gh/ajhynes7/scikit-spatial)\n\n# Introduction\n\nThis package provides spatial objects based on NumPy arrays, as well as\ncomputations using these objects. The package includes computations for\n2D, 3D, and higher-dimensional space.\n\nThe following spatial objects are provided:\n\n- Point\n- Points\n- Vector\n- Line\n- LineSegment\n- Plane\n- Circle\n- Sphere\n- Triangle\n- Cylinder\n\nMost of the computations fall into the following categories:\n\n- Measurement\n- Comparison\n- Projection\n- Intersection\n- Fitting\n- Transformation\n\nAll spatial objects are equipped with plotting methods based on\n`matplotlib`. Both 2D and 3D plotting are supported. Spatial\ncomputations can be easily visualized by plotting multiple objects at\nonce.\n\n## Why this instead of `scipy.spatial` or `sympy.geometry`?\n\nThis package has little to no overlap with the functionality of\n`scipy.spatial`. It can be viewed as an object-oriented extension.\n\nWhile similar spatial objects and computations exist in the\n`sympy.geometry` module, `scikit-spatial` is based on NumPy rather than\nsymbolic math. The primary objects of `scikit-spatial` (`Point`,\n`Points`, and `Vector`) are actually subclasses of the NumPy _ndarray_.\nThis gives them all the regular functionality of the _ndarray_, plus\nadditional methods from this package.\n\n```py\n>>> from skspatial.objects import Vector\n\n>>> vector = Vector([2, 0, 0])\n\n```\n\nBehaviour inherited from NumPy:\n\n```py\n>>> vector.size\n3\n\n>>> vector.mean().round(3)\nnp.float64(0.667)\n\n```\n\nAdditional methods from `scikit-spatial`:\n\n```py\n>>> vector.norm()\nnp.float64(2.0)\n\n>>> vector.unit()\nVector([1., 0., 0.])\n\n```\n\nBecause `Point` and `Vector` are both subclasses of `ndarray`, a `Vector` can be added to a `Point`. This produces a new `Point`.\n\n```py\n>>> from skspatial.objects import Point\n\n>>> Point([1, 2]) + Vector([3, 4])\nPoint([4, 6])\n\n```\n\n`Point` and `Vector` are based on a 1D NumPy array, and `Points` is\nbased on a 2D NumPy array, where each row represents a point in space.\nThe `Line` and `Plane` objects have `Point` and `Vector` objects as\nattributes.\n\nNote that most methods inherited from NumPy return a regular NumPy object,\ninstead of the spatial object class.\n\n```py\n>>> vector.sum()\nnp.int64(2)\n\n```\n\nThis is to avoid getting a spatial object with a forbidden shape, like a\nzero dimension `Vector`. Trying to convert this back to a `Vector`\ncauses an exception.\n\n```py\n>>> Vector(vector.sum())\nTraceback (most recent call last):\nValueError: The array must be 1D.\n\n```\n\nBecause the computations of `scikit-spatial` are also based on NumPy,\nkeyword arguments can be passed to NumPy functions. For example, a\ntolerance can be specified while testing for collinearity. The `tol`\nkeyword is passed to `numpy.linalg.matrix_rank`.\n\n```py\n>>> from skspatial.objects import Points\n\n>>> points = Points([[1, 2, 3], [4, 5, 6], [7, 8, 8]])\n\n>>> points.are_collinear()\nFalse\n\n>>> points.are_collinear(tol=1)\nTrue\n\n```\n\n# Installation\n\nThe package can be installed with pip.\n\n```bash\n$ pip install scikit-spatial\n\n```\n\nIt can also be installed with conda.\n\n```bash\n$ conda install scikit-spatial -c conda-forge\n\n```\n\n# Example Usage\n\n## Measurement\n\nMeasure the cosine similarity between two vectors.\n\n```py\n>>> from skspatial.objects import Vector\n\n>>> Vector([1, 0]).cosine_similarity([1, 1]).round(3)\nnp.float64(0.707)\n\n```\n\n## Comparison\n\nCheck if multiple points are collinear.\n\n```py\n>>> from skspatial.objects import Points\n\n>>> points = Points([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])\n\n>>> points.are_collinear()\nTrue\n\n```\n\n## Projection\n\nProject a point onto a line.\n\n```py\n>>> from skspatial.objects import Line\n\n>>> line = Line(point=[0, 0, 0], direction=[1, 1, 0])\n\n>>> line.project_point([5, 6, 7])\nPoint([5.5, 5.5, 0. ])\n\n```\n\n## Intersection\n\nFind the intersection of two planes.\n\n```py\n>>> from skspatial.objects import Plane\n\n>>> plane_a = Plane(point=[0, 0, 0], normal=[0, 0, 1])\n>>> plane_b = Plane(point=[5, 16, -94], normal=[1, 0, 0])\n\n>>> plane_a.intersect_plane(plane_b)\nLine(point=Point([5., 0., 0.]), direction=Vector([0, 1, 0]))\n\n```\n\nAn error is raised if the computation is undefined.\n\n```py\n>>> plane_b = Plane(point=[0, 0, 1], normal=[0, 0, 1])\n\n>>> plane_a.intersect_plane(plane_b)\nTraceback (most recent call last):\nValueError: The planes must not be parallel.\n\n```\n\n## Fitting\n\nFind the plane of best fit for multiple points.\n\n```py\n>>> points = [[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0]]\n\n>>> Plane.best_fit(points)\nPlane(point=Point([0.5, 0.5, 0. ]), normal=Vector([0., 0., 1.]))\n\n```\n\n## Transformation\n\nTransform multiple points to 1D coordinates along a line.\n\n```py\n>>> line = Line(point=[0, 0, 0], direction=[1, 2, 0])\n>>> points = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]\n\n>>> line.transform_points(points).round(3)\narray([ 2.236, 6.261, 10.286])\n\n```\n\n# Acknowledgment\n\nThis package was created with [Cookiecutter](https://github.com/audreyr/cookiecutter) and the [audreyr/cookiecutter-pypackage](https://github.com/audreyr/cookiecutter-pypackage) project template.\n",
"bugtrack_url": null,
"license": "BSD-3-Clause",
"summary": "Spatial objects and computations based on NumPy arrays.",
"version": "8.0.0",
"project_urls": {
"documentation": "https://scikit-spatial.readthedocs.io",
"repository": "https://github.com/ajhynes7/scikit-spatial"
},
"split_keywords": [
"numpy",
" matplotlib",
" visualization",
" spatial",
" linear algebra"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "e0185010a659f2b7fdb123d43116fa388af7d32498e36572a24fb0c95b63b971",
"md5": "c1edaf559619710daab045bfc7ee3c60",
"sha256": "226c5aa4742a94b71a1db11c7f0bda619cae462651095d95fe214b46f1e919a4"
},
"downloads": -1,
"filename": "scikit_spatial-8.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "c1edaf559619710daab045bfc7ee3c60",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 49754,
"upload_time": "2024-10-04T01:00:56",
"upload_time_iso_8601": "2024-10-04T01:00:56.814865Z",
"url": "https://files.pythonhosted.org/packages/e0/18/5010a659f2b7fdb123d43116fa388af7d32498e36572a24fb0c95b63b971/scikit_spatial-8.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "e671ec54f8d45e2aa2614d1b10255a6c7ed2e38fc4ae2948ab1ffecec1d4de4e",
"md5": "46b796aad3376480b2193cd090861209",
"sha256": "a51609797794fdb0ce33a946a65e2653d5f1276e60265957a6a83b8cd33432cd"
},
"downloads": -1,
"filename": "scikit_spatial-8.0.0.tar.gz",
"has_sig": false,
"md5_digest": "46b796aad3376480b2193cd090861209",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 36385,
"upload_time": "2024-10-04T01:00:58",
"upload_time_iso_8601": "2024-10-04T01:00:58.516611Z",
"url": "https://files.pythonhosted.org/packages/e6/71/ec54f8d45e2aa2614d1b10255a6c7ed2e38fc4ae2948ab1ffecec1d4de4e/scikit_spatial-8.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-04 01:00:58",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "ajhynes7",
"github_project": "scikit-spatial",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"tox": true,
"lcname": "scikit-spatial"
}