3D transformations for Python with comprehensive rotation representations, coordinate conversions, and visualization tools
—
Utilities for 3D plotting and visualization using matplotlib. This module provides high-level plotting functions for geometric shapes, coordinate frames, and 3D objects commonly used in robotics and computer graphics applications.
High-level matplotlib artists for drawing 3D objects and coordinate systems.
class Arrow3D:
"""
3D arrow artist for matplotlib.
Parameters:
- start: array-like, shape (3,) - arrow start position
- direction: array-like, shape (3,) - arrow direction vector
- length: float - arrow length
- **kwargs: additional matplotlib parameters
"""
class Frame:
"""
Coordinate frame artist showing x, y, z axes.
Parameters:
- A2B: array-like, shape (4, 4) - transformation matrix
- label: str - frame label
- s: float - frame scale
- **kwargs: additional parameters
"""
class LabeledFrame(Frame):
"""
Coordinate frame with axis labels (X, Y, Z).
Parameters:
- A2B: array-like, shape (4, 4) - transformation matrix
- label: str - frame label
- s: float - frame scale
- **kwargs: additional parameters
"""
class Trajectory:
"""
3D trajectory artist for path visualization.
Parameters:
- P: array-like, shape (n_steps, 3) - trajectory positions
- show_direction: bool - whether to show direction arrows
- **kwargs: additional matplotlib parameters
"""
class Camera:
"""
Camera visualization artist.
Parameters:
- cam2world: array-like, shape (4, 4) - camera pose
- sensor_size: array-like, shape (2,) - sensor dimensions
- focal_length: float - camera focal length
- **kwargs: additional parameters
"""Utilities for creating and managing 3D matplotlib axes.
def make_3d_axis(ax_s=1, pos=111, unit="m", n_ticks=6):
"""
Create a 3D matplotlib axis with proper formatting.
Parameters:
- ax_s: float - axis size/scale
- pos: int - subplot position (e.g., 111)
- unit: str - axis unit label
- n_ticks: int - number of axis ticks
Returns:
- ax: matplotlib Axes3D - configured 3D axis
"""
def remove_frame(ax):
"""
Remove frame/box from 3D axis for cleaner visualization.
Parameters:
- ax: matplotlib Axes3D - axis to modify
"""Functions for plotting various 3D geometric shapes and objects.
def plot_box(ax=None, size=[1, 1, 1], A2B=None, **kwargs):
"""
Plot a 3D box/cube.
Parameters:
- ax: matplotlib Axes3D - axis to plot on
- size: array-like, shape (3,) - box dimensions [length, width, height]
- A2B: array-like, shape (4, 4) - box pose transformation
- **kwargs: additional matplotlib parameters
Returns:
- collection: matplotlib collection - box visualization
"""
def plot_sphere(ax=None, radius=1.0, p=[0, 0, 0], **kwargs):
"""
Plot a 3D sphere.
Parameters:
- ax: matplotlib Axes3D - axis to plot on
- radius: float - sphere radius
- p: array-like, shape (3,) - sphere center position
- **kwargs: additional matplotlib parameters
Returns:
- surface: matplotlib surface - sphere visualization
"""
def plot_spheres(ax=None, P=None, radius=1.0, **kwargs):
"""
Plot multiple 3D spheres.
Parameters:
- ax: matplotlib Axes3D - axis to plot on
- P: array-like, shape (n_spheres, 3) - sphere center positions
- radius: float or array-like - sphere radius/radii
- **kwargs: additional matplotlib parameters
Returns:
- collection: matplotlib collection - spheres visualization
"""
def plot_cylinder(ax=None, length=1.0, radius=1.0, A2B=None, **kwargs):
"""
Plot a 3D cylinder.
Parameters:
- ax: matplotlib Axes3D - axis to plot on
- length: float - cylinder length
- radius: float - cylinder radius
- A2B: array-like, shape (4, 4) - cylinder pose transformation
- **kwargs: additional matplotlib parameters
Returns:
- collection: matplotlib collection - cylinder visualization
"""
def plot_mesh(ax=None, filename=None, A2B=None, **kwargs):
"""
Plot a 3D mesh from file.
Parameters:
- ax: matplotlib Axes3D - axis to plot on
- filename: str - path to mesh file
- A2B: array-like, shape (4, 4) - mesh pose transformation
- **kwargs: additional matplotlib parameters
Returns:
- collection: matplotlib collection - mesh visualization
"""
def plot_ellipsoid(ax=None, radii=[1, 1, 1], A2B=None, **kwargs):
"""
Plot a 3D ellipsoid.
Parameters:
- ax: matplotlib Axes3D - axis to plot on
- radii: array-like, shape (3,) - ellipsoid radii [a, b, c]
- A2B: array-like, shape (4, 4) - ellipsoid pose transformation
- **kwargs: additional matplotlib parameters
Returns:
- surface: matplotlib surface - ellipsoid visualization
"""
def plot_capsule(ax=None, height=1.0, radius=1.0, A2B=None, **kwargs):
"""
Plot a 3D capsule (cylinder with hemispherical ends).
Parameters:
- ax: matplotlib Axes3D - axis to plot on
- height: float - capsule height
- radius: float - capsule radius
- A2B: array-like, shape (4, 4) - capsule pose transformation
- **kwargs: additional matplotlib parameters
Returns:
- collection: matplotlib collection - capsule visualization
"""
def plot_cone(ax=None, height=1.0, radius=1.0, A2B=None, **kwargs):
"""
Plot a 3D cone.
Parameters:
- ax: matplotlib Axes3D - axis to plot on
- height: float - cone height
- radius: float - cone base radius
- A2B: array-like, shape (4, 4) - cone pose transformation
- **kwargs: additional matplotlib parameters
Returns:
- collection: matplotlib collection - cone visualization
"""Helper functions for drawing vectors and variable-length objects.
def plot_vector(ax=None, start=[0, 0, 0], direction=[1, 0, 0], **kwargs):
"""
Plot a 3D vector as an arrow.
Parameters:
- ax: matplotlib Axes3D - axis to plot on
- start: array-like, shape (3,) - vector start position
- direction: array-like, shape (3,) - vector direction
- **kwargs: additional matplotlib parameters
Returns:
- arrow: Arrow3D - vector visualization
"""
def plot_length_variable(ax=None, start=[0, 0, 0], end=[1, 0, 0], **kwargs):
"""
Plot a variable-length line between two points.
Parameters:
- ax: matplotlib Axes3D - axis to plot on
- start: array-like, shape (3,) - line start position
- end: array-like, shape (3,) - line end position
- **kwargs: additional matplotlib parameters
Returns:
- line: matplotlib Line3D - line visualization
"""import numpy as np
import matplotlib.pyplot as plt
from pytransform3d.plot_utils import (
make_3d_axis,
plot_box,
plot_sphere,
plot_cylinder
)
# Create 3D figure and axis
fig = plt.figure(figsize=(10, 8))
ax = make_3d_axis(ax_s=2, unit="m")
# Plot various geometric shapes
plot_box(ax, size=[0.5, 0.3, 0.2], A2B=np.eye(4), color='red', alpha=0.7)
# Sphere at different position
sphere_pose = np.eye(4)
sphere_pose[:3, 3] = [1, 0, 0] # translate
plot_sphere(ax, radius=0.3, p=[1, 0, 0], color='blue', alpha=0.6)
# Cylinder with rotation
cylinder_pose = np.eye(4)
cylinder_pose[:3, 3] = [0, 1, 0]
plot_cylinder(ax, length=0.8, radius=0.2, A2B=cylinder_pose,
color='green', alpha=0.8)
plt.show()import numpy as np
import matplotlib.pyplot as plt
from pytransform3d.plot_utils import make_3d_axis, LabeledFrame
from pytransform3d.transformations import transform_from
from pytransform3d.rotations import matrix_from_euler
# Create axis
fig = plt.figure()
ax = make_3d_axis(ax_s=1.5)
# Create and plot multiple coordinate frames
base_frame = np.eye(4)
frame1 = transform_from(
R=matrix_from_euler([0.2, 0.3, 0.1], 0, 1, 2, True),
p=[0.5, 0.2, 0.3]
)
frame2 = transform_from(
R=matrix_from_euler([-0.1, 0.5, -0.2], 0, 1, 2, True),
p=[-0.3, 0.4, 0.1]
)
# Plot frames with labels
LabeledFrame(A2B=base_frame, label="Base", s=0.3, ax=ax)
LabeledFrame(A2B=frame1, label="Frame1", s=0.2, ax=ax)
LabeledFrame(A2B=frame2, label="Frame2", s=0.2, ax=ax)
plt.show()import numpy as np
import matplotlib.pyplot as plt
from pytransform3d.plot_utils import make_3d_axis, Camera
from pytransform3d.transformations import transform_from
# Setup visualization
fig = plt.figure()
ax = make_3d_axis(ax_s=2)
# Camera looking at origin from different positions
cam_poses = []
for i in range(4):
angle = i * np.pi / 2
cam_pose = transform_from(
R=np.eye(3), # simplified - should use proper rotation
p=[2*np.cos(angle), 2*np.sin(angle), 1]
)
cam_poses.append(cam_pose)
# Plot cameras
for i, pose in enumerate(cam_poses):
Camera(
cam2world=pose,
sensor_size=[0.1, 0.1],
focal_length=0.2,
ax=ax,
alpha=0.7
)
plt.show()import matplotlib.pyplot as plt
from pytransform3d.plot_utils import make_3d_axis, plot_mesh
from pytransform3d.transformations import transform_from
# Load and display 3D mesh
fig = plt.figure()
ax = make_3d_axis(ax_s=1)
# Plot mesh at different poses (requires mesh file)
mesh_poses = [
np.eye(4),
transform_from(R=np.eye(3), p=[0.5, 0, 0]),
transform_from(R=np.eye(3), p=[0, 0.5, 0])
]
for pose in mesh_poses:
plot_mesh(
ax=ax,
filename="path/to/mesh.obj", # replace with actual mesh file
A2B=pose,
alpha=0.8
)
plt.show()Install with Tessl CLI
npx tessl i tessl/pypi-pytransform3d