magpylib package#

Copyright (c) 2026 Michael Ortner. All rights reserved.

magpylib: Python package for computation of magnetic fields of magnets, currents and moments.

class magpylib.Collection(*children, position=(0, 0, 0), orientation=None, override_parent=False, style=None, **kwargs)#

Bases: BaseGeo, BaseCollection, BaseVolume, BaseDipoleMoment

Group multiple children in a collection for common manipulation.

Children can be sources (magnets, currents, misc), sensors, and other collections.

Collections span a local reference frame. All children are moved with that reference frame when an operation (e.g. move, rotate, setter, …) is applied to the collection.

Collections can be used as source, observer, and target input for magnetic field and force computation. For the computation, a collection that contains sources/targets functions like a single source/target. When the collection contains sensors it functions like a list of all its sensors.

Parameters:
  • *children (Source | Sensor | Collection) – Sources, sensors, or collections that should be added to this collection.

  • position (array-like, shape (3,) or (p, 3), default (0, 0, 0)) – Object position(s) in global coordinates in units (m). position and orientation attributes define the object path.

  • orientation (Rotation | None, default None) – Object orientation(s) in global coordinates as a scipy Rotation. Rotation can have length 1 or p. None generates a unit-rotation.

  • override_parent (bool, default False) – If False thrown an error when an attempt is made to add an object that has already a parent to a Collection. If True, allow adding the object and override the objects parent attribute thus removing it from its previous collection.

  • style (dict | None, default None) – Object style inputs must be in dictionary form, e.g. {'color': 'red'} or using style underscore magic, e.g. style_color='red'.

Variables:
  • position (ndarray, shape (3,) or (p, 3)) – Same as constructor parameter position.

  • orientation (Rotation) – Same as constructor parameter orientation.

  • children (list) – Ordered list of children in the collection top level.

  • children_all (list) – Read-only. Ordered list of children in the collection including nested collections.

  • parent (Collection | None) – Parent collection of the object.

  • sensors (list) – Ordered list of sensor objects in the collection top level.

  • sensors_all (list) – Read-only. Ordered list of sensor objects in the collection including nested collections.

  • sources (list) – Ordered list of source objects in the collection top level.

  • sources_all (list) – Read-only. Ordered list of source objects in the collection including nested collections.

  • collections (list) – Ordered list of collection objects in the collection top level.

  • collections_all (list) – Read-only. Ordered list of collection objects in the collection including nested collections.

  • centroid (ndarray, shape (3,) or (p, 3)) – Read-only. Collection centroid in units (m) computed as the volume-weighted average of all child centroids. Can be a path.

  • volume (float) – Read-only. Total Collection volume (m³) of all magnets. Overlapping objects may lead to double counting.

  • dipole_moment (ndarray, shape (3,)) – Read-only. Total Collection dipole moment (A·m²) computed from the sum of all child dipole moments.

  • style (dict) – Style dictionary defining the visual properties of the collection objects.

Examples

Collections function as groups of multiple Magpylib objects. In this example we create a collection with two sources and move the whole collection:

>>> import numpy as np
>>> import magpylib as magpy
>>> src1 = magpy.magnet.Sphere(position=(2, 0, 0), diameter=1, polarization=(0.1, 0.2, 0.3))
>>> src2 = magpy.current.Circle(position=(-2, 0, 0), diameter=1, current=1)
>>> col = magpy.Collection(src1, src2)
>>> col.move((0, 0, 2))
Collection(id=...)
>>> print(src1.position)
[2. 0. 2.]
>>> print(src2.position)
[-2.  0.  2.]
>>> print(col.position)
[0. 0. 2.]

We can still directly access individual objects by name and by index:

>>> src1.move((2, 0, 0))
Sphere(id=...)
>>> col[1].move((-2, 0, 0))
Circle(id=...)
>>> print(src1.position)
[4. 0. 2.]
>>> print(src2.position)
[-4.  0.  2.]
>>> print(col.position)
[0. 0. 2.]

The field can be computed at position (0, 0, 0) as if the collection was a single source:

>>> B = col.getB((0, 0, 0))
>>> print(B)
[ 2.32922681e-04 -9.31694991e-05 -3.44484717e-10]

We add a sensor at position (0, 0, 0) to the collection:

>>> sens = magpy.Sensor()
>>> col.add(sens)
Collection(id=...)
>>> print(col.children)
[Sphere(id=...), Circle(id=...), Sensor(id=...)]

and can compute the field of the sources in the collection seen by the sensor with a single command:

>>> B = col.getB()
>>> with np.printoptions(precision=3):
...    print(B)
[ 2.329e-04 -9.317e-05 -3.445e-10]
add(*children, override_parent=False)#

Add sources, sensors or collections to the collection.

Parameters:
  • *children (Source | Sensor | Collection) – Add arbitrary sources, sensors or other collections to this collection.

  • override_parent (bool, default False) – If False, do not accept objects as children that already have parents. If True automatically remove such objects from previous parent collection.

Returns:

Self (allows chaining).

Return type:

Self

Examples

In this example we add a sensor object to a collection:

>>> import magpylib as magpy
>>> x1 = magpy.Sensor(style_label='x1')
>>> coll = magpy.Collection(x1, style_label='coll')
>>> coll.describe(format='label')
coll
└── x1
>>> x2 = magpy.Sensor(style_label='x2')
>>> coll.add(x2)
Collection(id=...)
>>> coll.describe(format='label')
coll
├── x1
└── x2
copy(**kwargs)#

Return deep copy with optional modifications.

Parameters:

**kwargs – Attribute overrides applied to the copy (e.g. position=(1, 2, 3)).

Returns:

Deep-copied object (same concrete subclass as original).

Return type:

Self

Examples

Create a Sensor object and copy to an another position:

>>> import magpylib as magpy
>>> sens1 = magpy.Sensor(style_label='sens1')
>>> sens2 = sens1.copy(position=(2, 6, 10), style_label='sens2')
>>> print(f'Instance {sens1.style.label} with position {sens1.position}.')
Instance sens1 with position [0. 0. 0.].
>>> print(f'Instance {sens2.style.label} with position {sens2.position}.')
Instance sens2 with position [ 2.  6. 10.].
describe(format='type+label+id', max_elems=10, return_string=False)#

Return or print a tree view of the collection.

Parameters:
  • format (str, default 'type+label+id') – Object description in tree view. Can be any combination of 'type', 'label' and 'id' and 'properties'.

  • max_elems (int, default 10) – If number of children at any level is higher than max_elems, elements are replaced by counters.

  • return_string (bool, default False) – If False print description with stdout, if True return as string.

Returns:

Tree view string if return_string=True, else None.

Return type:

str | None

getB(*inputs, sumup=False, squeeze=True, pixel_agg=None, output='ndarray', in_out='auto')#

Return B-field (T) at o observers generated by s sources.

SI units are used for all inputs and outputs.

Parameters:
  • *inputs (Source | Sensor | array-like, shape (o1, o2, ..., 3)) – Can be observers if the collection contains sources. In this case the collection behaves like a single source. Can be sources if the collection contains sensors. In this case the collection behaves like a list of all its sensors.

  • sumup (bool, default False) – If True, sum the fields from all sources when the collection is used as observer input. If False, keep the source axis.

  • squeeze (bool, default True) – If True squeeze singleton axes (e.g. a single source or a single sensor).

  • pixel_agg (str | None, default None) – Name of a NumPy aggregation function (e.g. 'mean', 'min') applied over the pixel axis of each sensor. Allows mixing sensors with different pixel shapes.

  • output ({'ndarray', 'dataframe'}, default 'ndarray') – Output container type. ‘dataframe’ returns a pandas DataFrame.

  • in_out ({'auto', 'inside', 'outside'}, default 'auto') – Assumption about observer locations relative to magnet bodies. 'auto' detects per observer (safest, slower). 'inside' treats all inside (faster). 'outside' treats all outside (faster).

Returns:

B-field (T) with squeezed shape (s, p, o, o1, o2, …, 3) where s is the number of sources when the collection functions as observer, p is the path length, and o is the number of observers with pixel shape (o1, o2, …) when the collection functions as source.

Return type:

ndarray | DataFrame

Examples

In this example we create a collection from two sources and two sensors:

>>> import numpy as np
>>> import magpylib as magpy
>>> # Create Collection with two sensors and two magnets
>>> src1 = magpy.magnet.Sphere(polarization=(0, 0, 1), diameter=1)
>>> src2 = src1.copy()
>>> sens1 = magpy.Sensor(position=(0, 0, 0.6))
>>> sens2 = sens1.copy()
>>> col = src1 + src2 + sens1 + sens2
>>> # The following computations all give the same result
>>> B = col.getB()
>>> B = magpy.getB(col, col)
>>> B = magpy.getB(col, [sens1, sens2])
>>> B = magpy.getB([src1, src2], col)
>>> B = magpy.getB([src1, src2], [sens1, sens2])
>>> with np.printoptions(precision=3):
...     print(B)
[[[0.    0.    0.386]
  [0.    0.    0.386]]

 [[0.    0.    0.386]
  [0.    0.    0.386]]]
getH(*inputs, sumup=False, squeeze=True, pixel_agg=None, output='ndarray', in_out='auto')#

Return H-field (A/m) at o observers generated by s sources.

SI units are used for all inputs and outputs.

Parameters:
  • *inputs (Source | Sensor | array-like, shape (o1, o2, ..., 3)) – Can be observers if the collection contains sources. In this case the collection behaves like a single source. Can be sources if the collection contains sensors. In this case the collection behaves like a list of all its sensors.

  • sumup (bool, default False) – If True, sum the fields from all sources when the collection is used as observer input. If False, keep the source axis.

  • squeeze (bool, default True) – If True squeeze singleton axes (e.g. a single source or a single sensor).

  • pixel_agg (str | None, default None) – Name of a NumPy aggregation function (e.g. 'mean', 'min') applied over the pixel axis of each sensor. Allows mixing sensors with different pixel shapes.

  • output ({'ndarray', 'dataframe'}, default 'ndarray') – Output container type. ‘dataframe’ returns a pandas DataFrame.

  • in_out ({'auto', 'inside', 'outside'}, default 'auto') – Assumption about observer locations relative to magnet bodies. 'auto' detects per observer (safest, slower). 'inside' treats all inside (faster). 'outside' treats all outside (faster).

Returns:

H-field (A/m) with squeezed shape (s, p, o, o1, o2, …, 3) where s is the number of sources when the collection functions as observer, p is the path length, and o is the number of observers with pixel shape (o1, o2, …) when the collection functions as source.

Return type:

ndarray | DataFrame

Examples

In this example we create a collection from two sources and two sensors:

>>> import numpy as np
>>> import magpylib as magpy
>>> # Create Collection with two sensors and two magnets
>>> src1 = magpy.magnet.Sphere(polarization=(0, 0, 1.0), diameter=1)
>>> src2 = src1.copy()
>>> sens1 = magpy.Sensor(position=(0, 0, 1))
>>> sens2 = sens1.copy()
>>> col = src1 + src2 + sens1 + sens2
>>> # The following computations all give the same result
>>> H = col.getH()
>>> H = magpy.getH(col, col)
>>> H = magpy.getH(col, [sens1, sens2])
>>> H = magpy.getH([src1, src2], col)
>>> H = magpy.getH([src1, src2], [sens1, sens2])
>>> with np.printoptions(precision=3):
...    print(H)
[[[    0.       0.   66314.56]
  [    0.       0.   66314.56]]

 [[    0.       0.   66314.56]
  [    0.       0.   66314.56]]]
getJ(*inputs, sumup=False, squeeze=True, pixel_agg=None, output='ndarray', in_out='auto')#

Return magnetic polarization (T) at o observers generated by s sources.

