""" Display function codes"""
import numpy as np
import matplotlib.pyplot as plt
from magpylib._lib.utility import format_obj_input, test_path_format
from magpylib._lib.display.mpl_draw import (draw_directs_faced, draw_faces, draw_markers, draw_path,
draw_pixel, draw_sensors, draw_dipoles, draw_circular, draw_line)
from magpylib._lib.display.disp_utility import (faces_box, faces_cylinder, system_size,
faces_sphere)
from magpylib import _lib
# ON INTERFACE
[docs]def display(
*objects,
markers=[(0,0,0)],
axis=None,
show_direction=False,
show_path=True,
size_sensors=1,
size_direction=1,
size_dipoles=1):
"""
Display objects and paths graphically using matplotlib 3D plotting.
Parameters
----------
objects: sources, collections or sensors
Objects to be displayed.
markers: array_like, shape (N,3), default=[(0,0,0)]
Display position markers in the global CS. By default a marker is placed
in the origin.
axis: pyplot.axis, default=None
Display graphical output in a given pyplot axis (must be 3D). By default a new
pyplot figure is created and displayed.
show_direction: bool, default=False
Set True to show magnetization and current directions.
show_path: bool or int, default=True
Options True, False, positive int. By default object paths are shown. If
show_path is a positive integer, objects will be displayed at multiple path
positions along the path, in steps of show_path.
size_sensor: float, default=1
Adjust automatic display size of sensors.
size_direction: float, default=1
Adjust automatic display size of direction arrows.
size_dipoles: float, default=1
Adjust automatic display size of dipoles.
Returns
-------
None: NoneType
Examples
--------
Display multiple objects, object paths, markers in 3D using Matplotlib:
>>> import magpylib as mag3
>>> col = mag3.Collection(
[mag3.magnet.Sphere(magnetization=(0,0,1), diameter=1) for _ in range(3)])
>>> for displ,src in zip([(.1414,0,0),(-.1,-.1,0),(-.1,.1,0)], col):
>>> src.move([displ]*50, increment=True)
>>> src.rotate_from_angax(angle=[10]*50, axis='z', anchor=0, start=0, increment=True)
>>> ts = [-.6,-.4,-.2,0,.2,.4,.6]
>>> sens = mag3.Sensor(position=(0,0,2), pixel=[(x,y,0) for x in ts for y in ts])
>>> mag3.display(col, sens)
--> graphic output
Display figure on your own 3D Matplotlib axis:
>>> import matplotlib.pyplot as plt
>>> import magpylib as mag3
>>> my_axis = plt.axes(projection='3d')
>>> magnet = mag3.magnet.Box(magnetization=(0,0,1), dimension=(1,2,3))
>>> sens = mag3.Sensor(position=(0,0,3))
>>> mag3.display(magnet, sens, axis=my_axis)
>>> plt.show()
--> graphic output
"""
# pylint: disable=protected-access
# pylint: disable=too-many-branches
# pylint: disable=too-many-statements
# pylint: disable=dangerous-default-value
# avoid circular imports
Box = _lib.obj_classes.Box
Cylinder = _lib.obj_classes.Cylinder
Sensor = _lib.obj_classes.Sensor
Sphere = _lib.obj_classes.Sphere
Dipole = _lib.obj_classes.Dipole
Circular = _lib.obj_classes.Circular
Line = _lib.obj_classes.Line
# create or set plotting axis
if axis is None:
fig = plt.figure(dpi=80, figsize=(8,8))
ax = fig.add_subplot(111, projection='3d')
ax.set_box_aspect((1, 1, 1))
generate_output = True
else:
ax = axis
generate_output = False
# load color map
cmap = plt.cm.get_cmap('hsv')
# flatten input
obj_list = format_obj_input(objects)
# test if every individual obj_path is good
test_path_format(obj_list)
# sort input objects --------------------------------------------------------
# objects with faces
faced_objects = [obj for obj in obj_list if isinstance(obj, (
Box,
Cylinder,
Sphere
))]
# sensors
sensors = [obj for obj in obj_list if isinstance(obj, Sensor)]
# dipoles
dipoles = [obj for obj in obj_list if isinstance(obj, Dipole)]
# currents
circulars = [obj for obj in obj_list if isinstance(obj, Circular)]
lines = [obj for obj in obj_list if isinstance(obj, Line)]
# draw objects and evaluate system size --------------------------------------
# draw faced objects and store vertices
face_points = []
for i, obj in enumerate(faced_objects):
col = cmap(i/len(faced_objects))
if isinstance(obj, Box):
faces = faces_box(obj,show_path)
lw = 0.5
face_points += draw_faces(faces, col, lw, ax)
elif isinstance(obj, Cylinder):
faces = faces_cylinder(obj,show_path)
lw = 0.25
face_points += draw_faces(faces, col, lw, ax)
elif isinstance(obj, Sphere):
faces = faces_sphere(obj,show_path)
lw = 0.25
face_points += draw_faces(faces, col, lw, ax)
# draw sensor pixel and get positions
sensor_points = draw_pixel(sensors, ax, show_path)
# get dipole positions
dipole_points = [dip.position for dip in dipoles]
# draw circulars and get line positions
current_points = draw_circular(circulars, show_path, ax)
current_points += draw_line(lines, show_path, ax)
# draw paths and get path points
path_points = []
if show_path: # True or int>0
for i, obj in enumerate(faced_objects):
col = cmap(i/len(faced_objects))
path_points += draw_path(obj, col, ax)
for sens in sensors:
path_points += draw_path(sens, '.6', ax)
for dip in dipoles:
path_points += draw_path(dip, '.6', ax)
for circ in circulars:
path_points += draw_path(circ, '.6', ax)
for line in lines:
path_points += draw_path(line, '.6', ax)
# markers -------------------------------------------------------
if markers:
markers = np.array(markers)
draw_markers(markers, ax)
# draw direction arrows (based on src size) -------------------------
if show_direction:
draw_directs_faced(faced_objects, cmap, ax, show_path, size_direction)
# determine system size -----------------------------------------
limx1, limx0, limy1, limy0, limz1, limz0 = system_size(
face_points, sensor_points, dipole_points, markers, path_points, current_points)
sys_size = max([limx1-limx0, limy1-limy0, limz1-limz0])
# draw all system sized based quantities -------------------------
draw_sensors(sensors, ax, sys_size, show_path, size_sensors)
draw_dipoles(dipoles, ax, sys_size, show_path, size_dipoles)
# plot styling --------------------------------------------------
ax.set(
xlabel = 'x [mm]',
ylabel = 'y [mm]',
zlabel = 'z [mm]',
xlim=(limx0, limx1),
ylim=(limy0, limy1),
zlim=(limz0, limz1)
)
# generate output ------------------------------------------------
if generate_output:
plt.show()