Time Series Seasonality Visualization
Time series data contains trends (long-term direction), seasonality (repeating periodic cycles), and residuals (noise) that must be identified before modeling. Visualizing these components reveals the structure your model needs to capture.
Time Series Decomposition
Classical decomposition separates a time series into trend, seasonal, and residual components using additive (Y = T + S + R) or multiplicative (Y = T × S × R) models. Additive is used when seasonal amplitude is constant; multiplicative when it grows with the trend.
Using seasonal_decompose
<pre><code class="language-python">import pandas as pd
from statsmodels.tsa.seasonal import seasonal_decompose
import matplotlib.pyplot as plt
df = pd.read_csv("monthly_sales.csv", index_col="date",
parse_dates=True)
result = seasonal_decompose(df["sales"], model="additive", period=12)
fig = result.plot()
fig.set_size_inches(12, 8)
plt.tight_layout()
plt.show()
print(result.trend.head())
print(result.seasonal.head())
print(result.resid.head())</pre>
Rolling Statistics and Autocorrelation
Rolling means smooth out noise to reveal the trend; autocorrelation plots (ACF/PACF) show how correlated a series is with its own past values, which determines lag features to include in ML models.
Rolling Mean and Standard Deviation
<pre><code class="language-python">import matplotlib.pyplot as plt
df["rolling_mean"] = df["sales"].rolling(window=12).mean()
df["rolling_std"] = df["sales"].rolling(window=12).std()
plt.figure(figsize=(12, 5))
plt.plot(df["sales"], label="Original", alpha=0.5)
plt.plot(df["rolling_mean"], label="12-Month Rolling Mean", color="red")
plt.fill_between(df.index,
df["rolling_mean"] - df["rolling_std"],
df["rolling_mean"] + df["rolling_std"],
alpha=0.2, color="red")
plt.legend()
plt.show()</pre>
Autocorrelation and Partial Autocorrelation
<pre><code class="language-python">from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8))
plot_acf(df["sales"].dropna(), lags=40, ax=ax1)
plot_pacf(df["sales"].dropna(), lags=40, ax=ax2)
plt.tight_layout()
plt.show()
# ACF spikes at multiples of 12 confirm annual seasonality</pre>