1 """Various plotting utlities.""" 5 import matplotlib.pyplot
as plt
7 from matplotlib
import patches
8 from mpl_toolkits.mplot3d
import Axes3D
15 Make axes of 3D plot have equal scale so that spheres appear as spheres, 16 cubes as cubes, etc.. This is one possible solution to Matplotlib's 17 ax.set_aspect('equal') and ax.axis('equal') not working for 3D. 20 fignum (int): An integer representing the figure number for Matplotlib. 22 fig = plt.figure(fignum)
23 ax = fig.gca(projection=
'3d')
31 origin = np.mean(limits, axis=1)
32 radius = 0.5 * np.max(np.abs(limits[:, 1] - limits[:, 0]))
34 ax.set_xlim3d([origin[0] - radius, origin[0] + radius])
35 ax.set_ylim3d([origin[1] - radius, origin[1] + radius])
36 ax.set_zlim3d([origin[2] - radius, origin[2] + radius])
41 Numpy equivalent of Matlab's ellipsoid function. 44 rx (double): Radius of ellipsoid in X-axis. 45 ry (double): Radius of ellipsoid in Y-axis. 46 rz (double): Radius of ellipsoid in Z-axis. 47 n (int): The granularity of the ellipsoid plotted. 50 tuple[numpy.ndarray]: The points in the x, y and z axes to use for the surface plot. 52 u = np.linspace(0, 2*np.pi, n+1)
53 v = np.linspace(0, np.pi, n+1)
54 x = -rx * np.outer(np.cos(u), np.sin(v)).T
55 y = -ry * np.outer(np.sin(u), np.sin(v)).T
56 z = -rz * np.outer(np.ones_like(u), np.cos(v)).T
63 Plots a Gaussian as an uncertainty ellipse 65 Based on Maybeck Vol 1, page 366 66 k=2.296 corresponds to 1 std, 68.26% of all probability 67 k=11.82 corresponds to 3 std, 99.74% of all probability 70 axes (matplotlib.axes.Axes): Matplotlib axes. 71 origin (gtsam.Point3): The origin in the world frame. 72 P (numpy.ndarray): The marginal covariance matrix of the 3D point 73 which will be represented as an ellipse. 74 scale (float): Scaling factor of the radii of the covariance ellipse. 75 n (int): Defines the granularity of the ellipse. Higher values indicate finer ellipses. 76 alpha (float): Transparency value for the plotted surface in the range [0, 1]. 79 U, S, _ = np.linalg.svd(P)
81 radii = k * np.sqrt(S)
89 data = np.kron(U[:, 0:1], xc) + np.kron(U[:, 1:2], yc) + \
90 np.kron(U[:, 2:3], zc)
92 x = data[0:n, :] + origin[0]
93 y = data[n:2*n, :] + origin[1]
94 z = data[2*n:, :] + origin[2]
96 axes.plot_surface(x, y, z, alpha=alpha, cmap=
'hot')
101 Plot a 2D pose on given axis `axes` with given `axis_length`. 104 axes (matplotlib.axes.Axes): Matplotlib axes. 105 pose (gtsam.Pose2): The pose to be plotted. 106 axis_length (float): The length of the camera axes. 107 covariance (numpy.ndarray): Marginal covariance matrix to plot 108 the uncertainty of the estimation. 111 gRp = pose.rotation().
matrix()
112 t = pose.translation()
116 x_axis = origin + gRp[:, 0] * axis_length
117 line = np.append(origin[np.newaxis], x_axis[np.newaxis], axis=0)
118 axes.plot(line[:, 0], line[:, 1],
'r-')
120 y_axis = origin + gRp[:, 1] * axis_length
121 line = np.append(origin[np.newaxis], y_axis[np.newaxis], axis=0)
122 axes.plot(line[:, 0], line[:, 1],
'g-')
124 if covariance
is not None:
125 pPp = covariance[0:2, 0:2]
126 gPp = np.matmul(np.matmul(gRp, pPp), gRp.T)
128 w, v = np.linalg.eig(gPp)
133 angle = np.arctan2(v[1, 0], v[0, 0])
134 e1 = patches.Ellipse(origin, np.sqrt(w[0]*k), np.sqrt(w[1]*k),
135 np.rad2deg(angle), fill=
False)
139 def plot_pose2(fignum, pose, axis_length=0.1, covariance=None,
140 axis_labels=(
'X axis',
'Y axis',
'Z axis')):
142 Plot a 2D pose on given figure with given `axis_length`. 145 fignum (int): Integer representing the figure number to use for plotting. 146 pose (gtsam.Pose2): The pose to be plotted. 147 axis_length (float): The length of the camera axes. 148 covariance (numpy.ndarray): Marginal covariance matrix to plot 149 the uncertainty of the estimation. 150 axis_labels (iterable[string]): List of axis labels to set. 153 fig = plt.figure(fignum)
156 covariance=covariance)
158 axes.set_xlabel(axis_labels[0])
159 axes.set_ylabel(axis_labels[1])
166 Plot a 3D point on given axis `axes` with given `linespec`. 169 axes (matplotlib.axes.Axes): Matplotlib axes. 170 point (gtsam.Point3): The point to be plotted. 171 linespec (string): String representing formatting options for Matplotlib. 172 P (numpy.ndarray): Marginal covariance matrix to plot the uncertainty of the estimation. 174 axes.plot([point[0]], [point[1]], [point[2]], linespec)
180 axis_labels=(
'X axis',
'Y axis',
'Z axis')):
182 Plot a 3D point on given figure with given `linespec`. 185 fignum (int): Integer representing the figure number to use for plotting. 186 point (gtsam.Point3): The point to be plotted. 187 linespec (string): String representing formatting options for Matplotlib. 188 P (numpy.ndarray): Marginal covariance matrix to plot the uncertainty of the estimation. 189 axis_labels (iterable[string]): List of axis labels to set. 192 fig: The matplotlib figure. 195 fig = plt.figure(fignum)
196 axes = fig.gca(projection=
'3d')
199 axes.set_xlabel(axis_labels[0])
200 axes.set_ylabel(axis_labels[1])
201 axes.set_zlabel(axis_labels[2])
207 title=
"3D Points", axis_labels=(
'X axis',
'Y axis',
'Z axis')):
209 Plots the Point3s in `values`, with optional covariances. 210 Finds all the Point3 objects in the given Values object and plots them. 211 If a Marginals object is given, this function will also plot marginal 212 covariance ellipses for each point. 215 fignum (int): Integer representing the figure number to use for plotting. 216 values (gtsam.Values): Values dictionary consisting of points to be plotted. 217 linespec (string): String representing formatting options for Matplotlib. 218 marginals (numpy.ndarray): Marginal covariance matrix to plot the 219 uncertainty of the estimation. 220 title (string): The title of the plot. 221 axis_labels (iterable[string]): List of axis labels to set. 229 point = values.atPoint3(key)
230 if marginals
is not None:
231 covariance = marginals.marginalCovariance(key)
235 fig =
plot_point3(fignum, point, linespec, covariance,
236 axis_labels=axis_labels)
242 fig = plt.figure(fignum)
244 fig.canvas.set_window_title(title.lower())
249 Plot a 3D pose on given axis `axes` with given `axis_length`. 252 axes (matplotlib.axes.Axes): Matplotlib axes. 253 point (gtsam.Point3): The point to be plotted. 254 linespec (string): String representing formatting options for Matplotlib. 255 P (numpy.ndarray): Marginal covariance matrix to plot the uncertainty of the estimation. 258 gRp = pose.rotation().
matrix()
259 origin = pose.translation()
262 x_axis = origin + gRp[:, 0] * axis_length
263 line = np.append(origin[np.newaxis], x_axis[np.newaxis], axis=0)
264 axes.plot(line[:, 0], line[:, 1], line[:, 2],
'r-')
266 y_axis = origin + gRp[:, 1] * axis_length
267 line = np.append(origin[np.newaxis], y_axis[np.newaxis], axis=0)
268 axes.plot(line[:, 0], line[:, 1], line[:, 2],
'g-')
270 z_axis = origin + gRp[:, 2] * axis_length
271 line = np.append(origin[np.newaxis], z_axis[np.newaxis], axis=0)
272 axes.plot(line[:, 0], line[:, 1], line[:, 2],
'b-')
279 gPp = gRp @ pPp @ gRp.T
283 def plot_pose3(fignum, pose, axis_length=0.1, P=None,
284 axis_labels=(
'X axis',
'Y axis',
'Z axis')):
286 Plot a 3D pose on given figure with given `axis_length`. 289 fignum (int): Integer representing the figure number to use for plotting. 290 pose (gtsam.Pose3): 3D pose to be plotted. 291 linespec (string): String representing formatting options for Matplotlib. 292 P (numpy.ndarray): Marginal covariance matrix to plot the uncertainty of the estimation. 293 axis_labels (iterable[string]): List of axis labels to set. 296 fig: The matplotlib figure. 299 fig = plt.figure(fignum)
300 axes = fig.gca(projection=
'3d')
302 axis_length=axis_length)
304 axes.set_xlabel(axis_labels[0])
305 axes.set_ylabel(axis_labels[1])
306 axes.set_zlabel(axis_labels[2])
312 title=
"Plot Trajectory", axis_labels=(
'X axis',
'Y axis',
'Z axis')):
314 Plot a complete 2D/3D trajectory using poses in `values`. 317 fignum (int): Integer representing the figure number to use for plotting. 318 values (gtsam.Values): Values containing some Pose2 and/or Pose3 values. 319 scale (float): Value to scale the poses by. 320 marginals (gtsam.Marginals): Marginalized probability values of the estimation. 321 Used to plot uncertainty bounds. 322 title (string): The title of the plot. 323 axis_labels (iterable[string]): List of axis labels to set. 325 fig = plt.figure(fignum)
326 axes = fig.gca(projection=
'3d')
328 axes.set_xlabel(axis_labels[0])
329 axes.set_ylabel(axis_labels[1])
330 axes.set_zlabel(axis_labels[2])
334 for key
in poses.keys():
335 pose = poses.atPose2(key)
337 covariance = marginals.marginalCovariance(key)
346 for key
in poses.keys():
347 pose = poses.atPose3(key)
349 covariance = marginals.marginalCovariance(key)
357 fig.canvas.set_window_title(title.lower())
361 scale=1, marginals=
None,
364 Incrementally plot a complete 3D trajectory using poses in `values`. 367 fignum (int): Integer representing the figure number to use for plotting. 368 values (gtsam.Values): Values dict containing the poses. 369 start (int): Starting index to start plotting from. 370 scale (float): Value to scale the poses by. 371 marginals (gtsam.Marginals): Marginalized probability values of the estimation. 372 Used to plot uncertainty bounds. 373 time_interval (float): Time in seconds to pause between each rendering. 374 Used to create animation effect. 376 fig = plt.figure(fignum)
377 axes = fig.gca(projection=
'3d')
382 for key
in keys[start:]:
383 if values.exists(key):
384 pose_i = values.atPose3(key)
394 plt.pause(time_interval)
def plot_incremental_trajectory(fignum, values, start=0, scale=1, marginals=None, time_interval=0.0)
def plot_3d_points(fignum, values, linespec="g*", marginals=None, title="3D Points", axis_labels=('X axis', 'Y axis', 'Z axis'))
def plot_pose3_on_axes(axes, pose, axis_length=0.1, P=None, scale=1)
def plot_trajectory(fignum, values, scale=1, marginals=None, title="Plot Trajectory", axis_labels=('X axis', 'Y axis', 'Z axis'))
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
def ellipsoid(rx, ry, rz, n)
def plot_covariance_ellipse_3d(axes, origin, P, scale=1, n=8, alpha=0.5)
def plot_pose2(fignum, pose, axis_length=0.1, covariance=None, axis_labels=('X axis', 'Y axis', 'Z axis'))
def set_axes_equal(fignum)
Values allPose3s(const Values &values)
Extract all Pose3 values.
Values allPose2s(const Values &values)
Extract all Pose3 values.
def plot_pose3(fignum, pose, axis_length=0.1, P=None, axis_labels=('X axis', 'Y axis', 'Z axis'))
def plot_pose2_on_axes(axes, pose, axis_length=0.1, covariance=None)
Map< Matrix< T, Dynamic, Dynamic, ColMajor >, 0, OuterStride<> > matrix(T *data, int rows, int cols, int stride)
def plot_point3(fignum, point, linespec, P=None, axis_labels=('X axis', 'Y axis', 'Z axis'))
def plot_point3_on_axes(axes, point, linespec, P=None)