Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Chapter 4 — Visualizing Time Series

Before estimating models or producing forecasts, we should first look carefully at the data.

Visualization is one of the most important steps in time series analysis.

A graph often reveals features that summary statistics alone may hide.

This chapter introduces:

The emphasis is practical and intuition-first.


Learning Objectives

By the end of this chapter, you should be able to:


4.1 Why Visualization Matters

Time series data often contain rich structure.

Plots may reveal:

A model estimated without visual inspection may miss important features of the data.


4.2 A First Example

We begin with a simple example using stock market data.

import yfinance as yf
import matplotlib.pyplot as plt

sp500 = yf.download("^GSPC", start="2018-01-01", auto_adjust=False)

sp500["Adj Close"].plot(figsize=(10,4))

plt.title("S&P 500 Adjusted Closing Price")
plt.xlabel("Date")
plt.ylabel("Index Level")

plt.savefig("figs/ch4/sp500.png", dpi=300, bbox_inches="tight")
plt.close()   # replace with plt.show()
sp500

4.3 Components of a Time Series

Many time series contain several components.

A useful decomposition is:

Series=Trend+Cycle+Seasonality+Noise\text{Series} = \text{Trend} + \text{Cycle} + \text{Seasonality} + \text{Noise}

Trend

A trend represents long-run movement.

Examples include:

Cycles

Cycles are medium-run fluctuations around the trend.

Examples include:

Seasonality

Seasonality refers to regular repeating patterns.

Examples include:

Noise

Noise represents unpredictable random fluctuations.


Many macroeconomic variables display strong trends.

Examples include:

Example: GDP

# !pip install pandas_datareader

import pandas_datareader.data as web
import matplotlib.pyplot as plt

thai_gdp = web.DataReader(
    "MKTGDPTHA646NWDB",
    "fred",
    start="2000-01-01"
)

thai_gdp.plot(figsize=(10,4))

plt.title("Thailand GDP")
plt.ylabel("Current U.S. Dollars")

plt.savefig("figs/ch4/thai_gdp.png", dpi=300, bbox_inches="tight")
plt.close()   # replace with plt.show()
Thai GDP

This has important implications for modeling and forecasting later in the book.


Some time series fluctuate around relatively stable levels.

Others drift persistently upward or downward.


4.6 Seasonality

Seasonality refers to repeating patterns linked to the calendar.

Examples include:

Example: Monthly Airline Passengers

# import matplotlib.pyplot as plt
import pandas as pd

url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/airline-passengers.csv"

df = pd.read_csv(url)

df["Passengers"].plot(figsize=(10,4))

plt.title("Monthly Airline Passengers")

plt.savefig("figs/ch4/airline.png", dpi=300, bbox_inches="tight")
plt.close()   # replace with plt.show()
Airline

The fluctuations repeat systematically through time.


4.7 Cycles

Economic cycles differ from seasonality.

Seasonality repeats regularly.

Business cycles are more irregular.

Examples include:


4.8 Noise and Random Fluctuations

Not all movements are meaningful.

Time series often contain substantial randomness.

This is especially important in finance.

Short-run market movements may contain substantial noise.


4.9 Visualizing Financial Returns

Prices and returns often behave very differently.

# import yfinance as yf
# import matplotlib.pyplot as plt
# import pandas as pd

aapl = yf.download("AAPL", start="2020-01-01", auto_adjust=False)

prices = aapl["Adj Close"]

returns = prices.pct_change()

fig, ax = plt.subplots(2,1, figsize=(10,7))

ax[0].plot(prices)
ax[0].set_title("Apple Adjusted Prices")

ax[1].plot(returns)
ax[1].set_title("Apple Daily Returns")

plt.tight_layout()

plt.savefig("figs/ch4/aapl.png", dpi=300, bbox_inches="tight")
plt.close()   # replace with plt.show()
APPLE

4.10 Volatility Clustering

Financial returns often display changing volatility.

Periods of calm are followed by periods of turbulence.

This phenomenon becomes central later in ARCH and GARCH models.


4.11 Structural Breaks

Some time series experience sudden changes.

These are called structural breaks.

Examples include:

Example

The COVID-19 pandemic caused dramatic movements in:


4.12 Rolling Averages

A rolling average smooths short-run fluctuations.

This helps reveal longer-run patterns.

Simple Rolling Average

A rolling average over kk periods is:

MAt=1ki=0k1xtiMA_t = \frac{1}{k} \sum_{i=0}^{k-1}x_{t-i}

Example

# import yfinance as yf
# import matplotlib.pyplot as plt

aapl = yf.download("AAPL", start="2020-01-01", auto_adjust=False)

prices = aapl["Adj Close"]

ma50 = prices.rolling(50).mean()

plt.figure(figsize=(10,4))

plt.plot(prices, label="Price")

plt.plot(ma50, label="50-Day MA")

plt.legend()

plt.title("Apple Stock Price and Moving Average")

plt.savefig("figs/ch4/rolling.png", dpi=300, bbox_inches="tight")
plt.close()   # replace with plt.show()
Rolling MA