Parameters:
  • *inputs (Source | Sensor | array-like, shape (o1, o2, ..., 3)) – Can be observers if the collection contains sources. In this case the collection behaves like a single source. Can be sources if the collection contains sensors. In this case the collection behaves like a list of all its sensors.

  • sumup (bool, default False) – If True, sum the fields from all sources when the collection is used as observer input. If False, keep the source axis.

  • squeeze (bool, default True) – If True squeeze singleton axes (e.g. a single source or a single sensor).

  • pixel_agg (str | None, default None) – Name of a NumPy aggregation function (e.g. 'mean', 'min') applied over the pixel axis of each sensor. Allows mixing sensors with different pixel shapes.

  • output ({'ndarray', 'dataframe'}, default 'ndarray') – Output container type. ‘dataframe’ returns a pandas DataFrame.

  • in_out ({'auto', 'inside', 'outside'}, default 'auto') – Assumption about observer locations relative to magnet bodies. 'auto' detects per observer (safest, slower). 'inside' treats all inside (faster). 'outside' treats all outside (faster).

Returns:

Polarization (T) with squeezed shape (s, p, o, o1, o2, …, 3) where s is the number of sources when the collection functions as observer, p is the path length, and o is the number of observers with pixel shape (o1, o2, …) when the collection functions as source.

Return type:

ndarray | DataFrame

Examples

>>> import numpy as np
>>> import magpylib as magpy
>>> cube = magpy.magnet.Cuboid(
...     dimension=(10, 1, 1),
...     polarization=(1, 0, 0)
... ).rotate_from_angax(45, 'z')
>>> coll = magpy.Collection(cube)
>>> J = coll.getJ((3, 3, 0))
>>> with np.printoptions(precision=3):
...    print(J)
[0.707 0.707 0.   ]
getM(*inputs, sumup=False, squeeze=True, pixel_agg=None, output='ndarray', in_out='auto')#

Return magnetization (A/m) at o observers generated by s sources.

SI units are used for all inputs and outputs.

Parameters:
  • *inputs (Source | Sensor | array-like, shape (o1, o2, ..., 3)) – Can be observers if the collection contains sources. In this case the collection behaves like a single source. Can be sources if the collection contains sensors. In this case the collection behaves like a list of all its sensors.

  • sumup (bool, default False) – If True, sum the fields from all sources when the collection is used as observer input. If False, keep the source axis.

  • squeeze (bool, default True) – If True squeeze singleton axes (e.g. a single source or a single sensor).

  • pixel_agg (str | None, default None) – Name of a NumPy aggregation function (e.g. 'mean', 'min') applied over the pixel axis of each sensor. Allows mixing sensors with different pixel shapes.

  • output ({'ndarray', 'dataframe'}, default 'ndarray') – Output container type. ‘dataframe’ returns a pandas DataFrame.

  • in_out ({'auto', 'inside', 'outside'}, default 'auto') – Assumption about observer locations relative to magnet bodies. 'auto' detects per observer (safest, slower). 'inside' treats all inside (faster). 'outside' treats all outside (faster).

Returns:

Magnetization (A/m) with squeezed shape (s, p, o, o1, o2, …, 3) where s is the number of sources when the collection functions as observer, p is the path length, and o is the number of observers with pixel shape (o1, o2, …) when the collection functions as source.

Return type:

ndarray | DataFrame

Examples

>>> import numpy as np
>>> import magpylib as magpy
>>> cube = magpy.magnet.Cuboid(
...     dimension=(10, 1, 1),
...     polarization=(1, 0, 0)
... ).rotate_from_angax(45, 'z')
>>> coll = magpy.Collection(cube)
>>> M = coll.getM((3, 3, 0))
>>> with np.printoptions(precision=0):
...    print(M)
[562698. 562698.      0.]
move(displacement, start='auto')#

Translate position by scalar or vector displacement.

Parameters:
  • displacement (array-like, shape (3,) or (n, 3)) – Displacement vector in units (m). Scalar input applies one translation to the path starting at index start. Vector input extends/appends element-wise. See Notes.

  • start (int | str, default 'auto') – Starting index when applying operation. With 'auto' scalar input sets start=0 (modify whole path) and vector input sets start=len(path) (append). See Notes for details.

Returns:

Self (allows chaining).

Return type:

Self

Notes

A path refers jointly to the position and orientation of the object. Scalar input applies a single operation. It is applied to the whole object path, starting with path index start. Vector input means a sequence of operations. Vector input of length n applies the individual n operations to n path entries, starting with path index start. When an input extends beyond the path, the object path will be padded by its edge-entries before the operation is applied. By default (start='auto') the index is set to start=0 for scalar input corresponding to moving the entire path, and to start=len(object path) for vector input corresponding to appending to the existing path.

Examples

Scalar input (single displacement):

>>> import magpylib as magpy
>>> sens = magpy.Sensor(position=(1, 1, 1))
>>> print(sens.position)
[1. 1. 1.]
>>> sens.move((1, 1, 1))
Sensor(id=...)
>>> print(sens.position)
[2. 2. 2.]

Create len>1 object paths with vector input:

>>> sens.move([(1, 1, 1), (2, 2, 2), (3, 3, 3)])
Sensor(id=...)
>>> print(sens.position)
[[2. 2. 2.]
 [3. 3. 3.]
 [4. 4. 4.]
 [5. 5. 5.]]

Apply operations starting with a designated path index:

>>> sens.move((0, 0, 2), start=2)
Sensor(id=...)
>>> print(sens.position)
[[2. 2. 2.]
 [3. 3. 3.]
 [4. 4. 6.]
 [5. 5. 7.]]
remove(*children, recursive=True, errors='raise')#

Remove children from the collection tree.

Parameters:
  • *children (Source | Sensor | Collection) – Remove the given children from the collection.

  • recursive (bool, default True) – Remove children also when they are in child collections.

  • errors ({'raise', 'ignore'}, default 'raise') – Toggle error output when child is not found for removal.

Returns:

Self (allows chaining).

Return type:

Self

Examples

In this example we remove a child from a collection:

>>> import magpylib as magpy
>>> x1 = magpy.Sensor(style_label='x1')
>>> x2 = magpy.Sensor(style_label='x2')
>>> col = magpy.Collection(x1, x2, style_label='col')
>>> col.describe(format='label')
col
├── x1
└── x2
>>> col.remove(x1)
Collection(id=...)
>>> col.describe(format='label')
col
└── x2
reset_path()#

Reset path: set position to (0, 0, 0) and orientation to unit rotation.

Returns:

Self (for chaining).

Return type:

Self

Examples

>>> import magpylib as magpy
>>> obj = magpy.Sensor(position=(1, 2, 3))
>>> obj.rotate_from_angax(45, 'z')
Sensor...
>>> print(obj.position)
[1. 2. 3.]
>>> print(obj.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 45.]
>>> obj.reset_path()
Sensor(id=...)
>>> print(obj.position)
[0. 0. 0.]
>>> print(obj.orientation.as_euler('xyz', degrees=True))
[0. 0. 0.]
rotate(rotation: Rotation, anchor=None, start='auto')#

Rotate about an anchor.

Parameters:
  • rotation (Rotation | None) – Scalar or vector rotation in the form of a scipy Rotation object. None is interpreted as unit rotation.

  • anchor (None | array-like, shape (3,) or (n, 3), default None) – Anchor point(s) (m). None rotates about object position; for a child in a collection it implies compound rotation about the parent position.

  • start (int | str, default 'auto') – Starting index when applying operation. With 'auto' scalar input sets start=0 (modify whole path) and vector input sets start=len(path) (append). See Notes for details.

Returns:

Self (allows chaining).

Return type:

Self

Notes

A path refers jointly to the position and orientation of the object. Scalar input applies a single operation. It is applied to the whole object path, starting with path index start. Vector input means a sequence of operations. Vector input of length n applies the individual n operations to n path entries, starting with path index start. When an input extends beyond the path, the object path will be padded by its edge-entries before the operation is applied. By default (start='auto') the index is set to start=0 for scalar input corresponding to moving the entire path, and to start=len(object path) for vector input corresponding to appending to the existing path.

Examples

Rotate an object about the origin:

>>> from scipy.spatial.transform import Rotation as R
>>> import magpylib as magpy
>>> sens = magpy.Sensor(position=(1, 0, 0))
>>> sens.rotate(R.from_euler('z', 45, degrees=True), anchor=0)
Sensor(id=...)
>>> print(sens.position)
[0.70710678 0.70710678 0.        ]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 45.]

Rotate the object about itself:

>>> sens.rotate(R.from_euler('z', 45, degrees=True))
Sensor(id=...)
>>> print(sens.position)
[0.70710678 0.70710678 0.        ]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 90.]

Create a rotation path by rotating in several steps about an anchor:

>>> sens.rotate(R.from_euler('z', [[15], [30], [45]], degrees=True), anchor=(0, 0, 0))
Sensor(id=...)
>>> print(sens.position)
[[ 7.07106781e-01  7.07106781e-01  0.00000000e+00]
 [ 5.00000000e-01  8.66025404e-01  0.00000000e+00]
 [ 2.58819045e-01  9.65925826e-01  0.00000000e+00]
 [-2.22044605e-16  1.00000000e+00  0.00000000e+00]]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[[  0.   0.  90.]
 [  0.   0. 105.]
 [  0.   0. 120.]
 [  0.   0. 135.]]
rotate_from_angax(angle, axis, anchor=None, start='auto', degrees=True)#

Rotate with scipy Rotation input.

Parameters:
  • angle (float | array-like, shape (n,)) – Rotation angle or sequence of angles in degrees. See property degrees.

  • axis (str | array-like, shape (3,) or (n, 3)) – Rotation axis direction. Provide a vector or one of 'x', 'y', 'z'.

  • anchor (None | array-like, shape (3,) or (n, 3), default None) – Anchor point(s) (m). None rotates about object position; for a child in a collection it implies compound rotation about the parent position.

  • start (int | str, default 'auto') – Starting index when applying operation. With 'auto' scalar input sets start=0 (modify whole path) and vector input sets start=len(path) (append). See Notes for details.

  • degrees (bool, default True) – If True, interpret angle input in degrees, else radians.

Returns:

Self (allows chaining).

Return type:

Self

Notes

A path refers jointly to the position and orientation of the object. Scalar input applies a single operation. It is applied to the whole object path, starting with path index start. Vector input means a sequence of operations. Vector input of length n applies the individual n operations to n path entries, starting with path index start. When an input extends beyond the path, the object path will be padded by its edge-entries before the operation is applied. By default (start='auto') the index is set to start=0 for scalar input corresponding to moving the entire path, and to start=len(object path) for vector input corresponding to appending to the existing path.

Examples

Rotate an object about the origin:

>>> import magpylib as magpy
>>> sens = magpy.Sensor(position=(1, 0, 0))
>>> sens.rotate_from_angax(45, axis='z', anchor=0)
Sensor(id=...)
>>> print(sens.position)
[0.70710678 0.70710678 0.        ]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 45.]

Rotate the object about itself:

>>> sens.rotate_from_angax(45, axis=(0, 0, 1))
Sensor(id=...)
>>> print(sens.position)
[0.70710678 0.70710678 0.        ]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 90.]

Create a rotation path by rotating in several steps about an anchor:

>>> sens.rotate_from_angax((15, 30, 45), axis='z', anchor=(0, 0, 0))
Sensor(id=...)
>>> print(sens.position)
[[ 7.07106781e-01  7.07106781e-01  0.00000000e+00]
 [ 5.00000000e-01  8.66025404e-01  0.00000000e+00]
 [ 2.58819045e-01  9.65925826e-01  0.00000000e+00]
 [-2.22044605e-16  1.00000000e+00  0.00000000e+00]]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[[  0.   0.  90.]
 [  0.   0. 105.]
 [  0.   0. 120.]
 [  0.   0. 135.]]
rotate_from_euler(angle, seq, anchor=None, start='auto', degrees=True)#

Rotate with Euler angle sequence.

Parameters:
  • angle (float | array-like, shape (n,)) – Angles of rotation in units (deg) by default.

  • seq (str) – Specifies sequence of axes for rotations. Up to 3 characters belonging to the set {‘X’, ‘Y’, ‘Z’} for intrinsic rotations, or {‘x’, ‘y’, ‘z’} for extrinsic rotations. Extrinsic and intrinsic rotations cannot be mixed in one function call.

  • anchor (None | array-like, shape (3,) or (n, 3), default None) – Anchor point(s) (m). None rotates about object position; for a child in a collection it implies compound rotation about the parent position.

  • start (int | str, default 'auto') – Starting index when applying operation. With 'auto' scalar input sets start=0 (modify whole path) and vector input sets start=len(path) (append). See Notes for details.

  • degrees (bool, default True) – If True, interpret angle input in degrees, else radians.

