The Data Display
Plots and tables, trace cards, axes, markers — and how a run's cubes become curves.
The Data Display is where results are looked at. It is a document, like a schematic or a layout: it
opens as a tab in the workspace, tears off into its own window, and is saved to disk as a .cdd file
that reopens exactly as you left it.
It plots files, not runs
A Data Display is not bound to one schematic or one run. It reads files
— .npy results, Touchstone .sNp, measured load-pull — and it will happily hold
traces from several at once. That is what lets you overlay a measurement on a simulation, or last week's
baseline on today's, without either of them knowing about the other.
Practical consequences:
- A run overwrites its results file, and every trace bound to that file refreshes. Nothing needs to be re-added.
- To keep a baseline, name a different results file for that run — see Where results live — and point a trace at it.
- A trace remembers the file it came from, so a saved
.cddreopens against the same data. - A new Data Display starts empty. Nothing is auto-plotted; you author it.
Anatomy of a display
A display holds one or more tabs; each tab is a canvas holding plots; each plot holds traces; a trace may carry markers. Plots are moved and resized on the canvas directly. The Plot Inspector — one panel per selected plot — is where the plot's type, its traces and its axes are edited.
There are four plot types, and which one will accept which data is the single most important rule in the Data Display. It has its own page: Plot Types.
From a DataSet to a curve
A run produces one DataSet: an ordered map of groups to named DataCubes.
- One group per analysis —
HB1,DC1,SP1— plus ameasurementsgroup, plus a default group ("") that a flat Touchstone file lands in. - Cubes are addressed
Analysis.Cube:HB1.V,SP1.S,measurements.PDC. A bare name resolves in the default group first, then inmeasurements, so you can writePDCand meanmeasurements.PDC. An analysis cube must stay qualified — a bareVwould find the wrong group.
A DataCube is an N-dimensional array, real or complex throughout, with named axes. Each axis has
numeric values, a unit, and sometimes string labels — the node axis of V is labelled with your net
names (and with the name of any VProbe you placed, which adds a row for the
net it taps), and the branch axis of I with your IProbe names.
| Cube | Axes, from single-point to fully swept | Kind |
|---|---|---|
V |
[node] → [node, harmonic] → [sweep…, node, harmonic] |
Complex for HB, real for DC |
I |
[branch] → [branch, harmonic] → [sweep…, branch, harmonic] |
Complex or real |
S |
[freq, i, j], or [sweep…, freq, i, j] |
Complex |
| a measurement | a scalar, or [sweep…] |
Real or complex |
A trace is a one-dimensional slice through a cube. Authoring a trace means saying, for each axis of the cube, what to do with it: use it as the X axis, iterate it as a family of curves, or pin it to one value. That is the whole model, and the trace card is its interface.
The trace card
Reading top to bottom:
Identity — what to plot. A group selector (an analysis, or Measurements) and then an item selector. For an analysis group the item selector is a compact V / I pair, because voltage and current are deliberately symmetric: one mental model, one set of controls. Both are always offered; if you pick one whose cube is not in the result you get an explicit empty state rather than a blank card. For S-parameters, an item is a matrix element.
Axis roles — how to slice it. One row per axis of the cube, each offering three roles:
| Role | What it does |
|---|---|
| X | Use this axis along the bottom of the plot. Exactly one axis may be X — or none, which makes the trace a scalar. |
| Fam | Iterate this axis as a family of curves. At most one, and it needs an X. |
| Fix | Pin this axis to a single value, chosen in the selector beside it. |
The node/branch label axis defaults to Fix — it is a selector, never the X axis. The default X
prefers freq when the cube has one, then falls back to the first non-label axis. A cube with no
non-label axis at all — a DC operating point with no sweep — has no X and resolves to a scalar, which is
what a Table is for.
The eye on the label-axis row reveals the entries that are normally hidden: every node beyond the ones you named, and every device-port branch beyond your IProbes. It is one control shared by the node and branch rows. A net label and a VProbe both count as naming a node, so both are visible without it.
Spec — the transform, and the shorthand text box (below).
Style — line, symbol, per-port Z0 for a network trace, and the number format on a Table.
Derived metrics. Beneath the matrix elements the item selector also offers quantities computed from the S-matrix rather than read out of it — stability factors, maximum gain, passivity, group delay, and the ESR / C / L / Q readouts a passive part is specified in. Selecting one reveals its own controls: the ordered port pair, and for a passive readout the Fixture that decides how the two-terminal impedance is recovered. Every equation is written out in Derived Metrics.
Against a harmonic-balance result
The same card, pointed at an HB drive sweep. The extra axes are what change: V now carries a
harmonic axis and a swept-power axis alongside the node axis, so there is a real choice to make about
which is X, which is the family, and which is pinned.
They look the same on the plot and they are not the same underneath. A Touchstone file
lands in the default group and is handled by the network path — group "S-Parameters", matrix-element
items, per-port Z0 available. An S-parameter run result lands in a named group
(SP1) and is a first-class cube: freq defaults to X, i and
j become 1-based port selectors, and dB20 is the default transform on a
rectangular plot. The Z0 cube beside it is a per-port reference impedance, not a signal, and
is never offered as one.
The spec shorthand
The text box on the spec row is a two-way view of the binding: every control on the card writes it, and editing it rewrites every control. The grammar is:
[transform] CubeName[ token, token, … ]
- transform — optional, either prefixed (
dB20 V[…]) or as a function (mag(V[…])). One ofdB20 dB10 dB mag phase real imag conj. - CubeName — qualified (
HB1.V) or bare (PDC). - token — one per axis, in the cube's own axis order:
| Token | Role |
|---|---|
: |
the whole axis, as X |
a:b |
a narrowed range, as X |
~ |
this axis is the family |
"Vout" |
fix to a labelled entry — a net or probe name |
3 |
fix to index 3 |
A bare CubeName with no brackets means the whole cube — every axis :. A spec with no : and no
~ at all is a scalar, valid on a Table: DC1.V["Vout"].
On an S/Y/Z cube's i and j axes a bare integer is a port
number, so SP1.S[:, 2, 1] is S21 and SP1.S[:, 1, 1] is S11 — the way an
RF engineer names them. Every other axis (freq, a sweep, harmonic) uses a
0-based index, and labelled axes use quoted names. A port outside 1..N is reported, not clamped.
Validity is checked as you type: exactly one X or none, at most one ~, and a ~ needs an X. Anything
else is reported inline under the box rather than silently producing a different curve.
The box also accepts a free expression across cubes — mag(HB1.V) - mag(HB1.Vref),
dB20(SP1.S[:, 2, 1]) — evaluated element-wise. Inside one, freq is the sample's own frequency in
Hz, so imag(SP1.Z[:, 1, 1]) / (2*pi*freq) plots an inductance against frequency. freq is bound
only when the X axis is a frequency; on a Pin- or Γ-swept trace the error names the axis the trace
actually has.
Families of curves
A family is one trace object that renders N curves — not N traces. Mark an axis Fam (or type ~
in its position) and every value of that axis draws its own curve, with one legend entry and one set of
style controls governing all of them.
dB20 HB1.V[:, "Vout", ~] every harmonic of Vout, versus the swept axis
SP1.S[~, :, 2, 1] S21 versus frequency, one curve per sweep point
That distinction matters when you change your mind about the sweep: you edit one card, not twenty.
Plotting against another quantity
A spec may end with vs <x-spec>, which plots the trace against that quantity instead of against the
cube's own swept axis:
Gain vs Pout
dB20(HB1.V[:, "Vout", 1]) vs Pout
This is how you get gain against output power rather than against drive, which is the form a PA designer actually wants. On the card it is the vs X row. The X side inherits the Y side's swept axis and family by axis name, so you rarely have to restate them, and the X side may even come from a different loaded file.
Axes and limits
Each plot carries axis labels and limits of its own, edited from the Plot Inspector. A trace may be assigned to a secondary (right-hand) Y axis on a rectangular plot, which is how gain in dB and efficiency in per cent share one frame legibly. Autoscale is on until you set a limit; setting one turns it off for that axis, so a figure you have framed deliberately does not re-frame itself on the next run.
The decibel floor
A decibel trace bottoms out at −250 dB. Below that the curve is drawn flat at −250, and a readout
says so with the inequality rather than a bare number — a marker info box reads dB(S(1,1)) ≤ -250.00,
a table cell ≤ -250.00.
This matters more often than it sounds, because a quantity that is analytically zero does not come back as zero. An ideal 50 Ω line terminated in 50 Ω has S(1,1) ≡ 0, and what the solver returns is double-precision roundoff: magnitudes scattered over a few orders of magnitude with the occasional exact zero mixed in. Converted to dB with no floor, that is a trace flickering across a 59 dB band with spikes to −∞ — and autoscale then sizes the axis to the flicker, so anything real sharing the plot is squashed into a line. The floor turns the noise into a flat line at the bottom of the frame and lets the rest of the plot keep its scale.
−250 dB was chosen to sit below anything a result can physically mean and above anything roundoff can
produce: thermal noise power in a 1 Hz bandwidth is −204 dB(W), while roundoff on a quantity of order
one reaches −285 dB. dB, dB10 and dB20 all share the one floor.
The floor is applied to the picture only. A measurement expression, and any value you export to
.npy, .mat or Touchstone, carries the unclamped number — so dB(S(1,1)) written as a measurement
can report a value below −250 dB even while the plot of the same quantity shows the floor. A number's
value never depends on whether it happened to be drawn.
Markers
Drop a marker on a trace to read its value. Markers are per-trace, they persist in the saved .cdd, and
on a load-pull contour they read the interpolated surface rather than the nearest grid point — which
is the point of fitting a surface at all. The maximum-power and maximum-efficiency locations are flagged
on a contour plot automatically.
Load-pull contours
A load-pull sweeps the termination Γ presented to the device over a grid, and at each grid point
drives the device up in power to a target gain compression. The raw result is therefore two-axis —
{grid point, drive step} — and every figure of merit is a value over that field. Contours are how you
look at it.
The form a contour takes is always the same: a metric, at a constant value of a different metric. Pout at constant 3 dB compression. Efficiency at constant Pout. Gain at constant back-off.
The contour card asks for exactly that:
- Metric — what is being contoured (Pout, PAE, gain, …).
- Constraint — the other metric held constant, and its value. Compression is the common case and has its own control.
- Levels — either a start/step/stop range or a count, plus whether to draw iso-lines, fills or labels.
- Substrate — the Γ plane (a Smith chart) or the Z plane (a rectangular plot).
- Frequency — pinned, for a frequency-swept load-pull.
- Interpolation — the radial-basis kernel, its smoothing and its shape parameter.
Reading the figure: each closed curve is a locus of terminations that deliver the same metric value, and the labels give that value. The P and E markers are the maximum-power and maximum-efficiency optima; the distance between them is the trade-off the design has to spend. The grid points themselves can be shown, and it is worth doing at least once: a contour is an interpolated surface, and it can only be trusted where the grid actually surrounds it. Contours that run off the edge of the constellation are extrapolation.
Background on the method and the surface model: Loadpull / Sourcepull and Loadpull Pursuit.
The toolbar
| # | Button | What it does |
|---|---|---|
| 1 | — | no tooltip |
| 2 | Add Rect Plot (Ctrl+Shift+A) | |
| 3 | Add Smith Plot | |
| 4 | Add Polar Plot | |
| 5 | Add Table | |
| 6 | Add 3D Pattern — for seeing a pattern is not the shape you assumed, and for the picture that goes in a report. The principal-plane cuts say more about an antenna. | |
| 7 | New Tab (Ctrl+T) | |
| 8 | Zoom Box (Z) — drag a box to zoom to it (Esc cancels; Ctrl++ steps) | |
| 9 | Zoom Out (Ctrl+-) | |
| 10 | Fit All (F, Ctrl+0) | |
| 11 | Undo (Ctrl+Z) | |
| 12 | Redo (Ctrl+Shift+Z) | |
| 13 | Save Display (.cdd) | |
| 14 | Open Display (.cdd) | |
| 15 | Export Data |
The groups, left to right: the source picker, which chooses the data source new traces bind to; the four plot types, which add a plot of that kind; add trace; the zoom and fit controls; undo and redo, which cover the whole display and not just the selected plot; and save, open and export.
See also: Plot types · Results & data export · Measurements · Simulations.