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
- 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.
- 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.
- 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.)
- 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.
- 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.
- 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?
| Situation | Right tool | Why |
|---|---|---|
| Two recordings of the same rig, started at different moments | Per-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 offset | Only that signal is displaced; shifting everything else would break the signals that were right |
| Comparing runs for a fair overlay | Per-dataset offset, aligned on a shared event | This 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.