Returns:

Self (allows chaining).

Return type:

Self

Notes

A path refers jointly to the position and orientation of the object. Scalar input applies a single operation. It is applied to the whole object path, starting with path index start. Vector input means a sequence of operations. Vector input of length n applies the individual n operations to n path entries, starting with path index start. When an input extends beyond the path, the object path will be padded by its edge-entries before the operation is applied. By default (start='auto') the index is set to start=0 for scalar input corresponding to moving the entire path, and to start=len(object path) for vector input corresponding to appending to the existing path.

Examples

Rotate an object about the origin:

>>> import magpylib as magpy
>>> sens = magpy.Sensor(position=(1, 0, 0))
>>> sens.rotate_from_euler(45, 'z', anchor=0)
Sensor...
>>> print(sens.position)
[0.70710678 0.70710678 0.        ]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 45.]

Rotate the object about itself:

>>> sens.rotate_from_euler(45, 'z')
Sensor(id=...)
>>> print(sens.position)
[0.70710678 0.70710678 0.        ]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 90.]

Create a rotation path by rotating in several steps about an anchor:

>>> sens.rotate_from_euler((15, 30, 45), 'z', anchor=(0, 0, 0))
Sensor(id=...)
>>> print(sens.position)
[[ 7.07106781e-01  7.07106781e-01  0.00000000e+00]
 [ 5.00000000e-01  8.66025404e-01  0.00000000e+00]
 [ 2.58819045e-01  9.65925826e-01  0.00000000e+00]
 [-2.22044605e-16  1.00000000e+00  0.00000000e+00]]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[[  0.   0.  90.]
 [  0.   0. 105.]
 [  0.   0. 120.]
 [  0.   0. 135.]]
rotate_from_matrix(matrix, anchor=None, start='auto')#

Rotate with rotation matrix/matrices.

Parameters:
  • matrix (array-like, shape (3, 3) or (n, 3, 3)) – Single rotation matrix or sequence.

  • anchor (None | array-like, shape (3,) or (n, 3), default None) – Anchor point(s) (m). None rotates about object position; for a child in a collection it implies compound rotation about the parent position.

  • start (int | str, default 'auto') – Starting index when applying operation. With 'auto' scalar input sets start=0 (modify whole path) and vector input sets start=len(path) (append). See Notes for details.

Returns:

Self (allows chaining).

Return type:

Self

Notes

A path refers jointly to the position and orientation of the object. Scalar input applies a single operation. It is applied to the whole object path, starting with path index start. Vector input means a sequence of operations. Vector input of length n applies the individual n operations to n path entries, starting with path index start. When an input extends beyond the path, the object path will be padded by its edge-entries before the operation is applied. By default (start='auto') the index is set to start=0 for scalar input corresponding to moving the entire path, and to start=len(object path) for vector input corresponding to appending to the existing path.

>>> import magpylib as magpy
>>> sens = magpy.Sensor(position=(1, 0, 0))
>>> sens.rotate_from_matrix([(0, -1, 0), (1, 0, 0), (0, 0, 1)], anchor=0)
Sensor(id=...)
>>> print(sens.position)
[0. 1. 0.]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 90.]

Rotate the object about itself:

>>> sens.rotate_from_matrix([(0, -1, 0), (1, 0, 0), (0, 0, 1)])
Sensor(id=...)
>>> print(sens.position)
[0. 1. 0.]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[  0.   0. 180.]
rotate_from_mrp(mrp, anchor=None, start='auto')#

Rotate with Modified Rodrigues Parameters (MRPs).

Parameters:
  • mrp (array-like, shape (3,) or (n, 3)) – Modified Rodrigues Parameters vector or sequence.

  • anchor (None | array-like, shape (3,) or (n, 3), default None) – Anchor point(s) (m). None rotates about object position; for a child in a collection it implies compound rotation about the parent position.

  • start (int | str, default 'auto') – Starting index when applying operation. With 'auto' scalar input sets start=0 (modify whole path) and vector input sets start=len(path) (append). See Notes for details.

Returns:

Self (for chaining).

Return type:

Self

Notes

A path refers jointly to the position and orientation of the object. Scalar input applies a single operation. It is applied to the whole object path, starting with path index start. Vector input means a sequence of operations. Vector input of length n applies the individual n operations to n path entries, starting with path index start. When an input extends beyond the path, the object path will be padded by its edge-entries before the operation is applied. By default (start='auto') the index is set to start=0 for scalar input corresponding to moving the entire path, and to start=len(object path) for vector input corresponding to appending to the existing path.

Examples

Rotate an object about the origin:

>>> import magpylib as magpy
>>> sens = magpy.Sensor(position=(1, 0, 0))
>>> sens.rotate_from_mrp((0, 0, 1), anchor=0)
Sensor(id=...)
>>> print(sens.position)
[-1.  0.  0.]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[  0.   0. 180.]

Rotate the object about itself:

>>> sens.rotate_from_matrix([(0, -1, 0), (1, 0, 0), (0, 0, 1)])
Sensor(id=...)
>>> print(sens.position)
[-1.  0.  0.]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[  0.   0. -90.]
rotate_from_quat(quat, anchor=None, start='auto')#

Rotate with quaternion(s).

Parameters:
  • quat (array-like, shape (4,) or (n, 4)) – Quaternion or quaternion sequence in (x, y, z, w) format.

  • anchor (None | array-like, shape (3,) or (n, 3), default None) – Anchor point(s) (m). None rotates about object position; for a child in a collection it implies compound rotation about the parent position.

  • start (int | str, default 'auto') – Starting index when applying operation. With 'auto' scalar input sets start=0 (modify whole path) and vector input sets start=len(path) (append). See Notes for details.

Returns:

Self (for chaining).

Return type:

Self

Notes

A path refers jointly to the position and orientation of the object. Scalar input applies a single operation. It is applied to the whole object path, starting with path index start. Vector input means a sequence of operations. Vector input of length n applies the individual n operations to n path entries, starting with path index start. When an input extends beyond the path, the object path will be padded by its edge-entries before the operation is applied. By default (start='auto') the index is set to start=0 for scalar input corresponding to moving the entire path, and to start=len(object path) for vector input corresponding to appending to the existing path.

Examples

Rotate an object about the origin:

>>> import magpylib as magpy
>>> sens = magpy.Sensor(position=(1, 0, 0))
>>> sens.rotate_from_quat((0, 0, 1, 1), anchor=0)
Sensor(id=...)
>>> print(sens.position)
[0. 1. 0.]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 90.]

Rotate the object about itself:

>>> sens.rotate_from_quat((0, 0, 1, 1))
Sensor(id=...)
>>> print(sens.position)
[0. 1. 0.]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[  0.   0. 180.]
rotate_from_rotvec(rotvec, anchor=None, start='auto', degrees=True)#

Rotate with rotation vector input.

Parameters:
  • rotvec (array-like, shape (3,) or (n, 3)) – Rotation vector or sequence. Direction gives axis, magnitude gives angle in radians.

  • anchor (None | array-like, shape (3,) or (n, 3), default None) – Anchor point(s) (m). None rotates about object position; for a child in a collection it implies compound rotation about the parent position.

  • start (int | str, default 'auto') – Starting index when applying operation. With 'auto' scalar input sets start=0 (modify whole path) and vector input sets start=len(path) (append). See Notes for details.

  • degrees (bool, default True) – If True, interpret angle input in degrees, else radians.

Returns:

Self (allows chaining).

Return type:

Self

Notes

A path refers jointly to the position and orientation of the object. Scalar input applies a single operation. It is applied to the whole object path, starting with path index start. Vector input means a sequence of operations. Vector input of length n applies the individual n operations to n path entries, starting with path index start. When an input extends beyond the path, the object path will be padded by its edge-entries before the operation is applied. By default (start='auto') the index is set to start=0 for scalar input corresponding to moving the entire path, and to start=len(object path) for vector input corresponding to appending to the existing path.

Examples

Rotate an object about the origin:

>>> import magpylib as magpy
>>> sens = magpy.Sensor(position=(1, 0, 0))
>>> sens.rotate_from_rotvec((0, 0, 45), anchor=0)
Sensor(id=...)
>>> print(sens.position)
[0.70710678 0.70710678 0.        ]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 45.]

Rotate the object about itself:

>>> sens.rotate_from_rotvec((0, 0, 45))
Sensor(id=...)
>>> print(sens.position)
[0.70710678 0.70710678 0.        ]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 90.]

Create a rotation path by rotating in several steps about an anchor:

>>> sens.rotate_from_rotvec([(0, 0, 15), (0, 0, 30), (0, 0, 45)], anchor=(0, 0, 0))
Sensor(id=...)
>>> print(sens.position)
[[ 7.07106781e-01  7.07106781e-01  0.00000000e+00]
 [ 5.00000000e-01  8.66025404e-01  0.00000000e+00]
 [ 2.58819045e-01  9.65925826e-01  0.00000000e+00]
 [-2.22044605e-16  1.00000000e+00  0.00000000e+00]]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[[  0.   0.  90.]
 [  0.   0. 105.]
 [  0.   0. 120.]
 [  0.   0. 135.]]
set_children_styles(arg=None, recursive=True, _validate=True, **kwargs)#

Set display style of all children in the collection.

Only matching properties will be applied.

Parameters:
  • arg (dict | str | None, default None) – Style arguments to be applied in the form of a style dictionary or style underscore magic input.

  • recursive (bool, default True) – Apply styles also to children of child collections.

Returns:

Self (allows chaining).

Return type:

Self

Examples

In this example we start by creating a collection from three sphere magnets:

>>> import magpylib as magpy
>>>
>>> col = magpy.Collection(
...     [
...         magpy.magnet.Sphere(position=(i, 0, 0), diameter=1, polarization=(0, 0, 0.1))
...         for i in range(3)
...     ]
... )
>>> # We apply styles using underscore magic for magnetization vector size and a style
>>> # dictionary for the color.
>>>
>>> col.set_children_styles(magnetization_size=0.5)
Collection(id=...)
>>> col.set_children_styles({'color': 'g'})
Collection(id=...)
>>>
>>> # Finally we create a separate sphere magnet and show both the collection
>>> # and the separate magnet with Matplotlib:
>>>
>>> src = magpy.magnet.Sphere(position=(3, 0, 0), diameter=1, polarization=(0, 0, 0.1))
>>> magpy.show(col, src) 
>>> # graphic output
show(*, backend=<default>, canvas=<default>, animation=<default>, zoom=<default>, markers=<default>, return_fig=<default>, canvas_update=<default>, row=<default>, col=<default>, output=<default>, sumup=<default>, pixel_agg=<default>, style=<default>, **kwargs)#

Display objects and paths graphically.

Global graphic styles can be set with kwargs as style dictionary or using style underscore magic.

Parameters:
  • *objects (Source | Sensor | Collection) – One or multiple Magpylib objects to be displayed.

  • backend ({'auto', 'matplotlib', 'plotly', 'pyvista'}, default 'auto') – With 'auto' the backend becomes 'plotly' inside a notebook when Plotly is installed, otherwise 'matplotlib'. If canvas is provided, its type determines the backend.

  • canvas (None | matplotlib.Figure | plotly.Figure | pyvista.Plotter, default None) – Existing canvas to draw on. If None, a new canvas is created and displayed.

  • animation (bool | float, default False) – If True and at least one object has a path, the path is animated. A positive float sets the total animation duration in seconds (Plotly only).

  • zoom (float, default 0.0) – 3D plot zoom level. 0 means tight bounds.

  • markers (array-like, shape (n, 3) | None, default None) – Global position markers shown as points.

  • return_fig (bool, default False) – If True, return the underlying figure object (Figure / FigureWidget / Plotter).

  • canvas_update (str | bool, default 'auto') – Layout update behaviour when using a provided canvas. With 'auto' applies internal layout only for newly created canvases. True forces update, False suppresses it.

  • row (int | None, default None) – Subplot row index.

  • col (int | None, default None) – Subplot column index.

  • output (str | tuple[str, ...], default 'model3d') – Plot output type. 'model3d' shows 3D geometry. Field plots are defined via component strings like 'Bx', 'Bxy', 'Hyz'. Multiple axes in a string imply vector norm combination (e.g., 'Bxy' => sqrt(Bx**2 + By**2)).

  • sumup (bool, default True) – Sum field contributions of sources.

  • pixel_agg (str, default 'mean') – NumPy reducer applied across sensor pixels (e.g., 'min', 'max', 'std').

  • style (dict | None, default None) – Global style overrides, e.g. {'color': 'red'} or via underscore magic (style_color='red'). Applied to matching objects.

