Creating Variable Factor Map (PCA) Plot with Python | by Huy Bui | Towards Data Science

One of the most joyful activities in analytics is working with beautiful visualization. With the Variable Factor Map, you can explain Principal Component Analysis with ease. A picture worth a thousand words
Principle Component Analysis (PCA), is a dimensionality-reduction method that is used to reduce the dimensionality of large data sets. It transforms multiple features into a much less number of new features while maintaining most of the information and variability of the original data.
If the number of features is 2, we can put them in a 2D plot and visualize how different features factor in each new component. In the picture above, four features (sepal width, sepal length, petal width, petal length) from the iris data set are compressed into two. They are component 1 (y-axis) and component 2 (x-axis), which maintain 97.77% of the information of the original dataset. The four vectors represent how these 2 components explain the four original features.
The code is created using minimal knowledge of Python and matplotlib. I believe simplicity is the keynote of all true elegance. There are three important steps to create this plot
Data preparation
PCA Decomposition
Plot
We first import the iris data set from sklearn
from sklearn import datasetsimport pandas as pdiris = datasets.load_iris()X=pd.DataFrame(data=iris.data,columns=iris.feature_names)X
There are 4 features for the iris data set, and we want to transform these 4 to 2 components as discussed before.
The scikit-learn package makes PCA method becomes very convenient, all we need to do is import PCA from sklearn decomposition library.
from sklearn.decomposition import PCAcolumns=X.columns.values #Store the name of the columns for labelingpca=PCA(n_components=2)pca.fit(X)pca_values=pca.components_pca.components_
We define n_component=2 , train the model by fit method, and stored PCA components_. Thesecomponents_ represent the principal axes in feature space. Two arrays here indicate the (x,y)-coordinates of the 4 features. Later we will plot these points by 4 vectors on the unit circle, this is where the fun begins.
Let’s first adjust the font and the size of the plot
import matplotlib.pyplot as plt plt.figure(figsize=(10,10))plt.rcParams.update({'font.size': 14})
The next step is plotting a circle. We will use the circle function
#Plot circle#Create a list of 500 points with equal spacing between -1 and 1import numpy as npx=np.linspace(start=-1,stop=1,num=500)#Find y1 and y2 for these pointsy_positive=lambda x: np.sqrt(1-x**2) y_negative=lambda x: -np.sqrt(1-x**2)plt.plot(x,list(map(y_positive, x)), color='maroon')plt.plot(x,list(map(y_negative, x)),color='maroon')
If you do not know about lambda or map function, you should put these useful methods to your toolbox
We will draw a smaller circle with the same logic just for a more aesthetic view
#Plot smaller circlex=np.linspace(start=-0.5,stop=0.5,num=500)y_positive=lambda x: np.sqrt(0.5**2-x**2) y_negative=lambda x: -np.sqrt(0.5**2-x**2)plt.plot(x,list(map(y_positive, x)), color='maroon')plt.plot(x,list(map(y_negative, x)),color='maroon')
Let’s also add the x-axis and y-axis, this is also totally optional!
#Create broken linesx=np.linspace(start=-1,stop=1,num=30)plt.scatter(x,[0]*len(x), marker='_',color='maroon')plt.scatter([0]*len(x), x, marker='|',color='maroon')
If you reach this step, you are half-way done. Give yourself a pat on the back!
Before plotting the vectors, let’s define the colors that we will use. The following code defines 6 different colors for corresponding features, if the features are more than 6, the color list will repeat its cycle.
#Define color listcolors = ['blue', 'red', 'green', 'black', 'purple', 'brown']if len(pca_values[0]) > 6:    colors=colors*(int(len(pca_values[0])/6)+1)
Now let’s plot the vectors and label them
add_string=""for i in range(len(pca_values[0])):    xi=pca_values[0][i]    yi=pca_values[1][i]    plt.arrow(0,0,               dx=xi, dy=yi,               head_width=0.03, head_length=0.03,               color=colors[i], length_includes_head=True)    add_string=f" ({round(xi,2)} {round(yi,2)})"    plt.text(pca_values[0, i],              pca_values[1, i] ,              s=columns[i] + add_string )
The functionplt.arrow takes the initial point and the endpoint of the vector. Here, the initial point is the origin (0,0), and the endpoints were obtained from the PCA component method previously.
Finally, we add some other cosmetics for the plot.
plt.xlabel(f"Component 1 ({round(pca.explained_variance_ratio_[0]*100,2)}%)")plt.ylabel(f"Component 2 ({round(pca.explained_variance_ratio_[1]*100,2)}%)")plt.title('Variable factor map (PCA)')plt.show()
You can also import the above code by doing the following
pip install -i https://test.pypi.org/simple/ variable-factor-map-Huy-Bui==0.0.3from variable_factor_map import pca_map from sklearn import datasetsimport pandas as pdiris = datasets.load_iris()X=pd.DataFrame(data=iris.data,columns=iris.feature_names)pca_map(X, figsize=(10,10), sup="Iris", print_values= False)
The pca_map function takes 4 inputs:
X: pandas Data Frame
figsize (float, float): the width and height of the output. Default is (10,10)
sup (string): The title of the plot. Default is an empty string
print_values (boolean): Display the vector values. Default is False
You can also visit my GitHub to see the source code. Have fun playing with Python!