Complex-Valued and Phase Plots

Visualizing Complex-Valued Data

In wireless communications and signal processing, nearly everything is complex-valued: channel coefficients, baseband signals, frequency responses, and constellation points. Plotting complex data requires special techniques — magnitude/phase dual plots, HSV phase coloring, constellation diagrams, and polar plots.

Definition:

Magnitude/Phase (Bode) Plot

A complex-valued function H(f)H(f) is visualized as two vertically-stacked panels:

Top: H(f) or 20log10H(f) (dB)\text{Top: } |H(f)| \text{ or } 20\log_{10}|H(f)| \text{ (dB)} Bottom: H(f) (radians or degrees)\text{Bottom: } \angle H(f) \text{ (radians or degrees)}

fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)
ax1.plot(f, 20*np.log10(np.abs(H)))
ax1.set_ylabel('|H(f)| (dB)')
ax2.plot(f, np.degrees(np.angle(H)))
ax2.set_ylabel('Phase (deg)')
ax2.set_xlabel('Frequency (Hz)')

Definition:

Constellation Diagram

A constellation diagram plots complex-valued symbols sk=Ik+jQks_k = I_k + jQ_k in the I-Q plane:

ax.scatter(symbols.real, symbols.imag, s=3, alpha=0.5)
ax.set(xlabel='In-Phase (I)', ylabel='Quadrature (Q)')
ax.set_aspect('equal')
ax.grid(True, alpha=0.3)

Ideal constellation points appear as tight clusters; noise and interference cause spreading.

Use ax.set_aspect('equal') — distorted aspect ratios make QPSK look like a rectangle instead of a square.

Theorem: Phase Unwrapping

The np.angle() function returns phase in (π,π](-\pi, \pi]. When the true phase exceeds this range, discontinuous jumps of ±2π\pm 2\pi appear. np.unwrap(phase) corrects these:

ϕunwrapped[n]=ϕ[n]2πround ⁣(ϕ[n]ϕ[n1]2π)\phi_{\text{unwrapped}}[n] = \phi[n] - 2\pi \cdot \text{round}\!\left(\frac{\phi[n] - \phi[n-1]}{2\pi}\right)

Always unwrap phase before plotting to show the true continuous phase response.

A linear-phase FIR filter has H(f)=2πfτ\angle H(f) = -2\pi f \tau. Without unwrapping, this appears as a sawtooth; after unwrapping, it is a clean straight line.

Example: Bode Plot of a Digital Filter

Plot the magnitude and unwrapped phase response of a 4th-order Butterworth lowpass filter.

Example: 16-QAM Constellation with Noise

Plot an ideal and noisy 16-QAM constellation diagram side by side.

Example: HSV Phase Coloring of a Complex Field

Visualize a 2D complex field where hue encodes phase and brightness encodes magnitude.

Constellation Diagram Explorer

View constellation diagrams for different modulation schemes at various SNR levels. See how noise spreads the ideal constellation points.

Parameters

Phase Rotation Animation

Watch how a frequency offset causes the constellation to rotate over time, and how a phase-locked loop (PLL) corrects it.

Parameters

Why This Matters: Constellation Diagrams and EVM

The Error Vector Magnitude (EVM) is measured directly from the constellation diagram as the RMS distance between received symbols and ideal constellation points. 3GPP specifies EVM limits for each modulation order: 17.5% for QPSK, 12.5% for 16-QAM, 8% for 64-QAM, and 3.5% for 256-QAM in 5G NR. Plotting the constellation is the first diagnostic step when a transmitter fails EVM tests.

Key Takeaway

For complex-valued data, always use dual mag/phase plots or constellation diagrams. Never plot only np.real(z) — you lose half the information. Always unwrap phase before plotting, and always use equal aspect ratio for constellation diagrams.

Quick Check

What does np.unwrap() do to a phase array?

Converts radians to degrees

Removes discontinuities larger than pi by adding multiples of 2*pi

Clips the phase to [-pi, pi]

Computes the inverse FFT of the phase

Constellation Diagram

A scatter plot of complex-valued symbols in the I-Q plane, showing the positions of transmitted or received modulation points.

Related: EVM (Error Vector Magnitude)

EVM (Error Vector Magnitude)

The RMS distance between received symbols and their ideal constellation positions, expressed as a percentage of the reference signal amplitude.

Bode Plot

A dual plot showing the magnitude (in dB) and phase of a complex-valued frequency response as functions of frequency.