Returns:

The created/updated figure object if return_fig=True; otherwise None.

Return type:

None | matplotlib.Figure | plotly.Figure | pyvista.Plotter

Examples

Display multiple objects, object paths, markers in 3D using Matplotlib or Plotly:

>>> import magpylib as magpy
>>> src = magpy.magnet.Sphere(polarization=(0, 0, 1), diameter=1)
>>> src.move([(0.1*x, 0, 0) for x in range(50)])
Sphere...
>>> src.rotate_from_angax(angle=[*range(0, 400, 10)], axis='z', anchor=0, start=11)
Sphere...
>>> ts = [-.4, 0, .4]
>>> sens = magpy.Sensor(position=(0, 0, 2), pixel=[(x, y, 0) for x in ts for y in ts])
>>> magpy.show(src, sens) 
>>> magpy.show(src, sens, backend='plotly') 
>>> # graphic output

Display output on your own canvas (here a Matplotlib 3d-axes):

>>> import matplotlib.pyplot as plt
>>> import magpylib as magpy
>>> my_axis = plt.axes(projection='3d')
>>> magnet = magpy.magnet.Cuboid(polarization=(1, 1, 1), dimension=(1, 2, 3))
>>> sens = magpy.Sensor(position=(0, 0, 3))
>>> magpy.show(magnet, sens, canvas=my_axis, zoom=1)
>>> plt.show() 
>>> # graphic output

Use sophisticated figure styling options accessible from defaults, as individual object styles or as global style arguments in display.

>>> import magpylib as magpy
>>> src1 = magpy.magnet.Sphere(position=[(0, 0, 0), (0, 0, 3)], diameter=1, polarization=(1, 1, 1))
>>> src2 = magpy.magnet.Sphere(
...     position=[(1, 0, 0), (1, 0, 3)],
...     diameter=1,
...     polarization=(1, 1, 1),
...     style_path_show=False
... )
>>> magpy.defaults.display.style.magnet.magnetization.size = 2
>>> src1.style.magnetization.size = 1
>>> magpy.show(src1, src2, style_color='r') 
>>> # graphic output

Use a context manager to jointly animate 3d and 2d subplots

>>> import magpylib as magpy
>>> import numpy as np
>>> import plotly.graph_objects as go
>>> path_len = 40
>>> sensor = magpy.Sensor()
>>> cyl1 = magpy.magnet.Cylinder(
...    polarization=(.1, 0, 0),
...    dimension=(1, 2),
...    position=(4, 0, 0),
...    style_label="Cylinder1",
... )
>>> sensor.move(np.linspace((0, 0, -3), (0, 0, 3), path_len), start=0)
Sensor(id=...)
>>> cyl1.rotate_from_angax(angle=np.linspace(0, 300, path_len), start=0, axis="z", anchor=0)
Cylinder(id=...)
>>> cyl2 = cyl1.copy().move((0, 0, 5))
>>> fig = go.Figure()
>>> with magpy.show_context(cyl1, cyl2, sensor, canvas=fig, backend="plotly", animation=True):
...    magpy.show(col=1, output="model3d")
...    magpy.show(col=2, output="Bxy", sumup=True)
...    magpy.show(col=3, output="Bz", sumup=False)
>>> fig.show() 
>>> # graphic output
property centroid#

Return centroid (m).

property children#

Ordered list of top level child objects.

property children_all#

Ordered list of all child objects in the collection tree.

property collections#

Ordered list of top level collection objects.

property collections_all#

Ordered list of all collection objects in the collection tree.

property dipole_moment#

Return dipole moment vector (A·m²).

get_trace = None#
property orientation#

Return object orientation.

None corresponds to unit rotation.

property parent#

Parent collection of the object.

property position#

Return object position in global coordinates (m).

property sensors#

Ordered list of top level sensor objects.

property sensors_all#

Ordered list of all sensor objects in the collection tree.

property sources#

Ordered list of top level source objects.

property sources_all#

Ordered list of all source objects in the collection tree.

property style#

Return object style as a BaseStyle instance.

property volume#

Return object volume (m³).

class magpylib.Sensor(position=(0, 0, 0), orientation=None, pixel=None, handedness='right', style=None, **kwargs)#

Bases: BaseGeo, BaseDisplayRepr

Magnetic field sensor.

Can be used as observers input for magnetic field computation.

When position=(0, 0, 0) and orientation=None the local object coordinates coincide with the global coordinate system.

SI units are used for all inputs and outputs.

Parameters:
  • position (array-like, shape (3,) or (p, 3), default (0, 0, 0)) – Object position(s) in global coordinates in units (m). position and orientation attributes define the object path.

  • orientation (None | Rotation, default None) – Object orientation(s) in global coordinates as a scipy Rotation. Rotation can have length 1 or p. None generates a unit-rotation.

  • pixel (None | array-like, shape (3,) or (o1, o2, ..., 3), default None) – Sensor pixel (= sensing element) positions in local object coordinates (rotate with object) in units (m).

  • handedness ({'right', 'left'}, default 'right') – Object local coordinate system handedness. If 'left', the x-axis is flipped.

  • style (None | dict, default None) – Style dictionary. Can also be provided via style underscore magic, e.g. style_color='red'.

Variables:
  • position (ndarray, shape (3,) or (p, 3)) – Same as constructor parameter position.

  • orientation (Rotation) – Same as constructor parameter orientation.

  • pixel (None | ndarray, shape (3,) or (o1, o2, ..., 3)) – Same as constructor parameter pixel.

  • handedness (str) – Same as constructor parameter handedness.

  • parent (Collection | None) – Parent collection of the object.

  • style (dict) – Style dictionary defining visual properties.

Examples

Sensor objects are observers for magnetic field computation. In this example we compute the B-field in units (T) as seen by the sensor in the center of a circular current loop:

>>> import numpy as np
>>> import magpylib as magpy
>>> sens = magpy.Sensor()
>>> loop = magpy.current.Circle(current=1, diameter=0.01)
>>> B = sens.getB(loop)
>>> with np.printoptions(precision=3):
...     print(B*1000)
[0.    0.    0.126]

We rotate the sensor by 45 degrees and compute the field again:

>>> sens.rotate_from_rotvec((45, 0, 0))
Sensor(id=...)
>>> B = sens.getB(loop)
>>> with np.printoptions(precision=3):
...     print(B)
[0.000e+00 8.886e-05 8.886e-05]

Finally, we set some sensor pixels and compute the field again:

>>> sens.pixel = ((0, 0, 0), (0.001, 0, 0), (0.002, 0, 0))
>>> B = sens.getB(loop)
>>> with np.printoptions(precision=3):
...     print(B)
[[0.000e+00 8.886e-05 8.886e-05]
 [0.000e+00 9.163e-05 9.163e-05]
 [0.000e+00 1.014e-04 1.014e-04]]
copy(**kwargs)#

Return deep copy with optional modifications.

Parameters:

**kwargs – Attribute overrides applied to the copy (e.g. position=(1, 2, 3)).

Returns:

Deep-copied object (same concrete subclass as original).

Return type:

Self

Examples

Create a Sensor object and copy to an another position:

>>> import magpylib as magpy
>>> sens1 = magpy.Sensor(style_label='sens1')
>>> sens2 = sens1.copy(position=(2, 6, 10), style_label='sens2')
>>> print(f'Instance {sens1.style.label} with position {sens1.position}.')
Instance sens1 with position [0. 0. 0.].
>>> print(f'Instance {sens2.style.label} with position {sens2.position}.')
Instance sens2 with position [ 2.  6. 10.].
describe(*, exclude=('style', 'field_func'), return_string=False)#

Return or print a formatted description of object properties.

Parameters:
  • exclude (str | Sequence[str], default ('style', 'field_func')) – Property names to omit from the description.

  • return_string (bool, default False) – If True return the description string; if False print it and return None.

Returns:

Description string if return_string=True else None.

Return type:

str | None

getB(*sources, sumup=False, squeeze=True, pixel_agg=None, output='ndarray', in_out='auto')#

Return B-field (T) from s sources as seen by the sensor.

SI units are used for all inputs and outputs.

Parameters:
  • *sources (Source | list) – Sources that generate the magnetic field. Can be a single source or a 1D list of s source objects.

  • sumup (bool, default False) – If True, sum the fields from all sources. If False, keep the source axis.

  • squeeze (bool, default True) – If True squeeze singleton axes (e.g. a single source or a single sensor).

  • pixel_agg (str | None, default None) – Name of a NumPy aggregation function (e.g. 'mean', 'min') applied over the pixel axis of each sensor. Allows mixing sensors with different pixel shapes.

  • output ({'ndarray', 'dataframe'}, default 'ndarray') – Output container type. 'dataframe' returns a pandas DataFrame.

  • in_out ({'auto', 'inside', 'outside'}, default 'auto') – Assumption about observer locations relative to magnet bodies. 'auto' detects per observer (safest, slower). 'inside' treats all inside (faster). 'outside' treats all outside (faster).

Returns:

B-field (T) with squeezed shape (s, p, 1, o1, o2, …, 3) where s is the number of sources, p is the path length, and o1, o2, … are sensor pixel dimensions.

Return type:

ndarray | DataFrame

Examples

Sensors are observers for magnetic field computation. In this example we compute the B-field in T as seen by the sensor in the center of a circular current loop:

>>> import numpy as np
>>> import magpylib as magpy
>>> sens = magpy.Sensor()
>>> loop = magpy.current.Circle(current=1, diameter=0.01)
>>> B = sens.getB(loop)
>>> with np.printoptions(precision=3):
...     print(B*1000)
[0.    0.    0.126]

Then we rotate the sensor by 45 degrees and compute the field again:

>>> sens.rotate_from_rotvec((45, 0, 0))
Sensor(id=...)
>>> B = sens.getB(loop)
>>> with np.printoptions(precision=3):
...     print(B)
[0.000e+00 8.886e-05 8.886e-05]

Finally we set some sensor pixels and compute the field again:

>>> sens.pixel = ((0, 0, 0), (0.001, 0, 0), (0.002, 0, 0))
>>> B = sens.getB(loop)
>>> with np.printoptions(precision=3):
...     print(B)
[[0.000e+00 8.886e-05 8.886e-05]
 [0.000e+00 9.163e-05 9.163e-05]
 [0.000e+00 1.014e-04 1.014e-04]]
getH(*sources, sumup=False, squeeze=True, pixel_agg=None, output='ndarray', in_out='auto')#

Return H-field (A/m) from s sources as seen by the sensor.

SI units are used for all inputs and outputs.

Parameters:
  • *sources (Source | list) – Sources that generate the magnetic field. Can be a single source or a 1D list of s source objects.

  • sumup (bool, default False) – If True, sum the fields from all sources. If False, keep the source axis.

  • squeeze (bool, default True) – If True squeeze singleton axes (e.g. a single source or a single sensor).

  • pixel_agg (str | None, default None) – Name of a NumPy aggregation function (e.g. 'mean', 'min') applied over the pixel axis of each sensor. Allows mixing sensors with different pixel shapes.

  • output ({'ndarray', 'dataframe'}, default 'ndarray') – Output container type. 'dataframe' returns a pandas DataFrame.

  • in_out ({'auto', 'inside', 'outside'}, default 'auto') – Assumption about observer locations relative to magnet bodies. 'auto' detects per observer (safest, slower). 'inside' treats all inside (faster). 'outside' treats all outside (faster).

Returns:

H-field (A/m) with squeezed shape (s, p, 1, o1, o2, …, 3) where s is the number of sources, p is the path length, and o1, o2, … are sensor pixel dimensions.

Return type:

ndarray | DataFrame

