Collections
Contents
Collections#
The Collection
class is a versatile way of grouping and manipulating multiple Magpylib objects. A basic introduction is given in Collections. Here things are explained in more detail with examples.
Constructing collections#
Collections have the attributes children
, sources
, sensors
and collections
. These attributes are ordered lists that contain objects that are added to the collection by reference (not copied). children
returns is list of all objects in the collection. sources
returns a list of the sources, sensors
a list of the sensors and collections
a list of “sub-collections” within the collection.
import magpylib as magpy
x1 = magpy.Sensor(style_label='x1')
s1 = magpy.magnet.Cuboid(style_label='s1')
c1 = magpy.Collection(style_label='c1')
coll = magpy.Collection(x1, s1, c1, style_label='coll')
print(f"children: {coll.children}")
print(f"sources: {coll.sources}")
print(f"sensors: {coll.sensors}")
print(f"collections: {coll.collections}")
children: [Sensor(id=139829444294976, label='x1'), Cuboid(id=139828691102592, label='s1'), Collection(id=139829444293728, label='c1')]
sources: [Cuboid(id=139828691102592, label='s1')]
sensors: [Sensor(id=139829444294976, label='x1')]
collections: [Collection(id=139829444293728, label='c1')]
New additions are always added at the end. Add objects to an existing collection using these parameters, or the add
method.
# automatically adjusts object label
x2 = x1.copy()
s2 = s1.copy()
c2 = c1.copy()
# add objects with add method
coll.add(x2, s2)
# add objects with parameters
coll.collections += [c2]
print(f"children: {coll.children}")
print(f"sources: {coll.sources}")
print(f"sensors: {coll.sensors}")
print(f"collections: {coll.collections}")
children: [Sensor(id=139829444294976, label='x1'), Cuboid(id=139828691102592, label='s1'), Sensor(id=139829444295360, label='x2'), Cuboid(id=139829520958080, label='s2'), Collection(id=139829444293728, label='c1'), Collection(id=139829520959808, label='c2')]
sources: [Cuboid(id=139828691102592, label='s1'), Cuboid(id=139829520958080, label='s2')]
sensors: [Sensor(id=139829444294976, label='x1'), Sensor(id=139829444295360, label='x2')]
collections: [Collection(id=139829444293728, label='c1'), Collection(id=139829520959808, label='c2')]
The describe
method is a very convenient way to view a Collection structure, especially when the collection is nested, i.e. when containing other collections:
# add more objects
c1.add(x2.copy())
c2.add(s2.copy())
coll.describe(format='label')
coll
├── x1
├── s1
├── x2
├── s2
├── c1
│ └── x3
└── c2
└── s3
For convenience, any two Magpylib object can be added up with +
to form a collection:
import magpylib as magpy
x1 = magpy.Sensor(style_label='x1')
s1 = magpy.magnet.Cuboid(style_label='s1')
coll = x1 + s1
coll.describe(format='label')
Collection
├── x1
└── s1
Child-parent relations#
Objects that are part of a collection become children of that collection, and the collection itself becomes their parent. Every Magpylib object has the parent
attribute, which is None
by default.
import magpylib as magpy
x1 = magpy.Sensor()
c1 = magpy.Collection(x1)
print(f"x1.parent: {x1.parent}")
print(f"c1.parent: {c1.parent}")
print(f"c1.children: {c1.children}")
x1.parent: Collection(id=139829444294592)
c1.parent: None
c1.children: [Sensor(id=139829444294544)]
Rather than adding objects to a collection, as described above, one can also set the parent
parameter. A Magpylib object can only have a single parent, i.e. it can only be part of a single collection. As a result, changing the parent will automatically remove the object from it’s previous collection.
import magpylib as magpy
x1 = magpy.Sensor(style_label='x1')
c1 = magpy.Collection(style_label='c1')
c2 = magpy.Collection(c1, style_label='c2')
print("Two empty, nested collections")
c2.describe(format='label')
print("\nSet x1 parent to c1")
x1.parent = c1
c2.describe(format='label')
print("\nChange x1 parent to c2")
x1.parent = c2
c2.describe(format='label')
Two empty, nested collections
c2
└── c1
Set x1 parent to c1
c2
└── c1
└── x1
Change x1 parent to c2
c2
├── c1
└── x1
Working with collections#
Collections have __getitem__
through the attribute children
defined which enables using collections directly as iterators,
import magpylib as magpy
x1 = magpy.Sensor()
x2 = magpy.Sensor()
coll = x1 + x2
for child in coll:
print(child)
Sensor(id=139828690856448)
Sensor(id=139828690855824)
and makes it possible to directly reference to a child object by index:
print(coll[0])
Sensor(id=139828690856448)
Collection nesting is powerful to create a self-consistent hierarchical structure, however, it is often in the way of simple construction and children access in nested trees. For this, the children_all
, sources_all
, sensors_all
and collections_all
read-only parameters, give quick access to all objects in the tree:
import magpylib as magpy
s1 = magpy.Sensor(style_label='s1')
s2 = s1.copy()
s3 = s2.copy()
# this creates anested collection
coll = s1 + s2 + s3
coll.describe(format='label')
# _all gives access to the whole tree
print([s.style.label for s in coll.sensors_all])
Collection
├── Collection
│ ├── s1
│ └── s2
└── s3
['s1', 's2', 's3']
How to work with collections in a practical way is demonstrated in the introduction section Collections.
How to make complex compound objects is documented in Collections - Compounds.
Efficient 3D models#
The Matplotlib and Plotly libraries were not designed for complex 3D graphic outputs. As a result, it becomes often inconvenient and slow when attempting to display many 3D objects. One solution to this problem when dealing with large collections, is to represent the latter by a single encompassing body, and to deactivate the individual 3D models of all children. This is demonstrated in the following example.
import magpylib as magpy
# create collection
coll = magpy.Collection()
for index in range(10):
cuboid = magpy.magnet.Cuboid(
magnetization=(0, 0, 1000 * (index%2-.5)),
dimension=(10,10,10),
position=(index*10,0,0),
)
coll.add(cuboid)
# add 3D-trace
plotly_trace = magpy.graphics.model3d.make_Cuboid(
backend='matplotlib',
dimension=(104, 12, 12),
position=(45, 0, 0),
alpha=0.5,
)
coll.style.model3d.add_trace(plotly_trace)
coll.style.label='Collection with visible children'
coll.show()
# hide the children default 3D representation
coll.set_children_styles(model3d_showdefault=False)
coll.style.label = 'Collection with hidden children'
coll.show()


Note
The Collection
position is set to (0,0,0) at creation time. Any added extra 3D-model will be bound to the local coordinate system of to the Collection
and rotated
/moved
together with its parent object.