or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

batch-operations.mdbatch-rotations.mdcamera.mdcoordinates.mdeditor.mdindex.mdplot-utils.mdrotations.mdtrajectories.mdtransform-manager.mdtransformations.mduncertainty.mdurdf.mdvisualization.md

visualization.mddocs/

0

# Visualization

1

2

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

3

4

## Capabilities

5

6

### Matplotlib-based Visualization

7

8

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

9

10

```python { .api }

11

# Layout functions

12

def make_3d_axis(ax_s=1, pos=111, unit=None, n_ticks=5, **kwargs):

13

"""

14

Create 3D matplotlib axis with proper scaling.

15

16

Parameters:

17

- ax_s: float - Axis scaling factor

18

- pos: int - Subplot position

19

- unit: str, optional - Axis unit label

20

- n_ticks: int - Number of axis ticks

21

22

Returns:

23

- ax: Axes3D - Configured 3D axis

24

"""

25

26

def remove_frame(ax):

27

"""Remove frame decorations from 3D axis."""

28

29

# Transformation plotting

30

def plot_transform(ax=None, A2B=None, s=1.0, ax_s=1, **kwargs):

31

"""

32

Plot transformation as coordinate frame.

33

34

Parameters:

35

- ax: Axes3D, optional - 3D axis

36

- A2B: array, shape (4, 4), optional - Transformation matrix

37

- s: float - Frame size scaling

38

- ax_s: float - Axis scaling

39

"""

40

41

def plot_screw(ax=None, q=None, s_axis=None, h=None, theta=None, s=1.0, ax_s=1, **kwargs):

42

"""Plot screw motion visualization."""

43

44

def plot_trajectory(P=None, show_direction=True, n_frames=10, s=1.0, ax=None, **kwargs):

45

"""

46

Plot 3D trajectory with direction indicators.

47

48

Parameters:

49

- P: array, shape (n_steps, 3 or 4, 4) - Trajectory as transforms or positions

50

- show_direction: bool - Show trajectory direction arrows

51

- n_frames: int - Number of coordinate frames to show

52

- s: float - Frame size scaling

53

- ax: Axes3D, optional - 3D axis

54

"""

55

56

# Geometry plotting

57

def plot_box(ax=None, size=[1, 1, 1], A2B=np.eye(4), **kwargs):

58

"""Plot 3D box."""

59

60

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

61

"""Plot sphere."""

62

63

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

64

"""Plot cylinder."""

65

66

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

67

"""Plot ellipsoid."""

68

69

def plot_capsule(ax=None, height=1.0, radius=1.0, A2B=np.eye(4), **kwargs):

70

"""Plot capsule (cylinder with hemispherical ends)."""

71

72

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

73

"""Plot cone."""

74

75

def plot_mesh(ax, filename, A2B=np.eye(4), **kwargs):

76

"""Plot mesh from file."""

77

78

# Vector utilities

79

def plot_vector(ax=None, start=np.zeros(3), direction=np.array([1, 0, 0]), **kwargs):

80

"""Plot 3D vector."""

81

82

def plot_length_variable(ax, start_point, end_point, label, **kwargs):

83

"""Plot length measurement with label."""

84

```

85

86

### Matplotlib Artist Classes

87

88

Reusable artist objects for complex 3D visualizations.

89

90

```python { .api }

91

class Arrow3D:

92

"""3D arrow visualization artist."""

93

94

class Frame:

95

"""Coordinate frame visualization artist."""

96

97

class LabeledFrame:

98

"""Labeled coordinate frame artist."""

99

100

class Trajectory:

101

"""3D trajectory visualization artist."""

102

103

class Camera:

104

"""Camera visualization artist."""

105

```

106

107

### Open3D-based Visualization

108

109

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

110

111

```python { .api }

112

def figure(**kwargs):

113

"""

114

Create Open3D-based 3D figure.

115

116

Returns:

117

- fig: Figure - Open3D figure instance

118

"""

119

120

class Figure:

121

"""Open3D-based 3D figure for high-performance rendering."""

122

123

def add(self, artist):

124

"""

125

Add artist to figure.

126

127

Parameters:

128

- artist: Artist - 3D artist object

129

"""

130

131

def show(self):

132

"""Display interactive 3D visualization."""

133

134

def plot(self, **kwargs):

135

"""Configure plot parameters."""

136

137

# Open3D Artist classes

138

class Artist:

139

"""Base artist class for Open3D rendering."""

140

141

class Line3D(Artist):

142

"""3D line visualization."""

143

144

class PointCollection3D(Artist):

145

"""Point cloud visualization."""

146

147

class Vector3D(Artist):

148

"""3D vector artist."""

149

150

class Frame(Artist):

151

"""Coordinate frame artist."""

152

153

class Trajectory(Artist):

154

"""3D trajectory artist."""

155

156

class Camera(Artist):

157

"""Camera visualization artist."""

158

159

class Box(Artist):

160

"""3D box artist."""

161

162

class Sphere(Artist):

163

"""Sphere artist."""

164

165

class Cylinder(Artist):

166

"""Cylinder artist."""

167

168

class Mesh(Artist):

169

"""Mesh visualization artist."""

170

171

class Ellipsoid(Artist):

172

"""Ellipsoid artist."""

173

174

class Capsule(Artist):

175

"""Capsule artist."""

176

177

class Cone(Artist):

178

"""Cone artist."""

179

180

class Plane(Artist):

181

"""Plane artist."""

182

183

class Graph(Artist):

184

"""Graph structure artist."""

185

```