Examples

Sensors are observers for magnetic field computation. In this example we compute the B-field in T as seen by the sensor in the center of a circular current loop:

>>> import numpy as np
>>> import magpylib as magpy
>>> sens = magpy.Sensor()
>>> loop = magpy.current.Circle(current=1, diameter=0.01)
>>> H = sens.getH(loop)
>>> with np.printoptions(precision=3):
...     print(H)
[  0.   0. 100.]

Then we rotate the sensor by 45 degrees and compute the field again:

>>> sens.rotate_from_rotvec((45, 0, 0))
Sensor(id=...)
>>> H = sens.getH(loop)
>>> with np.printoptions(precision=3):
...     print(H)
[ 0.    70.711 70.711]

Finally we set some sensor pixels and compute the field again:

>>> sens.pixel = ((0, 0, 0), (0.001, 0, 0), (0.002, 0, 0))
>>> H = sens.getH(loop)
>>> with np.printoptions(precision=3):
...     print(H)
[[ 0.    70.711 70.711]
 [ 0.    72.915 72.915]
 [ 0.    80.704 80.704]]
getJ(*sources, sumup=False, squeeze=True, pixel_agg=None, output='ndarray', in_out='auto')#

Return magnetic polarization (T) from s sources as seen by the sensor.

SI units are used for all inputs and outputs.

Parameters:
  • *sources (Source | list) – Sources that generate the magnetic field. Can be a single source or a 1D list of s source objects.

  • sumup (bool, default False) – If True, sum the fields from all sources. If False, keep the source axis.

  • squeeze (bool, default True) – If True squeeze singleton axes (e.g. a single source or a single sensor).

  • pixel_agg (str | None, default None) – Name of a NumPy aggregation function (e.g. 'mean', 'min') applied over the pixel axis of each sensor. Allows mixing sensors with different pixel shapes.

  • output ({'ndarray', 'dataframe'}, default 'ndarray') – Output container type. 'dataframe' returns a pandas DataFrame.

  • in_out ({'auto', 'inside', 'outside'}, default 'auto') – Assumption about observer locations relative to magnet bodies. 'auto' detects per observer (safest, slower). 'inside' treats all inside (faster). 'outside' treats all outside (faster).

Returns:

Magnetic polarization (T) with squeezed shape (s, p, 1, o1, o2, …, 3) where s is the number of sources, p is the path length, and o1, o2, … are sensor pixel dimensions.

Return type:

ndarray | DataFrame

Examples

Test if there is polarization at the location of the sensor.

>>> import numpy as np
>>> import magpylib as magpy
>>> cube = magpy.magnet.Cuboid(
...     dimension=(10, 1, 1),
...     polarization=(1, 0, 0)
... )
>>> sens = magpy.Sensor()
>>> J = sens.getJ(cube)
>>> with np.printoptions(precision=0):
...    print(J)
[1. 0. 0.]
getM(*sources, sumup=False, squeeze=True, pixel_agg=None, output='ndarray', in_out='auto')#

Return magnetization (A/m) from s sources as seen by the sensor.

SI units are used for all inputs and outputs.

Parameters:
  • *sources (Source | list) – Sources that generate the magnetic field. Can be a single source or a 1D list of s source objects.

  • sumup (bool, default False) – If True, sum the fields from all sources. If False, keep the source axis.

  • squeeze (bool, default True) – If True squeeze singleton axes (e.g. a single source or a single sensor).

  • pixel_agg (str | None, default None) – Name of a NumPy aggregation function (e.g. 'mean', 'min') applied over the pixel axis of each sensor. Allows mixing sensors with different pixel shapes.

  • output ({'ndarray', 'dataframe'}, default 'ndarray') – Output container type. 'dataframe' returns a pandas DataFrame.

  • in_out ({'auto', 'inside', 'outside'}, default 'auto') – Assumption about observer locations relative to magnet bodies. 'auto' detects per observer (safest, slower). 'inside' treats all inside (faster). 'outside' treats all outside (faster).

Returns:

Magnetization (A/m) with squeezed shape (s, p, 1, o1, o2, …, 3) where s is the number of sources, p is the path length, and o1, o2, … are sensor pixel dimensions.

Return type:

ndarray | DataFrame

Examples

Test if there is magnetization at the location of the sensor.

>>> import numpy as np
>>> import magpylib as magpy
>>> cube = magpy.magnet.Cuboid(
...     dimension=(10, 1, 1),
...     polarization=(1, 0, 0)
... )
>>> sens = magpy.Sensor()
>>> M = sens.getM(cube)
>>> with np.printoptions(precision=0):
...    print(M)
[795775.      0.      0.]
get_trace(*, autosize, path_ind=None, field_values, **kwargs) dict[str, Any]#

Create the plotly mesh3d parameters for a Sensor object in a dictionary based on the provided arguments.

size_pixels: float, default=1

A positive number. Adjusts automatic display size of sensor pixels. When set to 0, pixels will be hidden, when greater than 0, pixels will occupy half the ratio of the minimum distance between any pixel of the same sensor, equal to size_pixel.

move(displacement, start='auto')#

Translate position by scalar or vector displacement.

Parameters:
  • displacement (array-like, shape (3,) or (n, 3)) – Displacement vector in units (m). Scalar input applies one translation to the path starting at index start. Vector input extends/appends element-wise. See Notes.

  • start (int | str, default 'auto') – Starting index when applying operation. With 'auto' scalar input sets start=0 (modify whole path) and vector input sets start=len(path) (append). See Notes for details.

Returns:

Self (allows chaining).

Return type:

Self

Notes

A path refers jointly to the position and orientation of the object. Scalar input applies a single operation. It is applied to the whole object path, starting with path index start. Vector input means a sequence of operations. Vector input of length n applies the individual n operations to n path entries, starting with path index start. When an input extends beyond the path, the object path will be padded by its edge-entries before the operation is applied. By default (start='auto') the index is set to start=0 for scalar input corresponding to moving the entire path, and to start=len(object path) for vector input corresponding to appending to the existing path.

Examples

Scalar input (single displacement):

>>> import magpylib as magpy
>>> sens = magpy.Sensor(position=(1, 1, 1))
>>> print(sens.position)
[1. 1. 1.]
>>> sens.move((1, 1, 1))
Sensor(id=...)
>>> print(sens.position)
[2. 2. 2.]

Create len>1 object paths with vector input:

>>> sens.move([(1, 1, 1), (2, 2, 2), (3, 3, 3)])
Sensor(id=...)
>>> print(sens.position)
[[2. 2. 2.]
 [3. 3. 3.]
 [4. 4. 4.]
 [5. 5. 5.]]

Apply operations starting with a designated path index:

>>> sens.move((0, 0, 2), start=2)
Sensor(id=...)
>>> print(sens.position)
[[2. 2. 2.]
 [3. 3. 3.]
 [4. 4. 6.]
 [5. 5. 7.]]
reset_path()#

Reset path: set position to (0, 0, 0) and orientation to unit rotation.

Returns:

Self (for chaining).

Return type:

Self

Examples

>>> import magpylib as magpy
>>> obj = magpy.Sensor(position=(1, 2, 3))
>>> obj.rotate_from_angax(45, 'z')
Sensor...
>>> print(obj.position)
[1. 2. 3.]
>>> print(obj.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 45.]
>>> obj.reset_path()
Sensor(id=...)
>>> print(obj.position)
[0. 0. 0.]
>>> print(obj.orientation.as_euler('xyz', degrees=True))
[0. 0. 0.]
rotate(rotation: Rotation, anchor=None, start='auto')#

Rotate about an anchor.

Parameters:
  • rotation (Rotation | None) – Scalar or vector rotation in the form of a scipy Rotation object. None is interpreted as unit rotation.

  • anchor (None | array-like, shape (3,) or (n, 3), default None) – Anchor point(s) (m). None rotates about object position; for a child in a collection it implies compound rotation about the parent position.

  • start (int | str, default 'auto') – Starting index when applying operation. With 'auto' scalar input sets start=0 (modify whole path) and vector input sets start=len(path) (append). See Notes for details.

Returns:

Self (allows chaining).

Return type:

Self

Notes

A path refers jointly to the position and orientation of the object. Scalar input applies a single operation. It is applied to the whole object path, starting with path index start. Vector input means a sequence of operations. Vector input of length n applies the individual n operations to n path entries, starting with path index start. When an input extends beyond the path, the object path will be padded by its edge-entries before the operation is applied. By default (start='auto') the index is set to start=0 for scalar input corresponding to moving the entire path, and to start=len(object path) for vector input corresponding to appending to the existing path.

Examples

Rotate an object about the origin:

>>> from scipy.spatial.transform import Rotation as R
>>> import magpylib as magpy
>>> sens = magpy.Sensor(position=(1, 0, 0))
>>> sens.rotate(R.from_euler('z', 45, degrees=True), anchor=0)
Sensor(id=...)
>>> print(sens.position)
[0.70710678 0.70710678 0.        ]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 45.]

Rotate the object about itself:

>>> sens.rotate(R.from_euler('z', 45, degrees=True))
Sensor(id=...)
>>> print(sens.position)
[0.70710678 0.70710678 0.        ]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 90.]

Create a rotation path by rotating in several steps about an anchor:

>>> sens.rotate(R.from_euler('z', [[15], [30], [45]], degrees=True), anchor=(0, 0, 0))
Sensor(id=...)
>>> print(sens.position)
[[ 7.07106781e-01  7.07106781e-01  0.00000000e+00]
 [ 5.00000000e-01  8.66025404e-01  0.00000000e+00]
 [ 2.58819045e-01  9.65925826e-01  0.00000000e+00]
 [-2.22044605e-16  1.00000000e+00  0.00000000e+00]]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[[  0.   0.  90.]
 [  0.   0. 105.]
 [  0.   0. 120.]
 [  0.   0. 135.]]
rotate_from_angax(angle, axis, anchor=None, start='auto', degrees=True)#

Rotate with scipy Rotation input.

Parameters:
  • angle (float | array-like, shape (n,)) – Rotation angle or sequence of angles in degrees. See property degrees.

  • axis (str | array-like, shape (3,) or (n, 3)) – Rotation axis direction. Provide a vector or one of 'x', 'y', 'z'.

  • anchor (None | array-like, shape (3,) or (n, 3), default None) – Anchor point(s) (m). None rotates about object position; for a child in a collection it implies compound rotation about the parent position.

  • start (int | str, default 'auto') – Starting index when applying operation. With 'auto' scalar input sets start=0 (modify whole path) and vector input sets start=len(path) (append). See Notes for details.

  • degrees (bool, default True) – If True, interpret angle input in degrees, else radians.

Returns:

Self (allows chaining).

Return type:

Self

Notes

A path refers jointly to the position and orientation of the object. Scalar input applies a single operation. It is applied to the whole object path, starting with path index start. Vector input means a sequence of operations. Vector input of length n applies the individual n operations to n path entries, starting with path index start. When an input extends beyond the path, the object path will be padded by its edge-entries before the operation is applied. By default (start='auto') the index is set to start=0 for scalar input corresponding to moving the entire path, and to start=len(object path) for vector input corresponding to appending to the existing path.

Examples

Rotate an object about the origin:

>>> import magpylib as magpy
>>> sens = magpy.Sensor(position=(1, 0, 0))
>>> sens.rotate_from_angax(45, axis='z', anchor=0)
Sensor(id=...)
>>> print(sens.position)
[0.70710678 0.70710678 0.        ]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 45.]

Rotate the object about itself:

>>> sens.rotate_from_angax(45, axis=(0, 0, 1))
Sensor(id=...)
>>> print(sens.position)
[0.70710678 0.70710678 0.        ]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 90.]

Create a rotation path by rotating in several steps about an anchor:

>>> sens.rotate_from_angax((15, 30, 45), axis='z', anchor=(0, 0, 0))
Sensor(id=...)
>>> print(sens.position)
[[ 7.07106781e-01  7.07106781e-01  0.00000000e+00]
 [ 5.00000000e-01  8.66025404e-01  0.00000000e+00]
 [ 2.58819045e-01  9.65925826e-01  0.00000000e+00]
 [-2.22044605e-16  1.00000000e+00  0.00000000e+00]]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[[  0.   0.  90.]
 [  0.   0. 105.]
 [  0.   0. 120.]
 [  0.   0. 135.]]
