CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pytransform3d

3D transformations for Python with comprehensive rotation representations, coordinate conversions, and visualization tools

Pending
Overview
Eval results
Files

visualization.mddocs/

Visualization

3D plotting and visualization tools using matplotlib and Open3D backends for transformations, trajectories, and geometric objects with comprehensive rendering capabilities.

Capabilities

Matplotlib-based Visualization

2D and 3D plotting using matplotlib with support for transformations and geometric objects.

# Layout functions
def make_3d_axis(ax_s=1, pos=111, unit=None, n_ticks=5, **kwargs):
    """
    Create 3D matplotlib axis with proper scaling.
    
    Parameters:
    - ax_s: float - Axis scaling factor
    - pos: int - Subplot position
    - unit: str, optional - Axis unit label
    - n_ticks: int - Number of axis ticks
    
    Returns:
    - ax: Axes3D - Configured 3D axis
    """

def remove_frame(ax):
    """Remove frame decorations from 3D axis."""

# Transformation plotting
def plot_transform(ax=None, A2B=None, s=1.0, ax_s=1, **kwargs):
    """
    Plot transformation as coordinate frame.
    
    Parameters:
    - ax: Axes3D, optional - 3D axis
    - A2B: array, shape (4, 4), optional - Transformation matrix
    - s: float - Frame size scaling
    - ax_s: float - Axis scaling
    """

def plot_screw(ax=None, q=None, s_axis=None, h=None, theta=None, s=1.0, ax_s=1, **kwargs):
    """Plot screw motion visualization."""

def plot_trajectory(P=None, show_direction=True, n_frames=10, s=1.0, ax=None, **kwargs):
    """
    Plot 3D trajectory with direction indicators.
    
    Parameters:
    - P: array, shape (n_steps, 3 or 4, 4) - Trajectory as transforms or positions
    - show_direction: bool - Show trajectory direction arrows
    - n_frames: int - Number of coordinate frames to show
    - s: float - Frame size scaling
    - ax: Axes3D, optional - 3D axis
    """

# Geometry plotting
def plot_box(ax=None, size=[1, 1, 1], A2B=np.eye(4), **kwargs):
    """Plot 3D box."""

def plot_sphere(ax=None, radius=1.0, p=np.zeros(3), **kwargs):
    """Plot sphere."""

def plot_cylinder(ax=None, length=1.0, radius=1.0, A2B=np.eye(4), **kwargs):
    """Plot cylinder."""

def plot_ellipsoid(ax=None, radii=[1, 1, 1], A2B=np.eye(4), **kwargs):
    """Plot ellipsoid."""

def plot_capsule(ax=None, height=1.0, radius=1.0, A2B=np.eye(4), **kwargs):
    """Plot capsule (cylinder with hemispherical ends)."""

def plot_cone(ax=None, length=1.0, radius=1.0, A2B=np.eye(4), **kwargs):
    """Plot cone."""

def plot_mesh(ax, filename, A2B=np.eye(4), **kwargs):
    """Plot mesh from file."""

# Vector utilities
def plot_vector(ax=None, start=np.zeros(3), direction=np.array([1, 0, 0]), **kwargs):
    """Plot 3D vector."""

def plot_length_variable(ax, start_point, end_point, label, **kwargs):
    """Plot length measurement with label."""

Matplotlib Artist Classes

Reusable artist objects for complex 3D visualizations.

class Arrow3D:
    """3D arrow visualization artist."""
    
class Frame:
    """Coordinate frame visualization artist."""
    
class LabeledFrame:
    """Labeled coordinate frame artist."""
    
class Trajectory:
    """3D trajectory visualization artist."""
    
class Camera:
    """Camera visualization artist."""

Open3D-based Visualization

High-performance 3D rendering using Open3D backend (requires open3d dependency).

def figure(**kwargs):
    """
    Create Open3D-based 3D figure.
    
    Returns:
    - fig: Figure - Open3D figure instance
    """

class Figure:
    """Open3D-based 3D figure for high-performance rendering."""
    
    def add(self, artist):
        """
        Add artist to figure.
        
        Parameters:
        - artist: Artist - 3D artist object
        """
    
    def show(self):
        """Display interactive 3D visualization."""
    
    def plot(self, **kwargs):
        """Configure plot parameters."""

# Open3D Artist classes
class Artist:
    """Base artist class for Open3D rendering."""