4.13 Comparing Multiple Series

Visualization also helps compare multiple variables.

# import yfinance as yf
# import matplotlib.pyplot as plt

aapl = yf.download("AAPL", start="2020-01-01", auto_adjust=False)["Adj Close"]

msft = yf.download("MSFT", start="2020-01-01", auto_adjust=False)["Adj Close"]

plt.figure(figsize=(10,4))

plt.plot(aapl / aapl.iloc[0], label="Apple")

plt.plot(msft / msft.iloc[0], label="Microsoft")

plt.legend()

plt.title("Normalized Stock Prices")

plt.savefig("figs/ch4/twostocks.png", dpi=300, bbox_inches="tight")
plt.close()   # replace with plt.show()
Two Stocks

4.14 Log Scales

Some time series grow exponentially over long periods.

In such cases, log scales can improve interpretation.

Example

# import yfinance as yf
# import matplotlib.pyplot as plt

sp500 = yf.download("^GSPC", start="1990-01-01", auto_adjust=False)

plt.figure(figsize=(10,4))

plt.plot(sp500["Adj Close"])

plt.yscale("log")

plt.title("S&P 500 (Log Scale)")

plt.savefig("figs/ch4/logscale.png", dpi=300, bbox_inches="tight")
plt.close()   # replace with plt.show()
Log Scale

4.15 Visualization and Forecasting

Good forecasting begins with understanding the data visually.

Plots may reveal:

These features influence model selection later.


4.16 Gretl Example: Plotting a Time Series

Gretl provides simple visualization tools.


Step 1 — Open Data

Menu:

File → Open data

Step 2 — Plot a Variable

Select a variable and choose:

Variable → Time series plot

[GRETL Screenshot Placeholder: Time series plot]

Step 3 — Add Moving Average

Menu:

Add → Moving average

[GRETL Screenshot Placeholder: Moving average plot]

4.17 Common Mistakes


4.18 Looking Ahead

This chapter introduced visual exploration of time series data.

The next chapter studies smoothing and trend estimation more formally.

We will examine:

Key Takeaways

Concept Check

Basic

  1. What is the purpose of plotting a time series?

  2. What is a trend?

  3. What is a cycle?


Intuition

  1. Why is visualization often the first step in time series analysis?

  2. How can a plot help detect patterns that summary statistics cannot?

  3. What is the difference between signal and noise?


Intermediate

  1. What does a moving average do to a time series?

  2. Why does smoothing help reveal underlying patterns?

  3. What is the trade-off between smoothing and responsiveness?


Challenge

  1. Suppose a time series appears smooth after applying a moving average.


Interpretation & Practice

  1. You observe a time series plot with a steady upward movement.

    • What feature does this suggest?

    • Why might this create problems for analysis later?


  1. A time series fluctuates randomly around a constant level.

    • What type of behavior does this suggest?

    • What might be a suitable model for this?


  1. A time series shows long periods of calm followed by sudden large movements.

    • What feature of financial data does this illustrate?

    • Why is this important?


  1. A smoothed series (moving average) lags behind the original data.

    • Why does this happen?

    • When might this be a problem?


Challenge

  1. Two analysts use different moving averages:

    • Analyst A: 5-day MA

    • Analyst B: 50-day MA

    • Which one reacts faster to new information?

    • Which one is smoother?

    • Which one would be better for short-term trading?


Numerical Practice

Visual Thinking

  1. Consider the following simulated time series:

Source
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(0)

t = np.arange(100)

trend = 0.1 * t
noise = np.random.normal(0, 1, 100)

series = trend + noise

plt.plot(series)
plt.title("Simulated Trend + Noise")

plt.savefig("figs/ch3/Q_trent.png", dpi=300, bbox_inches="tight")
plt.close()   # replace with plt.show()
Trend

Smoothing a Stationary Series

  1. Simulate a stationary AR(1) series:

Source
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(0)

T = 150
phi = 0.7

e = np.random.normal(0, 1, T)

series = np.zeros(T)

for t in range(1, T):
    series[t] = phi * series[t-1] + e[t]

plt.plot(series)

plt.title("Simulated Stationary AR(1) Series")

plt.savefig("figs/ch3/Q_ar1.png", dpi=300, bbox_inches="tight")
plt.close()   # replace with plt.show()
AR1
  1. Apply moving averages to the AR(1) series:

Source
ma_short = np.convolve(series, np.ones(5)/5, mode="valid")

ma_long = np.convolve(series, np.ones(20)/20, mode="valid")

plt.plot(series, alpha=0.3, label="Original AR(1)")

plt.plot(
    range(4, T),
    ma_short,
    label="5-period MA"
)

plt.plot(
    range(19, T),
    ma_long,
    label="20-period MA"
)

plt.legend()

plt.title("Smoothing a Stationary AR(1) Series")

plt.savefig("figs/ch3/Q_ar1_ma.png", dpi=300, bbox_inches="tight")
plt.close()   # replace with plt.show()
AR1