I'd like to plot an eye diagram with a 'hot' colormap that becomes clearer not when the signal has high values, but when the signal is dense at an instant in time, see picture below.
Here is what I've already done:
def prbs_generation(size=15, oversampling_factor=100, bitrate=50, Fc=18.75, snr=20, plot=True, save=False):
print("Generation of the PRBS ...")
bit = list()
start = 1
lfsr = start
i = 1
while True:
fb = ((lfsr >> (size-1)) ^ (lfsr >> (size-2)) & 1)
lfsr = ((lfsr << 1) + fb) & (2 ** size - 1)
bit.append(fb)
if lfsr == start:
break
i = i + 1
bit = [float(i) for i in bit]
bit = np.array(bit)
t = np.arange(0, len(bit)) * (1000 / bitrate)
"Continuous" signal
g = np.ones(oversampling_factor)
bit_oversampled = np.zeros(len(bit) * oversampling_factor)
bit_oversampled[::oversampling_factor] = bit
bit_oversampled = signal.lfilter(g,1, bit_oversampled)
t_oversampled = np.arange(0, len(bit_oversampled)) * (1000 / (bitrate * oversampling_factor))
Filter the signal
Fs = 1000 / t_oversampled[1]
Wn = Fc / (Fs / 2) # Cutoff frequency
b, a = signal.bessel(4, Wn, btype='low', norm='mag')
Filter the signal
w, h = signal.freqz(b, a, fs=Fs)
bit_oversampled_filtered = signal.lfilter(b, a, bit_oversampled)
Add noise
bit_filtered_noisy = add_noise(bit_oversampled_filtered, snr)
if plot:
# Eye diagram
plotEyeDiagram_new(t_oversampled, bit_filtered_noisy, title='Eye diagram data generated', TSymb=20)
With plotEyeDiagram :
def plotEyeDiagram_new(X, Y, title, TSymb, samples=100000, plot=True, save=False):
NbSamples = len(Y)
OldSamplingRate = 1000 * (NbSamples - 1) / (X[-1] - X[0])
NewSamplingRate = OldSamplingRate + 0.03
nbSamples2 = round((NbSamples - 1) * NewSamplingRate / OldSamplingRate + 1)
Y2, X2 = signal.resample(Y, nbSamples2, X)
dataEyeX = np.divmod(X2, 2 * TSymb)
dataEyeX = dataEyeX[1]
if plot:
EyeFig = plt.figure()
plt.scatter(dataEyeX[:samples], Y2[:samples], cmap='hot', s=3)
plt.title(title, fontweight="bold")
plt.xlabel("Time (ps)")
plt.ylabel("Magnitude (A.U)")
plt.grid()
plt.tight_layout()
if save:
plt.savefig(title + ".png")
return dataEyeX[:samples]
And add_noise() :
def add_noise(data, snr):
signal_power = np.sum(data**2)/len(data)
noise_power = signal_power/(10**(snr/10))
noise = np.random.normal(0, np.sqrt(noise_power), len(data))
noisy_data = data + noise
return noisy_data
Here an example:
if __name__ == "__main__":
prbs_generation(oversampling_factor=100, snr=20, Fc=18.75, plot=True)
plt.show()
I get this king of figure when I filter and add noise :

Do you have any idea how to do it? Let me know if I am not clear! ;)
Thanks