class Line3D(Artist):
    """3D line visualization."""

class PointCollection3D(Artist):
    """Point cloud visualization."""

class Vector3D(Artist):
    """3D vector artist."""

class Frame(Artist):
    """Coordinate frame artist."""

class Trajectory(Artist):
    """3D trajectory artist."""

class Camera(Artist):
    """Camera visualization artist."""

class Box(Artist):
    """3D box artist."""

class Sphere(Artist):
    """Sphere artist."""

class Cylinder(Artist):
    """Cylinder artist."""

class Mesh(Artist):
    """Mesh visualization artist."""

class Ellipsoid(Artist):
    """Ellipsoid artist."""

class Capsule(Artist):
    """Capsule artist."""

class Cone(Artist):
    """Cone artist."""

class Plane(Artist):
    """Plane artist."""

class Graph(Artist):
    """Graph structure artist."""

Usage Examples

Basic Transformation Visualization

import numpy as np
import matplotlib.pyplot as plt
import pytransform3d.transformations as pt
import pytransform3d.rotations as pr
from pytransform3d.plot_utils import make_3d_axis, plot_transform

# Create transformations
T1 = pt.transform_from(p=[1, 0, 0])
R2 = pr.matrix_from_euler([0, 0, np.pi/4], "xyz", extrinsic=True)
T2 = pt.transform_from(R=R2, p=[0, 1, 0])
T3 = pt.transform_from(p=[0, 0, 1])

# Plot transformations
ax = make_3d_axis(ax_s=2)

plot_transform(ax=ax, A2B=np.eye(4), s=0.3, label='Origin')
plot_transform(ax=ax, A2B=T1, s=0.3, label='T1')
plot_transform(ax=ax, A2B=T2, s=0.3, label='T2') 
plot_transform(ax=ax, A2B=T3, s=0.3, label='T3')

ax.legend()
plt.show()

Trajectory Visualization

import numpy as np
import matplotlib.pyplot as plt
import pytransform3d.trajectories as ptr
from pytransform3d.plot_utils import make_3d_axis, plot_trajectory

# Generate circular trajectory
n_steps = 50
t = np.linspace(0, 2*np.pi, n_steps)
trajectory = []

for angle in t:
    # Circular motion in x-y plane
    x = np.cos(angle)
    y = np.sin(angle)
    z = 0.1 * angle  # slight upward spiral
    
    # Rotation to keep "forward" direction tangent to circle
    R = pr.matrix_from_euler([0, 0, angle + np.pi/2], "xyz", extrinsic=True)
    T = pt.transform_from(R=R, p=[x, y, z])
    trajectory.append(T)

trajectory = np.array(trajectory)

# Plot trajectory
ax = make_3d_axis(ax_s=2)
plot_trajectory(trajectory, show_direction=True, n_frames=8, s=0.1, ax=ax)

ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()

Geometric Objects

import numpy as np
import matplotlib.pyplot as plt
from pytransform3d.plot_utils import (
    make_3d_axis, plot_box, plot_sphere, plot_cylinder, plot_cone
)
import pytransform3d.transformations as pt

# Create scene with various objects
ax = make_3d_axis(ax_s=3)

# Plot different geometric objects
plot_box(ax=ax, size=[0.5, 0.3, 0.2], 
         A2B=pt.transform_from(p=[0, 0, 0]), 
         alpha=0.7, color='red')

plot_sphere(ax=ax, radius=0.3, p=[1, 0, 0], 
           alpha=0.7, color='green')

plot_cylinder(ax=ax, length=0.8, radius=0.2,
             A2B=pt.transform_from(p=[0, 1, 0]),
             alpha=0.7, color='blue')

plot_cone(ax=ax, length=0.6, radius=0.25,
          A2B=pt.transform_from(p=[1, 1, 0]),
          alpha=0.7, color='yellow')

ax.set_xlabel('X')
ax.set_ylabel('Y') 
ax.set_zlabel('Z')
plt.show()

Robot Visualization

import numpy as np
import matplotlib.pyplot as plt
from pytransform3d.transform_manager import TransformManager
from pytransform3d.plot_utils import make_3d_axis, plot_cylinder, plot_sphere
import pytransform3d.transformations as pt
import pytransform3d.rotations as pr

# Create simple robot arm
tm = TransformManager()

# Base
tm.add_transform("world", "base", pt.transform_from(p=[0, 0, 0.1]))