186

187

## Usage Examples

188

189

### Basic Transformation Visualization

190

191

```python

192

import numpy as np

193

import matplotlib.pyplot as plt

194

import pytransform3d.transformations as pt

195

import pytransform3d.rotations as pr

196

from pytransform3d.plot_utils import make_3d_axis, plot_transform

197

198

# Create transformations

199

T1 = pt.transform_from(p=[1, 0, 0])

200

R2 = pr.matrix_from_euler([0, 0, np.pi/4], "xyz", extrinsic=True)

201

T2 = pt.transform_from(R=R2, p=[0, 1, 0])

202

T3 = pt.transform_from(p=[0, 0, 1])

203

204

# Plot transformations

205

ax = make_3d_axis(ax_s=2)

206

207

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

208

plot_transform(ax=ax, A2B=T1, s=0.3, label='T1')

209

plot_transform(ax=ax, A2B=T2, s=0.3, label='T2')

210

plot_transform(ax=ax, A2B=T3, s=0.3, label='T3')

211

212

ax.legend()

213

plt.show()

214

```

215

216

### Trajectory Visualization

217

218

```python

219

import numpy as np

220

import matplotlib.pyplot as plt

221

import pytransform3d.trajectories as ptr

222

from pytransform3d.plot_utils import make_3d_axis, plot_trajectory

223

224

# Generate circular trajectory

225

n_steps = 50

226

t = np.linspace(0, 2*np.pi, n_steps)

227

trajectory = []

228

229

for angle in t:

230

# Circular motion in x-y plane

231

x = np.cos(angle)

232

y = np.sin(angle)

233

z = 0.1 * angle # slight upward spiral

234

235

# Rotation to keep "forward" direction tangent to circle

236

R = pr.matrix_from_euler([0, 0, angle + np.pi/2], "xyz", extrinsic=True)

237

T = pt.transform_from(R=R, p=[x, y, z])

238

trajectory.append(T)

239

240

trajectory = np.array(trajectory)

241

242

# Plot trajectory

243

ax = make_3d_axis(ax_s=2)

244

plot_trajectory(trajectory, show_direction=True, n_frames=8, s=0.1, ax=ax)

245

246

ax.set_xlabel('X')

247

ax.set_ylabel('Y')

248

ax.set_zlabel('Z')

249

plt.show()

250

```

251

252

### Geometric Objects

253

254

```python

255

import numpy as np

256

import matplotlib.pyplot as plt

257

from pytransform3d.plot_utils import (

258

make_3d_axis, plot_box, plot_sphere, plot_cylinder, plot_cone

259

)

260

import pytransform3d.transformations as pt

261

262

# Create scene with various objects

263

ax = make_3d_axis(ax_s=3)

264

265

# Plot different geometric objects

266

plot_box(ax=ax, size=[0.5, 0.3, 0.2],

267

A2B=pt.transform_from(p=[0, 0, 0]),

268

alpha=0.7, color='red')

269

270

plot_sphere(ax=ax, radius=0.3, p=[1, 0, 0],

271

alpha=0.7, color='green')

272

273

plot_cylinder(ax=ax, length=0.8, radius=0.2,

274

A2B=pt.transform_from(p=[0, 1, 0]),

275

alpha=0.7, color='blue')

276

277

plot_cone(ax=ax, length=0.6, radius=0.25,

278

A2B=pt.transform_from(p=[1, 1, 0]),

279

alpha=0.7, color='yellow')

280

281

ax.set_xlabel('X')

282

ax.set_ylabel('Y')

283

ax.set_zlabel('Z')

284

plt.show()

285

```

286

287

### Robot Visualization

288

289