rotate_from_euler(angle, seq, anchor=None, start='auto', degrees=True)#

Rotate with Euler angle sequence.

Parameters:
  • angle (float | array-like, shape (n,)) – Angles of rotation in units (deg) by default.

  • seq (str) – Specifies sequence of axes for rotations. Up to 3 characters belonging to the set {‘X’, ‘Y’, ‘Z’} for intrinsic rotations, or {‘x’, ‘y’, ‘z’} for extrinsic rotations. Extrinsic and intrinsic rotations cannot be mixed in one function call.

  • anchor (None | array-like, shape (3,) or (n, 3), default None) – Anchor point(s) (m). None rotates about object position; for a child in a collection it implies compound rotation about the parent position.

  • start (int | str, default 'auto') – Starting index when applying operation. With 'auto' scalar input sets start=0 (modify whole path) and vector input sets start=len(path) (append). See Notes for details.

  • degrees (bool, default True) – If True, interpret angle input in degrees, else radians.

Returns:

Self (allows chaining).

Return type:

Self

Notes

A path refers jointly to the position and orientation of the object. Scalar input applies a single operation. It is applied to the whole object path, starting with path index start. Vector input means a sequence of operations. Vector input of length n applies the individual n operations to n path entries, starting with path index start. When an input extends beyond the path, the object path will be padded by its edge-entries before the operation is applied. By default (start='auto') the index is set to start=0 for scalar input corresponding to moving the entire path, and to start=len(object path) for vector input corresponding to appending to the existing path.

Examples

Rotate an object about the origin:

>>> import magpylib as magpy
>>> sens = magpy.Sensor(position=(1, 0, 0))
>>> sens.rotate_from_euler(45, 'z', anchor=0)
Sensor...
>>> print(sens.position)
[0.70710678 0.70710678 0.        ]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 45.]

Rotate the object about itself:

>>> sens.rotate_from_euler(45, 'z')
Sensor(id=...)
>>> print(sens.position)
[0.70710678 0.70710678 0.        ]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 90.]

Create a rotation path by rotating in several steps about an anchor:

>>> sens.rotate_from_euler((15, 30, 45), 'z', anchor=(0, 0, 0))
Sensor(id=...)
>>> print(sens.position)
[[ 7.07106781e-01  7.07106781e-01  0.00000000e+00]
 [ 5.00000000e-01  8.66025404e-01  0.00000000e+00]
 [ 2.58819045e-01  9.65925826e-01  0.00000000e+00]
 [-2.22044605e-16  1.00000000e+00  0.00000000e+00]]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[[  0.   0.  90.]
 [  0.   0. 105.]
 [  0.   0. 120.]
 [  0.   0. 135.]]
rotate_from_matrix(matrix, anchor=None, start='auto')#

Rotate with rotation matrix/matrices.

Parameters:
  • matrix (array-like, shape (3, 3) or (n, 3, 3)) – Single rotation matrix or sequence.

  • anchor (None | array-like, shape (3,) or (n, 3), default None) – Anchor point(s) (m). None rotates about object position; for a child in a collection it implies compound rotation about the parent position.

  • start (int | str, default 'auto') – Starting index when applying operation. With 'auto' scalar input sets start=0 (modify whole path) and vector input sets start=len(path) (append). See Notes for details.

Returns:

Self (allows chaining).

Return type:

Self

Notes

A path refers jointly to the position and orientation of the object. Scalar input applies a single operation. It is applied to the whole object path, starting with path index start. Vector input means a sequence of operations. Vector input of length n applies the individual n operations to n path entries, starting with path index start. When an input extends beyond the path, the object path will be padded by its edge-entries before the operation is applied. By default (start='auto') the index is set to start=0 for scalar input corresponding to moving the entire path, and to start=len(object path) for vector input corresponding to appending to the existing path.

>>> import magpylib as magpy
>>> sens = magpy.Sensor(position=(1, 0, 0))
>>> sens.rotate_from_matrix([(0, -1, 0), (1, 0, 0), (0, 0, 1)], anchor=0)
Sensor(id=...)
>>> print(sens.position)
[0. 1. 0.]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 90.]

Rotate the object about itself:

>>> sens.rotate_from_matrix([(0, -1, 0), (1, 0, 0), (0, 0, 1)])
Sensor(id=...)
>>> print(sens.position)
[0. 1. 0.]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[  0.   0. 180.]
rotate_from_mrp(mrp, anchor=None, start='auto')#

Rotate with Modified Rodrigues Parameters (MRPs).

Parameters:
  • mrp (array-like, shape (3,) or (n, 3)) – Modified Rodrigues Parameters vector or sequence.

  • anchor (None | array-like, shape (3,) or (n, 3), default None) – Anchor point(s) (m). None rotates about object position; for a child in a collection it implies compound rotation about the parent position.

  • start (int | str, default 'auto') – Starting index when applying operation. With 'auto' scalar input sets start=0 (modify whole path) and vector input sets start=len(path) (append). See Notes for details.

Returns:

Self (for chaining).

Return type:

Self

Notes

A path refers jointly to the position and orientation of the object. Scalar input applies a single operation. It is applied to the whole object path, starting with path index start. Vector input means a sequence of operations. Vector input of length n applies the individual n operations to n path entries, starting with path index start. When an input extends beyond the path, the object path will be padded by its edge-entries before the operation is applied. By default (start='auto') the index is set to start=0 for scalar input corresponding to moving the entire path, and to start=len(object path) for vector input corresponding to appending to the existing path.

Examples

Rotate an object about the origin:

>>> import magpylib as magpy
>>> sens = magpy.Sensor(position=(1, 0, 0))
>>> sens.rotate_from_mrp((0, 0, 1), anchor=0)
Sensor(id=...)
>>> print(sens.position)
[-1.  0.  0.]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[  0.   0. 180.]

Rotate the object about itself:

>>> sens.rotate_from_matrix([(0, -1, 0), (1, 0, 0), (0, 0, 1)])
Sensor(id=...)
>>> print(sens.position)
[-1.  0.  0.]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[  0.   0. -90.]
rotate_from_quat(quat, anchor=None, start='auto')#

Rotate with quaternion(s).

Parameters:
  • quat (array-like, shape (4,) or (n, 4)) – Quaternion or quaternion sequence in (x, y, z, w) format.

  • anchor (None | array-like, shape (3,) or (n, 3), default None) – Anchor point(s) (m). None rotates about object position; for a child in a collection it implies compound rotation about the parent position.

  • start (int | str, default 'auto') – Starting index when applying operation. With 'auto' scalar input sets start=0 (modify whole path) and vector input sets start=len(path) (append). See Notes for details.

Returns:

Self (for chaining).

Return type:

Self

Notes

A path refers jointly to the position and orientation of the object. Scalar input applies a single operation. It is applied to the whole object path, starting with path index start. Vector input means a sequence of operations. Vector input of length n applies the individual n operations to n path entries, starting with path index start. When an input extends beyond the path, the object path will be padded by its edge-entries before the operation is applied. By default (start='auto') the index is set to start=0 for scalar input corresponding to moving the entire path, and to start=len(object path) for vector input corresponding to appending to the existing path.

Examples

Rotate an object about the origin:

>>> import magpylib as magpy
>>> sens = magpy.Sensor(position=(1, 0, 0))
>>> sens.rotate_from_quat((0, 0, 1, 1), anchor=0)
Sensor(id=...)
>>> print(sens.position)
[0. 1. 0.]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 90.]

Rotate the object about itself:

>>> sens.rotate_from_quat((0, 0, 1, 1))
Sensor(id=...)
>>> print(sens.position)
[0. 1. 0.]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[  0.   0. 180.]
rotate_from_rotvec(rotvec, anchor=None, start='auto', degrees=True)#

Rotate with rotation vector input.

Parameters:
  • rotvec (array-like, shape (3,) or (n, 3)) – Rotation vector or sequence. Direction gives axis, magnitude gives angle in radians.

  • anchor (None | array-like, shape (3,) or (n, 3), default None) – Anchor point(s) (m). None rotates about object position; for a child in a collection it implies compound rotation about the parent position.

  • start (int | str, default 'auto') – Starting index when applying operation. With 'auto' scalar input sets start=0 (modify whole path) and vector input sets start=len(path) (append). See Notes for details.

  • degrees (bool, default True) – If True, interpret angle input in degrees, else radians.

Returns:

Self (allows chaining).

Return type:

Self

Notes

A path refers jointly to the position and orientation of the object. Scalar input applies a single operation. It is applied to the whole object path, starting with path index start. Vector input means a sequence of operations. Vector input of length n applies the individual n operations to n path entries, starting with path index start. When an input extends beyond the path, the object path will be padded by its edge-entries before the operation is applied. By default (start='auto') the index is set to start=0 for scalar input corresponding to moving the entire path, and to start=len(object path) for vector input corresponding to appending to the existing path.

Examples

Rotate an object about the origin:

>>> import magpylib as magpy
>>> sens = magpy.Sensor(position=(1, 0, 0))
>>> sens.rotate_from_rotvec((0, 0, 45), anchor=0)
Sensor(id=...)
>>> print(sens.position)
[0.70710678 0.70710678 0.        ]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 45.]

Rotate the object about itself:

>>> sens.rotate_from_rotvec((0, 0, 45))
Sensor(id=...)
>>> print(sens.position)
[0.70710678 0.70710678 0.        ]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[ 0.  0. 90.]

Create a rotation path by rotating in several steps about an anchor:

>>> sens.rotate_from_rotvec([(0, 0, 15), (0, 0, 30), (0, 0, 45)], anchor=(0, 0, 0))
Sensor(id=...)
>>> print(sens.position)
[[ 7.07106781e-01  7.07106781e-01  0.00000000e+00]
 [ 5.00000000e-01  8.66025404e-01  0.00000000e+00]
 [ 2.58819045e-01  9.65925826e-01  0.00000000e+00]
 [-2.22044605e-16  1.00000000e+00  0.00000000e+00]]
>>> print(sens.orientation.as_euler('xyz', degrees=True))
[[  0.   0.  90.]
 [  0.   0. 105.]
 [  0.   0. 120.]
 [  0.   0. 135.]]
show(*, backend=<default>, canvas=<default>, animation=<default>, zoom=<default>, markers=<default>, return_fig=<default>, canvas_update=<default>, row=<default>, col=<default>, output=<default>, sumup=<default>, pixel_agg=<default>, style=<default>, **kwargs)#

Display objects and paths graphically.

Global graphic styles can be set with kwargs as style dictionary or using style underscore magic.

Parameters:
  • *objects (Source | Sensor | Collection) – One or multiple Magpylib objects to be displayed.

  • backend ({'auto', 'matplotlib', 'plotly', 'pyvista'}, default 'auto') – With 'auto' the backend becomes 'plotly' inside a notebook when Plotly is installed, otherwise 'matplotlib'. If canvas is provided, its type determines the backend.

  • canvas (None | matplotlib.Figure | plotly.Figure | pyvista.Plotter, default None) – Existing canvas to draw on. If None, a new canvas is created and displayed.

  • animation (bool | float, default False) – If True and at least one object has a path, the path is animated. A positive float sets the total animation duration in seconds (Plotly only).

  • zoom (float, default 0.0) – 3D plot zoom level. 0 means tight bounds.

  • markers (array-like, shape (n, 3) | None, default None) – Global position markers shown as points.

  • return_fig (bool, default False) – If True, return the underlying figure object (Figure / FigureWidget / Plotter).

  • canvas_update (str | bool, default 'auto') – Layout update behaviour when using a provided canvas. With 'auto' applies internal layout only for newly created canvases. True forces update, False suppresses it.

  • row (int | None, default None) – Subplot row index.

  • col (int | None, default None) – Subplot column index.

  • output (str | tuple[str, ...], default 'model3d') – Plot output type. 'model3d' shows 3D geometry. Field plots are defined via component strings like 'Bx', 'Bxy', 'Hyz'. Multiple axes in a string imply vector norm combination (e.g., 'Bxy' => sqrt(Bx**2 + By**2)).

  • sumup (bool, default True) – Sum field contributions of sources.

  • pixel_agg (str, default 'mean') – NumPy reducer applied across sensor pixels (e.g., 'min', 'max', 'std').

  • style (dict | None, default None) – Global style overrides, e.g. {'color': 'red'} or via underscore magic (style_color='red'). Applied to matching objects.