# First joint (shoulder)
R1 = pr.matrix_from_euler([0, 0, 0.3], "xyz", extrinsic=True)
tm.add_transform("base", "link1", pt.transform_from(R=R1, p=[0, 0, 0.2]))

# Second joint (elbow)
R2 = pr.matrix_from_euler([0, -0.5, 0], "xyz", extrinsic=True)
tm.add_transform("link1", "link2", pt.transform_from(R=R2, p=[0.4, 0, 0]))

# End effector
tm.add_transform("link2", "end_effector", pt.transform_from(p=[0.3, 0, 0]))

# Visualize robot
ax = make_3d_axis(ax_s=1)

# Plot coordinate frames
tm.plot_frames_in("world", ax=ax, s=0.1)
tm.plot_connections_in_frame("world", ax=ax)

# Add geometric representation
# Base cylinder
plot_cylinder(ax=ax, length=0.1, radius=0.05, 
             A2B=tm.get_transform("world", "base"),
             color='gray', alpha=0.8)

# Link 1
T_link1 = tm.get_transform("world", "link1")
link1_T = pt.transform_from(p=[0.2, 0, 0])  # offset for link geometry
plot_cylinder(ax=ax, length=0.4, radius=0.03,
             A2B=pt.concat(T_link1, link1_T),
             color='blue', alpha=0.8)

# Link 2  
T_link2 = tm.get_transform("world", "link2")
link2_T = pt.transform_from(p=[0.15, 0, 0])
plot_cylinder(ax=ax, length=0.3, radius=0.025,
             A2B=pt.concat(T_link2, link2_T),
             color='red', alpha=0.8)

# End effector
T_end = tm.get_transform("world", "end_effector")
plot_sphere(ax=ax, radius=0.03, p=T_end[:3, 3], color='green')

ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()

Open3D High-Performance Visualization

# Note: Requires 'pip install open3d'
try:
    import pytransform3d.visualizer as pv
    import pytransform3d.transformations as pt
    import numpy as np
    
    # Create Open3D figure
    fig = pv.figure()
    
    # Add coordinate frame
    frame = pv.Frame(A2B=np.eye(4), s=0.3)
    fig.add(frame)
    
    # Add trajectory
    trajectory = ptr.random_trajectories(50)
    traj_artist = pv.Trajectory(trajectory)
    fig.add(traj_artist)
    
    # Add geometric objects
    box = pv.Box(size=[0.2, 0.2, 0.2], A2B=pt.transform_from(p=[1, 0, 0]))
    fig.add(box)
    
    sphere = pv.Sphere(radius=0.1, center=[0, 1, 0])
    fig.add(sphere)
    
    # Show interactive visualization
    fig.show()
    
except ImportError:
    print("Open3D not available - install with 'pip install open3d'")

Animation

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from pytransform3d.plot_utils import make_3d_axis, plot_transform
import pytransform3d.transformations as pt
import pytransform3d.rotations as pr

# Set up figure
fig = plt.figure()
ax = make_3d_axis(ax_s=2)

# Animation parameters
n_frames = 100
t_values = np.linspace(0, 4*np.pi, n_frames)

def animate(frame):
    ax.clear()
    ax = make_3d_axis(ax_s=2)
    
    # Create rotating transformation
    angle = t_values[frame]
    R = pr.matrix_from_euler([0, 0, angle], "xyz", extrinsic=True)
    p = [np.cos(angle), np.sin(angle), 0.1*angle]
    T = pt.transform_from(R=R, p=p)
    
    # Plot reference frame and animated frame
    plot_transform(ax=ax, A2B=np.eye(4), s=0.2, alpha=0.5)
    plot_transform(ax=ax, A2B=T, s=0.3)
    
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    ax.set_title(f'Frame: {frame}, Angle: {angle:.2f}')

# Create animation
anim = animation.FuncAnimation(fig, animate, frames=n_frames, interval=50)
plt.show()

# Uncomment to save animation
# anim.save('rotating_frame.gif', writer='pillow', fps=20)

Install with Tessl CLI

npx tessl i tessl/pypi-pytransform3d

docs

batch-operations.md

batch-rotations.md

camera.md

coordinates.md

editor.md

index.md

plot-utils.md

rotations.md

trajectories.md

transform-manager.md

transformations.md

uncertainty.md

urdf.md

visualization.md

tile.json