Custom transforms are how PlotJuggler turns raw logged data into the series you actually want to look at — a derived value computed from one or more recorded series. PlotJuggler 3’s Custom Function Editor made those transforms a Lua-only affair. PlotJuggler 4, first in the 3.999.9 preview (10 August 2026) and then in 4.0.0, adds Python scripting as an alternative to Lua for derived series. This guide explains what that means in practice, when each language is the better choice, and the workflow — without inventing API documentation the project has not published. Context: the PlotJuggler 4 hub; downloads on the Download page.
What a custom transform is (and still is)
The concept is unchanged from PJ3. You select existing series as inputs, describe the computation, and PlotJuggler produces a new, derived series that behaves like any other curve: you can plot it, overlay it, apply further filters (derivative, integral, FFT and friends) and save it as part of your layout — PJ4 saves layouts and transforms together. The classic example from the PX4 world is converting a quaternion attitude into roll, pitch and yaw series. In PJ3 that meant writing a Lua function — multi-input, single-output — in the built-in editor. In PJ4 you can still do exactly that in Lua, or write the transform in Python instead.
What Python changes — and what it does not
Python in PJ4 is an alternative expression language for the same feature, not a different feature. It does not replace Lua, and existing Lua transforms and Lua knowledge remain valid in PJ4. The project’s own 3.999.9 release notes phrase it precisely that way: “Python scripting as alternative to Lua”. What changes is who can write transforms comfortably, and in what language a team can maintain them: a robotics or data team that already lives in Python no longer has to context-switch into Lua for one tool in the chain. What does not magically change: you still design the same computation — same inputs, same derived output — and you still validate the result against data you understand before trusting it.
The workflow, step by step
- Load your data in PlotJuggler 4 — a CSV, ULog, MCAP or any other supported source — and confirm the input series you need are present.
- Create a custom transform for a derived series and choose the scripting language: Python for a new transform written by a Python-fluent team, Lua if you are porting or reusing an existing one.
- Write the computation against the input series: the transform reads the inputs sample by sample and emits the derived value for each timestamp.
- Preview against known data. Plot the derived series next to its inputs and sanity-check a few points by hand before using it in real analysis.
- Save the layout. PJ4 saves transforms with the layout, so the derived series can be recreated the next time you open that view of the data.
A note on honesty: the project has not, at the time of writing, published a full end-user scripting manual for PJ4, and the official documentation set remains developer-facing. So this guide deliberately describes the workflow rather than printing “API documentation”. The snippet below is an illustrative pattern in pseudocode — it shows the shape of a transform (several inputs in, one derived value out, applied over time), not real PlotJuggler function names, which you should take from the application and the project repository itself:
# Illustrative pattern only — pseudocode, NOT PlotJuggler API
# inputs: recorded series selected in the transform editor
# output: one derived value per timestamp
for each timestamp t:
derived[t] = combine( input_a[t], input_b[t], ... )Lua or Python: how to choose
| Situation | Better choice | Why |
|---|---|---|
| You have working Lua transforms from PJ3 | Lua | They express the same computations in PJ4; rewriting working code in a second language adds risk, not value. |
| Your team writes Python everywhere else | Python | One language across your analysis stack is easier to review, share and maintain. |
| You are following an existing tutorial or the PX4 documentation | Whichever it uses | The established PJ3-era material — including the PX4 docs’ quaternion example — is written in Lua; match the source in front of you. |
| You are starting a brand-new transform library | Python, if your team is Python-first | New, long-lived code belongs in the language your team will still enjoy maintaining in two years. |
Where scripting fits in PJ4
Scripted transforms sit alongside PJ4’s built-in analysis — filters, derivative, integral and FFT — and feed the same views, from classic time-series plots to the new multimodal ones described in Video and 3D Visualisation. They are also per-layout assets: because layouts and transforms save together, a well-built transform becomes part of a reusable view you can share with colleagues. If you are coming from PJ3, the migration guide covers where transforms fit in the move; if you are deciding whether PJ4 is worth the move at all, start with What’s New in PlotJuggler 4.0.
