Fundamentals 6 min read

Fit Real-World Data with Fourier Series Using Python

This article explains Fourier series theory, demonstrates how to remove linear trends from monthly CO₂ data, and shows step‑by‑step Python code using SciPy's curve_fit to fit and predict the data with a 100‑term Fourier expansion.

Model Perspective
Model Perspective
Model Perspective
Fit Real-World Data with Fourier Series Using Python

Fourier Series

Any periodic function can be represented as a linear combination of sine and cosine functions with different amplitudes and phases, a concept first discovered by French mathematician Joseph Fourier.

Python Case Study

We use the Fourier series formulas to fit a real‑world dataset. Because real data contain noise, we first remove the linear trend and then fit the residual using a Fourier series with SciPy's curve_fit to estimate the coefficients.

<code>import pandas as pd
import numpy as
data = pd.read_excel('data/load_co2_monthly.xlsx', index_col=0)
</code>

The first 24 rows of the monthly CO₂ data are shown in the original article (omitted here for brevity).

<code>xarray = data.index.values
yarray = data.co2.values
plt.plot(xarray, yarray)
plt.show()
</code>

After plotting, a clear upward trend is observed. We remove this linear trend:

<code>k, b = np.polyfit(xarray, yarray, deg=1)

def linear(x):
    return k * x + b

y_trend = linear(xarray)
plt.plot(xarray, yarray)
plt.plot(xarray, y_trend)
plt.show()
</code>

Subtracting the linear component yields the detrended series:

<code>y_no_trend = yarray - linear(xarray)
plt.plot(y_no_trend)
plt.show()
</code>

The detrended data exhibits a clear periodic pattern with a period of 12 months.

<code>from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
import numpy as

def fourier(x, *a):
    w = 2 * np.pi / 12  # period = 12
    ret = 0
    for deg in range(0, int(len(a) / 2) + 1):
        ret += a[deg] * np.cos(deg * w * x) + a[len(a) - deg - 1] * np.sin(deg * w * x)
    return ret

popt, pcov = curve_fit(fourier, xarray, y_no_trend, [1.0] * 100)  # 100‑term Fourier series

y_no_trend_pred = fourier(xarray, *popt)
</code>

We visualize the original detrended data against the Fourier fit:

<code>plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.plot(xarray, y_no_trend)
plt.title('Original')
plt.subplot(1, 2, 2)
plt.plot(xarray, y_no_trend_pred)
plt.title('Fourier')
plt.show()
</code>

Finally, we combine the linear trend and the Fourier‑based periodic component and compare it with the original series:

<code>plt.plot(xarray, yarray, label='original')
plt.plot(xarray, linear(xarray) + fourier(xarray, *popt), label='pred')
plt.legend()
plt.show()
</code>

The combined model matches the original data closely, demonstrating that Fourier series can effectively capture periodic patterns in noisy real‑world datasets.

Reference:

Fourier Series (with Python square‑wave example) https://zhuanlan.zhihu.com/p/544218711

Pythonsignal processingtime series analysisdata fittingFourier series
Model Perspective
Written by

Model Perspective

Insights, knowledge, and enjoyment from a mathematical modeling researcher and educator. Hosted by Haihua Wang, a modeling instructor and author of "Clever Use of Chat for Mathematical Modeling", "Modeling: The Mathematics of Thinking", "Mathematical Modeling Practice: A Hands‑On Guide to Competitions", and co‑author of "Mathematical Modeling: Teaching Design and Cases".

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.