PlotJuggler Time Offset: Align Signals That Start at Different Times

Two signals, two clocks, two start buttons pressed a second apart — and a plot that insists your systems disagreed when they actually agreed perfectly, just not simultaneously. Time offset is PlotJuggler’s answer: shift a curve (in PJ3) or a whole dataset (in PJ4) along the time axis until events that happened together line up together. The GSC queries behind this tutorial — time offset, time shift, aligning signals — all describe the same underlying need. This guide explains the concept, including the T=0 idea, then gives a careful alignment workflow. Related: comparing multiple bag files and the Tutorials hub.

The problem, precisely

A time offset problem exists when the relative timing inside each recording is correct, but the recordings (or signals) do not share a common zero. Each file is honest about its own timeline; they simply started counting at different moments — a logger armed before the controller booted, a bag recorded a breath after the test rig’s CSV export began. No amount of zooming fixes that, because the data itself needs to move. That is what an offset does: it adds a constant shift to a timeline, leaving every interval inside the recording untouched. If intervals themselves are stretched or drifting, you have a clock-rate problem instead — offsets will align one event and misalign the rest, which is exactly the diagnostic the verification step below exploits.

The T=0 concept

Alignment needs a reference. The PJ3 interface expresses this with a “T=0” time-offset control: in effect, you declare which moment counts as zero, and the curves are viewed relative to it. The mental model generalises to both generations: pick one event as the anchor — the instant the test truly began — and express everything else relative to that anchor. PJ4 formalises the same idea at the dataset level: its layouts and views work with per-dataset time offsets, one shift per loaded recording, stored in the layout (schema v4) together with the viewport. PJ3’s offsets, by contrast, are applied per curve. Same goal, different granularity — and the granularity matters when a recording holds thirty signals you need to move together.

Step-by-step: aligning two signals

  1. Load both signals and plot them together. Overlay is essential — you cannot align what you cannot see together. The loading workflows are in Getting Started and the bag and MCAP tutorial.
  2. Choose a reference event that exists in both. The best anchors are sharp and unambiguous: a step command and its response, a mode switch, a distinctive spike. Slow ramps and periodic waves make poor anchors — a repeating wave aligns at every period, most of them wrong.
  3. Measure the gap. Read the event’s time in the first signal and in the second. The difference is your candidate offset. (Illustrative numbers: if the step appears at 14.2 s in one recording and 15.0 s in the other, the second recording’s timeline needs to move 0.8 s earlier to coincide.)
  4. Apply the offset to the late signal. In PJ3, apply the time shift to the curve; in PJ4, set the dataset’s offset so the whole recording moves as one. Direction matters: you are moving the late recording earlier (or, equivalently, delaying the early one) — if the gap doubles instead of closing, you shifted the wrong way; undo and reverse the sign.
  5. Verify on a second, independent event. Find a different event later in the recording and check it also lines up. One event can always be forced into alignment; two events aligning after a single constant shift is real evidence the offset is right.
  6. Save the layout. An alignment you do not save is an alignment you will redo. Layouts are covered in Saving and Sharing PlotJuggler Layouts — and in PJ4 the offsets themselves are part of what the layout stores.

Per-curve or per-dataset: which are you moving?

SituationRight toolWhy
Two recordings of the same rig, started at different momentsPer-dataset offset (PJ4) or per-curve shifts applied uniformly (PJ3)The whole recording shares one wrong zero; move it as a unit so internal timing is preserved by construction
One sensor in a single recording lags the others (a delayed topic, a buffered device)Per-curve offsetOnly that signal is displaced; shifting everything else would break the signals that were right
Comparing runs for a fair overlayPer-dataset offset, aligned on a shared eventThis is the alignment step inside the multiple-bag comparison workflow

Pitfalls worth knowing

  • Aligning on a periodic signal. A sine wave matches itself every period. Anchor on an aperiodic event, then use the wave only as a fine check.
  • Chasing drift with offsets. If event one aligns and event two, minutes later, does not — with the error growing over time — the clocks ran at different rates. A constant offset cannot fix drift; align near the interval you are analysing and say so in your notes.
  • Forgetting the offset is active. An offset left on a curve makes later absolute-time readings wrong. Note offsets in the layout name or your test log, especially when sharing the layout with colleagues.
  • Over-aligning noise. On noisy signals, align on the feature (the step, the edge), not on the nearest noise peak.

Master this one control and two other tutorials unlock: fair multi-recording comparisons and meaningful XY plots between signals recorded together. The rest of the series is on the Tutorials hub; the program and its checksums are on the Download page.

Similar Posts