Returns:

The created/updated figure object if return_fig=True; otherwise None.

Return type:

None | matplotlib.Figure | plotly.Figure | pyvista.Plotter

Examples

Display multiple objects, object paths, markers in 3D using Matplotlib or Plotly:

>>> import magpylib as magpy
>>> src = magpy.magnet.Sphere(polarization=(0, 0, 1), diameter=1)
>>> src.move([(0.1*x, 0, 0) for x in range(50)])
Sphere...
>>> src.rotate_from_angax(angle=[*range(0, 400, 10)], axis='z', anchor=0, start=11)
Sphere...
>>> ts = [-.4, 0, .4]
>>> sens = magpy.Sensor(position=(0, 0, 2), pixel=[(x, y, 0) for x in ts for y in ts])
>>> magpy.show(src, sens) 
>>> magpy.show(src, sens, backend='plotly') 
>>> # graphic output

Display output on your own canvas (here a Matplotlib 3d-axes):

>>> import matplotlib.pyplot as plt
>>> import magpylib as magpy
>>> my_axis = plt.axes(projection='3d')
>>> magnet = magpy.magnet.Cuboid(polarization=(1, 1, 1), dimension=(1, 2, 3))
>>> sens = magpy.Sensor(position=(0, 0, 3))
>>> magpy.show(magnet, sens, canvas=my_axis, zoom=1)
>>> plt.show() 
>>> # graphic output

Use sophisticated figure styling options accessible from defaults, as individual object styles or as global style arguments in display.

>>> import magpylib as magpy
>>> src1 = magpy.magnet.Sphere(position=[(0, 0, 0), (0, 0, 3)], diameter=1, polarization=(1, 1, 1))
>>> src2 = magpy.magnet.Sphere(
...     position=[(1, 0, 0), (1, 0, 3)],
...     diameter=1,
...     polarization=(1, 1, 1),
...     style_path_show=False
... )
>>> magpy.defaults.display.style.magnet.magnetization.size = 2
>>> src1.style.magnetization.size = 1
>>> magpy.show(src1, src2, style_color='r') 
>>> # graphic output

Use a context manager to jointly animate 3d and 2d subplots

>>> import magpylib as magpy
>>> import numpy as np
>>> import plotly.graph_objects as go
>>> path_len = 40
>>> sensor = magpy.Sensor()
>>> cyl1 = magpy.magnet.Cylinder(
...    polarization=(.1, 0, 0),
...    dimension=(1, 2),
...    position=(4, 0, 0),
...    style_label="Cylinder1",
... )
>>> sensor.move(np.linspace((0, 0, -3), (0, 0, 3), path_len), start=0)
Sensor(id=...)
>>> cyl1.rotate_from_angax(angle=np.linspace(0, 300, path_len), start=0, axis="z", anchor=0)
Cylinder(id=...)
>>> cyl2 = cyl1.copy().move((0, 0, 5))
>>> fig = go.Figure()
>>> with magpy.show_context(cyl1, cyl2, sensor, canvas=fig, backend="plotly", animation=True):
...    magpy.show(col=1, output="model3d")
...    magpy.show(col=2, output="Bxy", sumup=True)
...    magpy.show(col=3, output="Bz", sumup=False)
>>> fig.show() 
>>> # graphic output
property centroid#

Return centroid (m).

property handedness#

Object local coordinate system handedness.

property orientation#

Return object orientation.

None corresponds to unit rotation.

property parent#

Parent collection of the object.

property pixel#

Sensor pixel positions in local object coordinates in units (m).

property position#

Return object position in global coordinates (m).

property style#

Return object style as a BaseStyle instance.

magpylib.getB(sources=None, observers=None, sumup=False, squeeze=True, pixel_agg=None, output='ndarray', in_out='auto', **kwargs)#

Return B-field (T) of s sources at o observers.

SI units are used for all inputs and outputs.

Parameters:
  • sources (Source | list) – Sources that generate the magnetic field. Can be a single source or a 1D list of s sources.

  • observers (Sensor | list[Sensor] | array-like, shape (o1, o2, ..., 3)) – Input specifying where the field is evaluated. Multiple objects in a list must have identical pixel shape unless pixel_agg is used. All positions given in units (m)

  • sumup (bool, default False) – If True, sum the fields from all sources. If False, keep the source axis.

  • squeeze (bool, default True) – If True squeeze singleton axes (e.g. a single source or a single sensor).

  • pixel_agg (str | None, default None) – Name of a NumPy aggregation function (e.g. 'mean', 'min') applied over the pixel axis of each sensor. Allows mixing sensors with different pixel shapes.

  • output ({'ndarray', 'dataframe'}, default 'ndarray') – Output container type. 'dataframe' returns a pandas DataFrame.

  • in_out ({'auto', 'inside', 'outside'}, default 'auto') – Assumption about observer locations relative to magnet bodies. 'auto' detects per observer (safest, slower). 'inside' treats all inside (faster). 'outside' treats all outside (faster).

Returns:

B-field (T) with squeezed shape (s, p, o, o1, o2, …, 3) where s is the number of sources, p is the number of paths, o the number of observers with (pixel)shape o1, o2, … .

Return type:

ndarray | DataFrame

Examples

B-field of a current loop and a spherical magnet at one observer:

>>> import numpy as np
>>> import magpylib as magpy
>>> loop = magpy.current.Circle(current=100, diameter=0.002)
>>> sph = magpy.magnet.Sphere(polarization=(0.0, 0.0, 0.1), diameter=0.001)
>>> B = magpy.getB([loop, sph], (0.01, 0.01, 0.01))
>>> with np.printoptions(precision=3):
...     print(B)
[[ 6.054e-06  6.054e-06  2.357e-08]
[ 8.019e-07  8.019e-07 -9.056e-23]]

With two sensors:

>>> s1 = magpy.Sensor(position=(0.01, 0.01, 0.01))
>>> s2 = s1.copy(position=(0.01, 0.01, -0.01))
>>> B = magpy.getB([loop, sph], [s1, s2])
>>> with np.printoptions(precision=3):
...     print(B)
[[[ 6.054e-06  6.054e-06  2.357e-08]
[-6.054e-06 -6.054e-06  2.357e-08]]

[[ 8.019e-07  8.019e-07 -9.056e-23]
[-8.019e-07 -8.019e-07 -9.056e-23]]]
magpylib.getFT(sources, targets, pivot='centroid', eps=1e-05, squeeze=True, meshreport=False, return_mesh=False)#

Compute magnetic force and torque on t targets from s sources.

The computation uses meshing and finite differences. SI units are assumed for all inputs and outputs.

Parameters:
  • sources (Source | list[Source]) – Sources that generate the magnetic field. Can be a single source or a 1D list of s source objects.

  • targets (Target | list[Target]) – Objects on which the magnetic field acts, generating force and torque. Can be a 1D list of t target objects. All targets (except Dipoles and Spheres) must have a valid meshing parameter set.

  • pivot ('centroid' | None | array-like, shape (3,) or (t, 3) or (t, p, 3), default 'centroid') – Pivot point through which the force contributes to the torque. If 'centroid', each target’s centroid is used. If None, no pivot is applied (may yield nonphysical results). If an array of shape (3,), the same pivot is used for all targets. Shapes (t, 3) and (t, p, 3) provide per-target or per-target-per-path pivots.

  • eps (float, default 1e-5) – Finite-difference step size for gradient-field computation for magnet targets. A good value is 1e-5 * characteristic_system_size (e.g., magnet size or source-target distance).

  • squeeze (bool, default True) – If True, dimensions of size 1 in the output are removed.

  • meshreport (bool, default False) – If True, prints a brief report of the mesh used for each target.

  • return_mesh (bool, default False) – If True, returns the meshes as a list of dictionaries instead of force and torque.

Returns:

Force and torque with shapes (s, p, t, 3), where s is the number of sources, p the path length, and t the number of targets. If squeeze is True, dimensions of size 1 are removed. If return_mesh is True, returns the meshes list instead.

Return type:

tuple[ndarray, ndarray]

Notes

The force and torque are computed via F = (gradB) · MOM and T = B x MOM + r x F. The gradient field is obtained using finite differences on the meshed targets.

Examples

>>> import numpy as np
>>> import magpylib as magpy
>>> cube = magpy.magnet.Cuboid(
...     dimension=(1.0, 1.0, 1.0),
...     polarization=(0.1, 0.2, 0.3),
... )
>>> circ = magpy.current.Circle(
...     diameter=2.0,
...     current=1e3,
...     position=(0.0, 0.0, 1.0),
...     meshing=50,
... )
>>> F, T = magpy.getFT(cube, circ)
>>> print(f'force: {np.round(F, decimals=2)} N')
force: [ 13.65  27.31 -81.93] N
>>> print(f'torque: {np.round(T, decimals=2)} N*m')
torque: [-8.55  4.27 -0.  ] N*m
magpylib.getH(sources=None, observers=None, sumup=False, squeeze=True, pixel_agg=None, output='ndarray', in_out='auto', **kwargs)#

Return H-field (A/m) of s sources at o observers.

SI units are used for all inputs and outputs.

Parameters:
  • sources (Source | list) – Sources that generate the magnetic field. Can be a single source or a 1D list of s sources.

  • observers (Sensor | list[Sensor] | array-like, shape (o1, o2, ..., 3)) – Input specifying where the field is evaluated. Multiple objects in a list must have identical pixel shape unless pixel_agg is used. All positions given in units (m)

  • sumup (bool, default False) – If True, sum the fields from all sources. If False, keep the source axis.

  • squeeze (bool, default True) – If True squeeze singleton axes (e.g. a single source or a single sensor).

  • pixel_agg (str | None, default None) – Name of a NumPy aggregation function (e.g. 'mean', 'min') applied over the pixel axis of each sensor. Allows mixing sensors with different pixel shapes.

  • output ({'ndarray', 'dataframe'}, default 'ndarray') – Output container type. 'dataframe' returns a pandas DataFrame.

  • in_out ({'auto', 'inside', 'outside'}, default 'auto') – Assumption about observer locations relative to magnet bodies. 'auto' detects per observer (safest, slower). 'inside' treats all inside (faster). 'outside' treats all outside (faster).

Returns:

H-field (A/m) with squeezed shape (s, p, o, o1, o2, …, 3) where s is the number of sources, p is the number of paths, o the number of observers with (pixel)shape o1, o2, … .

Return type:

ndarray | DataFrame

Examples

H-field of a current loop and a spherical magnet at one observer:

>>> import numpy as np
>>> import magpylib as magpy
>>> loop = magpy.current.Circle(current=100.0, diameter=0.002)
>>> sph = magpy.magnet.Sphere(polarization=(0.0, 0.0, 0.1), diameter=0.001)
>>> H = magpy.getH([loop, sph], (0.01, 0.01, 0.01))
>>> with np.printoptions(precision=3):
...    print(H)
[[ 4.818e+00  4.818e+00  1.875e-02]
[ 6.381e-01  6.381e-01 -7.207e-17]]

With two sensors:

>>> sens1 = magpy.Sensor(position=(0.01, 0.01, 0.01))
>>> sens2 = sens1.copy(position=(0.01, 0.01, -0.01))
>>> H = magpy.getH([src1, src2], [sens1, sens2])
>>> with np.printoptions(precision=3):
...    print(H)
[[[ 4.818e+00  4.818e+00  1.875e-02]
[-4.818e+00 -4.818e+00  1.875e-02]]

[[ 6.381e-01  6.381e-01 -7.207e-17]
[-6.381e-01 -6.381e-01 -7.207e-17]]]
magpylib.getJ(sources=None, observers=None, sumup=False, squeeze=True, pixel_agg=None, output='ndarray', in_out='auto', **kwargs)#

Return magnetic polarization (T) of s sources at o observers.

SI units are used for all inputs and outputs.

