Skip to content

Commit 0af4b42

Browse files
committed
Add options for stack plot, angle unwrapping, grid
1 parent 3512286 commit 0af4b42

File tree

1 file changed

+61
-25
lines changed

1 file changed

+61
-25
lines changed

roboticstoolbox/tools/trajectory.py

Lines changed: 61 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -614,29 +614,43 @@ def mtraj(tfunc, q0, qf, t):
614614
return Trajectory('mtraj', x, y, yd, ydd, istime)
615615

616616

617-
def qplot(x, y=None, arm=False, block=False, labels=None):
617+
def qplot(x, y=None, wrist=False, unwrap=False, block=False, labels=None,
618+
loc=None, grid=True, stack=False, **kwargs):
618619
"""
619-
Plot robot joint angles
620+
Plot trajectory data
620621
621-
:param q: joint angle trajectory
622-
:type q: numpy ndarray, shape=(M,N)
622+
:param q: trajectory, one row per timestep
623+
:type q: ndarray(m,n)
623624
:param t: time vector, optional
624625
:type t: numpy ndarray, shape=(M,)
625-
:param arm: distinguish arm and wrist joints with line styles, default False
626-
:type arm: bool
627-
628-
This is a convenience function to plot joint angle trajectories (MxN) for
629-
an N-axis robot, where each row represents one time step.
626+
:param wrist: distinguish arm and wrist joints with line styles
627+
:type wrist: bool
628+
:param unwrap: unwrap joint angles so that they smoothly increase or
629+
decrease when they pass through :math:`\pm \pi`
630+
:type unwrap: bool
631+
:param block: block until the plot is closed
632+
:type block: bool
633+
:param labels: legend labels
634+
:type labels: list of str, or single string with space separated labels
635+
:param kwargs: options passed to pyplot.plot
636+
:param loc: legend location as per pyplot.legend
637+
:type loc: str
638+
639+
This is a convenience function to plot trajectories, where each row represents one time step.
630640
631641
- ``qplot(q)`` plots the joint angles versus row number. If N==6 a
632642
conventional 6-axis robot is assumed, and the first three joints are
633643
shown as solid lines, the last three joints (wrist) are shown as dashed
634644
lines. A legend is also displayed.
635645
636-
- ``qplot(q, t)`` as above but displays the joint angle trajectory versus
646+
- ``qplot(t, q)`` as above but displays the joint angle trajectory versus
637647
time given the time vector T (Mx1).
638648
639-
:seealso: :func:`jtraj`
649+
Example::
650+
651+
>>> qplot(q, x, labels='x y z')
652+
653+
:seealso: :func:`jtraj`, :func:`numpy.unwrap`
640654
"""
641655
if y is None:
642656
q = x
@@ -648,28 +662,50 @@ def qplot(x, y=None, arm=False, block=False, labels=None):
648662
if t.ndim != 1 or q.shape[0] != t.shape[0]:
649663
raise ValueError('dimensions of arguments are not consistent')
650664

665+
if unwrap:
666+
q = np.unwrap(q, axis=0)
667+
651668
n = q.shape[1]
652-
fig, ax = plt.subplots()
653-
if n == 6 and arm:
654-
plt.plot(t, q[:, 0:3])
655-
plt.plot(t, q[:, 3:6], '--')
656-
else:
657-
plt.plot(t, q)
658669

659670
if labels is None:
660-
ax.legend([f"q{i+1}" for i in range(n)])
671+
labels = [f"q{i}" for i in range(n)]
661672
elif isinstance(labels, str):
662-
ax.legend(labels.split(' '))
663-
elif isinstance(labels, (tuple, list)):
664-
ax.legend(labels)
673+
labels = labels.split(' ')
674+
elif not isinstance(labels, (tuple, list)):
675+
raise TypeError('wrong type for labels')
676+
677+
678+
fig, ax = plt.subplots()
679+
680+
if stack:
681+
for i in range(n):
682+
ax = plt.subplot(n, 1, i + 1)
683+
684+
plt.plot(t, q[:, i], **kwargs)
685+
686+
plt.grid(grid)
687+
ax.set_ylabel(labels[i])
688+
ax.set_xlim(t[0], t[-1])
689+
690+
ax.set_xlabel('Time (s)')
691+
692+
else:
693+
if n == 6 and wrist:
694+
plt.plot(t, q[:, 0:3], **kwargs)
695+
plt.plot(t, q[:, 3:6], '--', **kwargs)
696+
else:
697+
plt.plot(t, q, **kwargs)
665698

666-
plt.grid(True)
667-
ax.set_xlabel('Time (s)')
668-
ax.set_ylabel('Joint coordinates (rad,m)')
669-
ax.set_xlim(t[0], t[-1])
699+
ax.legend(labels, loc=loc)
700+
701+
plt.grid(grid)
702+
ax.set_xlabel('Time (s)')
703+
ax.set_ylabel('Joint coordinates (rad,m)')
704+
ax.set_xlim(t[0], t[-1])
670705

671706
plt.show(block=block)
672707

708+
return fig.get_axes()
673709

674710
# -------------------------------------------------------------------------- #
675711

0 commit comments

Comments
 (0)