sdr.plot.eye(x: NDArray, sps: int, span: int = 2, sample_rate: float | None = None, color: 'index' | str = 'index', **kwargs)

Plots the eye diagram of the baseband modulated signal \(x[n]\).

Parameters:
x: NDArray

The baseband modulated signal \(x[n]\). If x is complex, the real and imaginary rasters are interleaved. Time order is preserved.

sps: int

The number of samples per symbol.

span: int = 2

The number of symbols per raster.

sample_rate: float | None = None

The sample rate \(f_s\) of the signal in samples/s. If None, the x-axis will be labeled as “Samples”.

color: 'index' | str = 'index'

Indicates how to color the rasters. If "index", the rasters are colored based on their index. If a valid Matplotlib color, the rasters are all colored with that color.

**kwargs

Additional keyword arguments to pass to sdr.plot.raster().

Example

Modulate 100 QPSK symbols.

In [1]: psk = sdr.PSK(4, phase_offset=45); \
   ...: s = np.random.randint(0, psk.order, 100); \
   ...: a = psk.map_symbols(s)
   ...: 

Apply a raised cosine pulse shape and examine the eye diagram. Since the raised cosine pulse shape is a Nyquist filter, there is no intersymbol interference (ISI) at the symbol decisions.

In [2]: sps = 25; \
   ...: h = sdr.raised_cosine(0.5, 6, sps); \
   ...: fir = sdr.Interpolator(sps, h); \
   ...: x = fir(a)
   ...: 

In [3]: plt.figure(figsize=(8, 4)); \
   ...: sdr.plot.eye(x, sps)
   ...: 
../../_images/sdr_plot_eye_1.png

Apply a root raised cosine pulse shape and examine the eye diagram. The root raised cosine filter is not a Nyquist filter, and ISI can be observed. (It should be noted that two cascaded root raised cosine filters, one for transmit and one for receive, is a Nyquist filter. This is why SRRC pulse shaping is often used in practice.)

In [4]: sps = 25; \
   ...: h = sdr.root_raised_cosine(0.5, 6, sps); \
   ...: fir = sdr.Interpolator(sps, h); \
   ...: x = fir(a)
   ...: 

In [5]: plt.figure(figsize=(8, 4)); \
   ...: sdr.plot.eye(x, sps)
   ...: 
../../_images/sdr_plot_eye_2.png