1
$\begingroup$

I am currently working with a signal, and I am interested in plotting its spectra. I have used python, I have computed the signal values, and I have an array that has the time-series values of the signal.

Using the periodogram function from the signal library I am able to compute the power spectra, but when plotting the spectrum against the frequencies, the graph is not smooth.

I would like to have a smooth graph, and from some of the research I've been doing I think applying a filter is needed, however I am not sure what filter I should be using and I would like some information.

$\endgroup$
2
  • 1
    $\begingroup$ "I would have to have a smooth graph": Why? (there's valid reasons, for example if you know something about the signal you don't tell us, when your observation is short etc, but in general:) Making a plot look like you want it to is kind of like lying with data... Mostly, however, the method of scaling would always depend on the usage of the spectrum afterwards, i.e. how you smooth something depends on why you smooth it. $\endgroup$ Commented May 19, 2020 at 18:54
  • 1
    $\begingroup$ As an alternative to the periodogram you could try to use Welch's method to estimate the power spectral density of your signal. It's basically a smoothed version of the periodogram and is available in Python in the SciPy library. $\endgroup$
    – applesoup
    Commented May 19, 2020 at 19:04

1 Answer 1

2
$\begingroup$

Using scipy.signal.filtfilt is often a good choice for post processing such as smoothing plots due to its zero delay (a non zero delay filter in contrast will create a frequency shift given the sample delay induced from input to output that would otherwise need to be compensated for).

As for the actual filter coefficients, A moving average would be simplest and often more than sufficient for a visual smoothing (numerator coefficients all 1's over the number of samples to average, and denominator coefficient as a single value equal to the number of samples). For example:

out = scipy.signal.filtfilt([1,1,1,1,1],5, sig)

Note that filtfilt works by using the filter in forward and reverse directions (thus cancelling the delay for non-causal post-processing), so the moving average is done twice in cascade.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.