```python

290

import numpy as np

291

import matplotlib.pyplot as plt

292

from pytransform3d.transform_manager import TransformManager

293

from pytransform3d.plot_utils import make_3d_axis, plot_cylinder, plot_sphere

294

import pytransform3d.transformations as pt

295

import pytransform3d.rotations as pr

296

297

# Create simple robot arm

298

tm = TransformManager()

299

300

# Base

301

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

302

303

# First joint (shoulder)

304

R1 = pr.matrix_from_euler([0, 0, 0.3], "xyz", extrinsic=True)

305

tm.add_transform("base", "link1", pt.transform_from(R=R1, p=[0, 0, 0.2]))

306

307

# Second joint (elbow)

308

R2 = pr.matrix_from_euler([0, -0.5, 0], "xyz", extrinsic=True)

309

tm.add_transform("link1", "link2", pt.transform_from(R=R2, p=[0.4, 0, 0]))

310

311

# End effector

312

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

313

314

# Visualize robot

315

ax = make_3d_axis(ax_s=1)

316

317

# Plot coordinate frames

318

tm.plot_frames_in("world", ax=ax, s=0.1)

319

tm.plot_connections_in_frame("world", ax=ax)

320

321

# Add geometric representation

322

# Base cylinder

323

plot_cylinder(ax=ax, length=0.1, radius=0.05,

324

A2B=tm.get_transform("world", "base"),

325

color='gray', alpha=0.8)

326

327

# Link 1

328

T_link1 = tm.get_transform("world", "link1")

329

link1_T = pt.transform_from(p=[0.2, 0, 0]) # offset for link geometry

330

plot_cylinder(ax=ax, length=0.4, radius=0.03,

331

A2B=pt.concat(T_link1, link1_T),

332

color='blue', alpha=0.8)

333

334

# Link 2

335

T_link2 = tm.get_transform("world", "link2")

336

link2_T = pt.transform_from(p=[0.15, 0, 0])

337

plot_cylinder(ax=ax, length=0.3, radius=0.025,

338

A2B=pt.concat(T_link2, link2_T),

339

color='red', alpha=0.8)

340

341

# End effector

342

T_end = tm.get_transform("world", "end_effector")

343

plot_sphere(ax=ax, radius=0.03, p=T_end[:3, 3], color='green')

344

345

ax.set_xlabel('X')

346

ax.set_ylabel('Y')

347

ax.set_zlabel('Z')

348

plt.show()

349

```

350

351

### Open3D High-Performance Visualization

352

353

```python

354

# Note: Requires 'pip install open3d'

355

try:

356

import pytransform3d.visualizer as pv

357

import pytransform3d.transformations as pt

358

import numpy as np

359

360

# Create Open3D figure

361

fig = pv.figure()

362

363

# Add coordinate frame

364

frame = pv.Frame(A2B=np.eye(4), s=0.3)

365

fig.add(frame)

366

367

# Add trajectory

368

trajectory = ptr.random_trajectories(50)

369

traj_artist = pv.Trajectory(trajectory)

370

fig.add(traj_artist)

371

372

# Add geometric objects

373

box = pv.Box(size=[0.2, 0.2, 0.2], A2B=pt.transform_from(p=[1, 0, 0]))

374

fig.add(box)

375

376

sphere = pv.Sphere(radius=0.1, center=[0, 1, 0])

377

fig.add(sphere)

378

379

# Show interactive visualization

380

fig.show()

381

382

except ImportError:

383

print("Open3D not available - install with 'pip install open3d'")

384

```

385

386

### Animation

387

388

```python

389

import numpy as np

390

import matplotlib.pyplot as plt

391

import matplotlib.animation as animation

392

from pytransform3d.plot_utils import make_3d_axis, plot_transform

393

import pytransform3d.transformations as pt

394

import pytransform3d.rotations as pr

395

396

# Set up figure

397

fig = plt.figure()

398

ax = make_3d_axis(ax_s=2)

399

400

# Animation parameters

401

n_frames = 100

402

t_values = np.linspace(0, 4*np.pi, n_frames)

403

404

def animate(frame):

405

ax.clear()

406

ax = make_3d_axis(ax_s=2)

407

408

# Create rotating transformation

409

angle = t_values[frame]

410

R = pr.matrix_from_euler([0, 0, angle], "xyz", extrinsic=True)

411

p = [np.cos(angle), np.sin(angle), 0.1*angle]

412

T = pt.transform_from(R=R, p=p)

413

414

# Plot reference frame and animated frame

415

plot_transform(ax=ax, A2B=np.eye(4), s=0.2, alpha=0.5)

416

plot_transform(ax=ax, A2B=T, s=0.3)

417

418

ax.set_xlabel('X')

419

ax.set_ylabel('Y')

420

ax.set_zlabel('Z')

421

ax.set_title(f'Frame: {frame}, Angle: {angle:.2f}')

422

423

# Create animation

424

anim = animation.FuncAnimation(fig, animate, frames=n_frames, interval=50)

425

plt.show()

426

427

# Uncomment to save animation

428

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

429

```