signal processing
Python programming
noise addition
data analysis
digital signal processing

adding noise to a signal in python

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Adding noise to a signal is a common way to simulate real measurements, test filtering algorithms, or build more realistic training data. In Python, the basic workflow is straightforward: create or load the clean signal, generate a noise distribution, and add the two arrays together. The important part is controlling how strong the noise should be.

Start with a Clean Signal

It helps to begin with a simple signal so you can see the effect clearly. A sine wave is a good example:

python
1import numpy as np
2import matplotlib.pyplot as plt
3
4sample_rate = 1000
5duration = 1.0
6t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False)
7
8clean_signal = np.sin(2 * np.pi * 5 * t)
9
10plt.plot(t, clean_signal)
11plt.title("Clean signal")
12plt.xlabel("Time (s)")
13plt.ylabel("Amplitude")
14plt.show()

This gives a one-second, five-hertz sine wave sampled at one thousand points per second.

Add Gaussian Noise

The most common synthetic noise model is white Gaussian noise. In NumPy, generate it with np.random.normal and add it directly to the signal.

python
1import numpy as np
2
3rng = np.random.default_rng(42)
4noise = rng.normal(loc=0.0, scale=0.2, size=clean_signal.shape)
5
6noisy_signal = clean_signal + noise

Here, loc=0.0 means zero-mean noise and scale=0.2 sets the standard deviation. Larger values produce more aggressive corruption.

Plot the result:

python
1plt.plot(t, clean_signal, label="clean")
2plt.plot(t, noisy_signal, label="noisy", alpha=0.7)
3plt.legend()
4plt.title("Signal with Gaussian noise")
5plt.xlabel("Time (s)")
6plt.ylabel("Amplitude")
7plt.show()

This is often enough for experiments where you only need a rough noisy version of the original signal.

Control Noise with a Target SNR

In signal processing, it is often better to specify noise strength with a signal-to-noise ratio, or SNR, instead of an arbitrary standard deviation. That gives more predictable behavior across signals with different amplitudes.

python
1import numpy as np
2
3def add_awgn(signal, snr_db, rng=None):
4    if rng is None:
5        rng = np.random.default_rng()
6
7    signal_power = np.mean(signal ** 2)
8    snr_linear = 10 ** (snr_db / 10)
9    noise_power = signal_power / snr_linear
10    noise_std = np.sqrt(noise_power)
11
12    noise = rng.normal(0.0, noise_std, size=signal.shape)
13    return signal + noise
14
15
16noisy_20db = add_awgn(clean_signal, snr_db=20, rng=np.random.default_rng(1))
17noisy_5db = add_awgn(clean_signal, snr_db=5, rng=np.random.default_rng(1))

A higher SNR means less noise. A twenty-decibel signal stays relatively clean, while five decibels is much noisier.

Other Noise Models

Gaussian noise is the default choice for many simulations, but it is not the only option. Depending on the domain, you may want:

  • uniform noise for simple bounded perturbations
  • Poisson noise for count-like measurements
  • impulse noise for sudden spikes or dropouts

Uniform noise example:

python
uniform_noise = rng.uniform(low=-0.1, high=0.1, size=clean_signal.shape)
uniform_noisy_signal = clean_signal + uniform_noise

The right distribution depends on the physical or statistical process you are trying to model.

Keep Experiments Reproducible

When testing algorithms, reproducibility matters. Use a seeded random number generator rather than relying on global random state.

python
rng = np.random.default_rng(12345)
noise = rng.normal(0.0, 0.2, size=clean_signal.shape)

That way, repeated runs use the same synthetic noise and make comparisons fairer.

Common Pitfalls

One common mistake is adding noise with a standard deviation that has no relationship to the signal scale. The result may be far noisier or far cleaner than intended.

Another mistake is skipping reproducibility. If every run uses a different random sequence, it becomes harder to compare filters or model performance fairly.

Developers also sometimes confuse amplitude scaling with power-based SNR control. If you care about a target SNR, compute noise power from signal power rather than guessing a standard deviation.

Finally, be careful with clipping and data type conversion. If the signal will later be cast to integers or written to a bounded format, added noise can push values out of range.

Summary

  • In Python, adding noise usually means generating a noise array and adding it elementwise to the signal.
  • Gaussian noise is the most common starting point for simulations.
  • SNR-based noise generation is more controlled than guessing a standard deviation.
  • Different applications may call for Gaussian, uniform, Poisson, or impulse-like noise models.
  • Seeded random generators make noisy-signal experiments reproducible.

Course illustration
Course illustration

All Rights Reserved.