Before applying statistical models like ARIMA, which assume stationarity, it's essential to check if your time series data meets this condition. A quick and intuitive first step is visual inspection. While not conclusive on its own, plotting the data and its rolling statistics can often reveal obvious trends or changes in variance that indicate non-stationarity.
The most basic check involves simply plotting the time series values against time. Look for the following visual cues:
Let's look at an example using Python. We'll assume you have your time series loaded into a Pandas Series or DataFrame indexed by time.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import plotly.graph_objects as go # Using plotly for interactive plots
# Sample Data: Create a non-stationary series with a trend
dates = pd.date_range(start='2023-01-01', periods=50, freq='D')
data_nonstationary = np.linspace(10, 25, 50) + np.random.normal(0, 2, 50)
ts_nonstationary = pd.Series(data_nonstationary, index=dates)
# Sample Data: Create a potentially stationary series
data_stationary = np.random.normal(15, 3, 50)
ts_stationary = pd.Series(data_stationary, index=dates)
# --- Plotting Non-Stationary Data ---
fig_nonstationary = go.Figure()
fig_nonstationary.add_trace(go.Scatter(x=ts_nonstationary.index, y=ts_nonstationary.values,
mode='lines', name='Time Series', line=dict(color='#339af0'))) # blue
fig_nonstationary.update_layout(
title='Time Series with an Upward Trend',
xaxis_title='Date',
yaxis_title='Value',
template='plotly_white',
height=350,
margin=dict(l=20, r=20, t=40, b=20)
)
# fig_nonstationary.show() # Use this in a notebook
# --- Plotting Stationary Data ---
fig_stationary = go.Figure()
fig_stationary.add_trace(go.Scatter(x=ts_stationary.index, y=ts_stationary.values,
mode='lines', name='Time Series', line=dict(color='#20c997'))) # teal
fig_stationary.update_layout(
title='Potentially Stationary Time Series',
xaxis_title='Date',
yaxis_title='Value',
template='plotly_white',
height=350,
margin=dict(l=20, r=20, t=40, b=20)
)
# fig_stationary.show() # Use this in a notebook
Running the code above (ideally in an environment that displays Plotly charts) would generate two plots.
The clear upward slope in this plot is a strong indicator of non-stationarity due to a trend.
This series appears to fluctuate around a constant level (around 15) with relatively consistent variance. It looks more likely to be stationary, although we need more checks.
A more quantitative visual approach is to plot the rolling mean and rolling standard deviation (or variance). If the series is stationary, both the rolling mean and rolling standard deviation should remain roughly constant over time. Significant upward or downward trends, or large fluctuations in these rolling statistics, strongly suggest non-stationarity.
Pandas provides the rolling()
method to easily calculate these statistics.
# Define window size for rolling statistics (e.g., 7 days)
window_size = 7
# Calculate rolling mean and standard deviation for the non-stationary series
rolling_mean_ns = ts_nonstationary.rolling(window=window_size).mean()
rolling_std_ns = ts_nonstationary.rolling(window=window_size).std()
# --- Plotting Non-Stationary Data with Rolling Stats ---
fig_roll_ns = go.Figure()
fig_roll_ns.add_trace(go.Scatter(x=ts_nonstationary.index, y=ts_nonstationary.values,
mode='lines', name='Original Series', line=dict(color='#adb5bd', width=1))) # gray
fig_roll_ns.add_trace(go.Scatter(x=rolling_mean_ns.index, y=rolling_mean_ns.values,
mode='lines', name='Rolling Mean', line=dict(color='#f03e3e', width=2))) # red
fig_roll_ns.add_trace(go.Scatter(x=rolling_std_ns.index, y=rolling_std_ns.values,
mode='lines', name='Rolling Std Dev', line=dict(color='#fd7e14', width=2))) # orange
fig_roll_ns.update_layout(
title='Non-Stationary Series with Rolling Statistics (Window=7)',
xaxis_title='Date',
yaxis_title='Value',
template='plotly_white',
height=400,
legend_title_text='Metrics',
margin=dict(l=20, r=20, t=50, b=20)
)
# fig_roll_ns.show()
Let's visualize this for the non-stationary data.
The rolling mean clearly trends upwards, confirming the visual assessment from the first plot. The rolling standard deviation appears relatively constant here, but the drifting mean is sufficient to classify the series as non-stationary. A similar plot for the stationary example would show both the rolling mean and rolling standard deviation hovering around flat lines.
Visual inspection is a valuable starting point, offering quick insights into the data's behavior. However, it has limitations:
Therefore, while visual checks are useful for identifying obvious non-stationarity, they should always be followed by more rigorous statistical tests, such as the Augmented Dickey-Fuller (ADF) test, which provide a quantitative measure of stationarity. We will cover these tests in the next section.
© 2025 ApX Machine Learning