Parameters:
  • sources (Source | list) – Sources that generate the magnetic field. Can be a single source or a 1D list of s sources.

  • observers (Sensor | list[Sensor] | array-like, shape (o1, o2, ..., 3)) – Input specifying where the field is evaluated. Multiple objects in a list must have identical pixel shape unless pixel_agg is used. All positions given in units (m)

  • sumup (bool, default False) – If True, sum the fields from all sources. If False, keep the source axis.

  • squeeze (bool, default True) – If True squeeze singleton axes (e.g. a single source or a single sensor).

  • pixel_agg (str | None, default None) – Name of a NumPy aggregation function (e.g. 'mean', 'min') applied over the pixel axis of each sensor. Allows mixing sensors with different pixel shapes.

  • output ({'ndarray', 'dataframe'}, default 'ndarray') – Output container type. 'dataframe' returns a pandas DataFrame.

  • in_out ({'auto', 'inside', 'outside'}, default 'auto') – Assumption about observer locations relative to magnet bodies. 'auto' detects per observer (safest, slower). 'inside' treats all inside (faster). 'outside' treats all outside (faster).

Returns:

Polarization (T) with squeezed shape (s, p, o, o1, o2, …, 3) where s is the number of sources, p is the number of paths, o the number of observers with (pixel)shape o1, o2, … .

Return type:

ndarray | DataFrame

Examples

Polarization at one point (inside the magnet):

>>> import numpy as np
>>> import magpylib as magpy
>>> cube = magpy.magnet.Cuboid(
...     dimension=(10, 1, 1),
...     polarization=(1, 0, 0)
... ).rotate_from_angax(45, 'z')
>>> J = cube.getJ((3, 3, 0))
>>> with np.printoptions(precision=3):
...    print(J)
[0.707 0.707 0.   ]
magpylib.getM(sources=None, observers=None, sumup=False, squeeze=True, pixel_agg=None, output='ndarray', in_out='auto', **kwargs)#

Return magnetization (A/m) of s sources at o observers.

SI units are used for all inputs and outputs.

Parameters:
  • sources (Source | list) – Sources that generate the magnetic field. Can be a single source or a 1D list of s sources.

  • observers (Sensor | list[Sensor] | array-like, shape (o1, o2, ..., 3)) – Input specifying where the field is evaluated. Multiple objects in a list must have identical pixel shape unless pixel_agg is used. All positions given in units (m)

  • sumup (bool, default False) – If True, sum the fields from all sources. If False, keep the source axis.

  • squeeze (bool, default True) – If True squeeze singleton axes (e.g. a single source or a single sensor).

  • pixel_agg (str | None, default None) – Name of a NumPy aggregation function (e.g. 'mean', 'min') applied over the pixel axis of each sensor. Allows mixing sensors with different pixel shapes.

  • output ({'ndarray', 'dataframe'}, default 'ndarray') – Output container type. 'dataframe' returns a pandas DataFrame.

  • in_out ({'auto', 'inside', 'outside'}, default 'auto') – Assumption about observer locations relative to magnet bodies. 'auto' detects per observer (safest, slower). 'inside' treats all inside (faster). 'outside' treats all outside (faster).

Returns:

Magnetization (A/m) with squeezed shape (s, p, o, o1, o2, …, 3) where s is the number of sources, p is the number of paths, o the number of observers with (pixel)shape o1, o2, … .

Return type:

ndarray | DataFrame

Examples

Magnetization at one point (inside the magnet):

>>> import numpy as np
>>> import magpylib as magpy
>>> cube = magpy.magnet.Cuboid(
...     dimension=(10, 1, 1),
...     polarization=(1, 0, 0)
... ).rotate_from_angax(45, 'z')
>>> M = cube.getM((3, 3, 0))
>>> with np.printoptions(precision=0):
...    print(M)
[562698. 562698.      0.]
magpylib.show(*objects, backend=<default>, canvas=<default>, animation=<default>, zoom=<default>, markers=<default>, return_fig=<default>, canvas_update=<default>, row=<default>, col=<default>, output=<default>, sumup=<default>, pixel_agg=<default>, style=<default>, **kwargs)#

Display objects and paths graphically.

Global graphic styles can be set with kwargs as style dictionary or using style underscore magic.

Parameters:
  • *objects (Source | Sensor | Collection) – One or multiple Magpylib objects to be displayed.

  • backend ({'auto', 'matplotlib', 'plotly', 'pyvista'}, default 'auto') – With 'auto' the backend becomes 'plotly' inside a notebook when Plotly is installed, otherwise 'matplotlib'. If canvas is provided, its type determines the backend.

  • canvas (None | matplotlib.Figure | plotly.Figure | pyvista.Plotter, default None) – Existing canvas to draw on. If None, a new canvas is created and displayed.

  • animation (bool | float, default False) – If True and at least one object has a path, the path is animated. A positive float sets the total animation duration in seconds (Plotly only).

  • zoom (float, default 0.0) – 3D plot zoom level. 0 means tight bounds.

  • markers (array-like, shape (n, 3) | None, default None) – Global position markers shown as points.

  • return_fig (bool, default False) – If True, return the underlying figure object (Figure / FigureWidget / Plotter).

  • canvas_update (str | bool, default 'auto') – Layout update behaviour when using a provided canvas. With 'auto' applies internal layout only for newly created canvases. True forces update, False suppresses it.

  • row (int | None, default None) – Subplot row index.

  • col (int | None, default None) – Subplot column index.

  • output (str | tuple[str, ...], default 'model3d') – Plot output type. 'model3d' shows 3D geometry. Field plots are defined via component strings like 'Bx', 'Bxy', 'Hyz'. Multiple axes in a string imply vector norm combination (e.g., 'Bxy' => sqrt(Bx**2 + By**2)).

  • sumup (bool, default True) – Sum field contributions of sources.

  • pixel_agg (str, default 'mean') – NumPy reducer applied across sensor pixels (e.g., 'min', 'max', 'std').

  • style (dict | None, default None) – Global style overrides, e.g. {'color': 'red'} or via underscore magic (style_color='red'). Applied to matching objects.

Returns:

The created/updated figure object if return_fig=True; otherwise None.

Return type:

None | matplotlib.Figure | plotly.Figure | pyvista.Plotter

Examples

Display multiple objects, object paths, markers in 3D using Matplotlib or Plotly:

>>> import magpylib as magpy
>>> src = magpy.magnet.Sphere(polarization=(0, 0, 1), diameter=1)
>>> src.move([(0.1*x, 0, 0) for x in range(50)])
Sphere...
>>> src.rotate_from_angax(angle=[*range(0, 400, 10)], axis='z', anchor=0, start=11)
Sphere...
>>> ts = [-.4, 0, .4]
>>> sens = magpy.Sensor(position=(0, 0, 2), pixel=[(x, y, 0) for x in ts for y in ts])
>>> magpy.show(src, sens) 
>>> magpy.show(src, sens, backend='plotly') 
>>> # graphic output

Display output on your own canvas (here a Matplotlib 3d-axes):

>>> import matplotlib.pyplot as plt
>>> import magpylib as magpy
>>> my_axis = plt.axes(projection='3d')
>>> magnet = magpy.magnet.Cuboid(polarization=(1, 1, 1), dimension=(1, 2, 3))
>>> sens = magpy.Sensor(position=(0, 0, 3))
>>> magpy.show(magnet, sens, canvas=my_axis, zoom=1)
>>> plt.show() 
>>> # graphic output

Use sophisticated figure styling options accessible from defaults, as individual object styles or as global style arguments in display.

>>> import magpylib as magpy
>>> src1 = magpy.magnet.Sphere(position=[(0, 0, 0), (0, 0, 3)], diameter=1, polarization=(1, 1, 1))
>>> src2 = magpy.magnet.Sphere(
...     position=[(1, 0, 0), (1, 0, 3)],
...     diameter=1,
...     polarization=(1, 1, 1),
...     style_path_show=False
... )
>>> magpy.defaults.display.style.magnet.magnetization.size = 2
>>> src1.style.magnetization.size = 1
>>> magpy.show(src1, src2, style_color='r') 
>>> # graphic output

Use a context manager to jointly animate 3d and 2d subplots

>>> import magpylib as magpy
>>> import numpy as np
>>> import plotly.graph_objects as go
>>> path_len = 40
>>> sensor = magpy.Sensor()
>>> cyl1 = magpy.magnet.Cylinder(
...    polarization=(.1, 0, 0),
...    dimension=(1, 2),
...    position=(4, 0, 0),
...    style_label="Cylinder1",
... )
>>> sensor.move(np.linspace((0, 0, -3), (0, 0, 3), path_len), start=0)
Sensor(id=...)
>>> cyl1.rotate_from_angax(angle=np.linspace(0, 300, path_len), start=0, axis="z", anchor=0)
Cylinder(id=...)
>>> cyl2 = cyl1.copy().move((0, 0, 5))
>>> fig = go.Figure()
>>> with magpy.show_context(cyl1, cyl2, sensor, canvas=fig, backend="plotly", animation=True):
...    magpy.show(col=1, output="model3d")
...    magpy.show(col=2, output="Bxy", sumup=True)
...    magpy.show(col=3, output="Bz", sumup=False)
>>> fig.show() 
>>> # graphic output
magpylib.show_context(*objects, backend=<default>, canvas=<default>, animation=<default>, zoom=<default>, markers=<default>, return_fig=<default>, canvas_update=<default>, row=<default>, col=<default>, output=<default>, sumup=<default>, pixel_agg=<default>, style=<default>, **kwargs)#

Context manager for grouping multiple show() calls with shared settings.

Use this to apply common display options across several successive show() calls and have them rendered together on a single canvas and/or subplot layout. All supplied options are remembered during the context and applied to the final combined render when the context exits.

Parameters:
  • objects (Source | Sensor | Collection) – One or more Magpylib objects to register up-front for display.

  • backend (str, default magpylib.defaults.display.backend) – Plotting backend: 'auto', 'matplotlib', 'plotly', or 'pyvista'.

  • canvas (None | matplotlib.Figure | plotly.Figure | pyvista.Plotter, default None) – Existing canvas to draw on. If None, a new canvas is created.

  • animation (bool | float, default False) – If True (and at least one object has a path) the path is animated. A positive float sets total animation duration in seconds (Plotly only).

  • zoom (float, default 0.0) – 3D plot zoom level 0.0 means tight bounds.

  • markers (array-like, shape (n, 3) | None, default None) – Global position markers shown as points.

  • return_fig (bool, default False) – If True, return the underlying figure from the final render.

  • canvas_update (str | bool, default 'auto') – Layout update behaviour when using a provided canvas: 'auto', True, or False.

  • row (int | None, default None) – Subplot row index for all enclosed show() calls that omit row.

  • col (int | None, default None) – Subplot column index for all enclosed show() calls that omit col.

  • output (str | tuple[str, ...], default 'model3d') – Plot output type (e.g., 'model3d', 'Bx', 'Bxy', 'Hyz').

  • sumup (bool, default True) – Sum source contributions when output != 'model3d'.

  • pixel_agg (str, default 'mean') – NumPy reducer applied across sensor pixels for non-'model3d' outputs (e.g., 'min', 'max', 'std').

  • style (dict | None, default None) – Global style overrides (e.g., {'color': 'red'}) or via underscore magic (e.g., style_color='red').

  • **kwargs – Additional backend, figure (fig_*), and show (show_*) options.

Yields:

DisplayContext – The active display context. After the with block, the combined render result is available as ctx.show_return_value.

Returns:

The context manager does not return a value.

Return type:

None

Notes

  • All show() calls inside the context inherit unspecified options from the context manager arguments.

  • Objects passed to the context are combined with objects passed to each inner show() call.

  • On exit, a single show() is executed with the aggregated objects and options.

Examples

Create a 1x3 Plotly layout and render 3 outputs in one animation:

>>> import magpylib as magpy
>>> import plotly.graph_objects as go
>>> fig = go.Figure()
>>> with magpy.show_context(src1, src2, sensor, canvas=fig, backend='plotly', animation=True) as ctx:
...     magpy.show(col=1, output='model3d')
...     magpy.show(col=2, output='Bxy', sumup=True)
...     magpy.show(col=3, output='Bz', sumup=False)
>>> fig  

Subpackages#