Visualise principal component analysis with Matplotlib

logo of a chart:Correlogram

This post describes how to create charts related to Principal Component Analysis (PCA). PCA is a famous tool and has lots of application in the field of data visualization. The charts will be create with matplotlib.
We will go over the scree plot (explained variance plot), the correlation circle plot and the visualization of the observations on the new principal components. These charts are the most basics when working with PCA but are an important start.

About Principal Component Analysis

The principal component analysis (PCA) is a widely used dimensionality reduction and data analysis technique in the field of statistics and machine learning. It is used to transform high-dimensional data into a lower-dimensional representation while retaining as much of the original variability as possible. PCA achieves this by identifying the directions (principal components) in the data along which there is the most variation.

Representing data in smaller spaces is a technique used for important visualization and statistical analysis tasks:

  • clustering (finding groups of similar observations)
  • feature significance (which variables are most important in terms of variability?)
  • outlier detection (find observations that stand out from the rest)
  • exploratory analysis (simply to better understand the dataset)

Libraries

In order to apply PCA to our data, we need to use a library that supports it: in our case, this will be scikit-learn.

  • matplotlib is used for creating the chart
  • scikit-learn is used for applying the PCA to our dataset
  • numpy is used to generate some data
  • pandas is used to put the data into a dataframe

Don't forget to install scikit-learn with the pip install -U scikit-learn command.

# Libraries
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler

Dataset

We're going to create a data set consisting of 4 variables, more or less correlated. We want them to be correlated, because that's what makes a PCA relevant in an analysis.

The data are generated using numpy random function np.random.normal() and np.random.uniform(). Then, we store these variables to a pandas dataframe.

One important part of PCA is to normalize the data. In practice, it just means applying a z-score transformation and it is really easy.

# Create our variables
sample_size = 100
random1 = np.random.uniform(30, 20, sample_size)
random2 = random1*3 + np.random.normal(10, 30, sample_size)
random3 = random2*-3 + np.random.normal(10, 100, sample_size)
random4 = random3*2 + np.random.normal(10, 500, sample_size)

df = pd.DataFrame({'variable1': random1,
                   'variable2': random2,
                   'variable3': random3,
                   'variable4': random4,})

# Scale our data using z-score normalization
scaler = StandardScaler()
data_scaled = scaler.fit_transform(df)
df = pd.DataFrame(data_scaled, columns=df.columns)

Create the PCA object

With scikit-learn, it's easy to make a PCA. Simply initialize a PCA object (and optionnaly specify the number of components you want to keep). As it's difficult to create a visualization on more than 2 axes (3 is possible but more complex), we'll keep only the first 2 dimensions (see graph section below).

# Init a PCA object where we will only keep the 2 first principal components
pca = PCA()

# Use the `fit_transform` method from this object to our dataframe
pca_results = pca.fit_transform(df)

Scree plot

A scree plot is actually just a barplot, but usually create for factorial analysis like PCA. In this context, it gives us the information of 'how much inertia each component has?'.

# Get the explained variance ratio for each principal component
explained_variance = pca.explained_variance_ratio_

# Set figsize
plt.figure(figsize=(10, 6))

# Create a scree plot to visualize the explained variance
plt.plot(range(1, len(explained_variance) + 1), # x-axis
         explained_variance*100, # convert explained variance in percentage
         marker='o', # add a marker at each value
        )

# Add title and axis label
plt.title('Scree Plot of Explained Variance for Principal Components')
plt.xlabel('Principal Component')
plt.ylabel('Explained Variance (in %)')

# Add label to x-axis
plt.xticks(range(1, len(explained_variance) + 1))

# Add grid in the background
plt.grid(True)

# Display the chart
plt.show()