Every plot so far has put time on the horizontal axis. An XY plot asks a different question: not “how did this signal evolve?” but “how do these two signals relate?” — position against position, output against input, one joint against another. XY plots are a long-standing PlotJuggler feature in PJ3, and PJ4 keeps them at the centre of its workflow — you drag signals into time-series and XY plots. This tutorial shows how to build one, what to use it for, and how to read what it draws. It builds on Getting Started; the whole series is on the Tutorials hub.
Time plot vs XY plot: the one idea
In a time plot, each curve is a function of time: at every timestamp, a value. In an XY plot, time steps aside and becomes the invisible parameter that walks the point along its path: the horizontal position comes from one signal (X), the vertical position from another (Y), and each timestamp contributes one point. Connect the points in time order and the plot draws the path of the relationship itself — a trajectory through the space the two signals define. That is why XY plots reveal things time plots hide: loops, limits, dead zones and phase differences become shapes you can see at a glance, instead of two wiggly lines you must mentally correlate.
Step-by-step: your first XY plot
- Load data with at least two related numeric signals. A CSV with two position columns, or a bag with a robot’s x and y fields, is ideal. Loading is the usual drag-and-drop workflow from Getting Started or the CSV tutorial.
- Create an XY view of the data. PlotJuggler’s workflow is drag-based in both generations: you build an XY plot by bringing the two chosen signals into an XY plotting area, designating which signal plays the X role and which plays the Y role. X is the reference — the signal you want to read the other “against”.
- Check the pairing makes sense. Both signals must describe the same moments. Signals recorded together in one file pair naturally; signals from different files need their timelines aligned first — that is the time offset workflow, and skipping it is the main way XY plots lie.
- Read the path, then zoom. The whole-recording view shows the overall shape; zoom into a section of interest to inspect a single manoeuvre, limit cycle or excursion in detail, exactly as you would on a time plot.
- Save the arrangement. If the pairing answers a recurring question, capture it in a layout alongside your time plots — the two views side by side are worth more than either alone.
Three jobs XY plots do better than time plots
| Job | X and Y | What the shape tells you |
|---|---|---|
| Trajectory | X = x-position, Y = y-position | The actual path travelled, drawn to scale: missed waypoints, overshoot at corners, and drift appear as geometry, not as two separate wiggles |
| Phase / relationship | X = reference or input signal, Y = response or output signal | A clean proportional response draws a straight line; lag draws a loop whose width grows with the delay; saturation flattens the ends; a dead zone flattens the middle |
| Joint / state space | X = one joint or state, Y = another joint or state | Coordination between the two — which leads, which follows, and whether the pair traces the same path in both directions or encloses a hysteresis loop |
How to read what it draws
- Straight diagonal line: the signals are proportional. The slope is the ratio between them — a calibration error often shows up here before it shows up anywhere else.
- Closed loop: the pair returns to its start with Y lagging or leading X. Loop area grows with phase difference; a loop in a position-vs-position plot is simply a closed path travelled.
- Loop that does not close: the system drifted during the recording — the end state differs from the start state. Compare with the time plot to find when.
- dense scribble in one region: the system spent most of its time there — dwell, oscillation around a setpoint, or noise dominating a near-constant signal.
- Direction matters: the path is traced in time order. Where the story is ambiguous, drop back to the time plot for the same interval and read the two views together.
Combining XY with the rest of the toolkit
XY plots get stronger with derived signals. Plot velocity against position by first computing the velocity with the built-in derivative transform, or define a combined quantity with a Lua custom function and use its output as an axis. Compare two runs by building the same XY view for each recording — the multiple-recording comparison workflow — and aligning their timelines first so the pairings are honest. In PJ4, XY plots also sit next to the new video and 3D views on the same timeline, so the abstract relationship and the physical scene can be inspected in the same pass.
Limits, honestly stated
An XY plot is only as trustworthy as the pairing behind it: mismatched sample times, unaligned recordings and signals in different units all produce confident-looking nonsense. It also discards time as an axis — when “when” is the question, the time plot is still the right tool. Used for the questions it suits, though, it is the fastest diagnostic in this entire series: one picture, and the relationship is either healthy or it is not. Continue with Lua custom functions to build the derived axes you just read about, or return to the Tutorials hub for the full path. If PlotJuggler is not installed yet, the Install guides and the Download page will get you there first.
