import matplotlib.pyplot as plt import numpy as np def plot_scree(eigenvals, total_var, ncomp=None, x_label='factor'): """ Plot of the ordered eigenvalues and variance explained for the loadings Parameters ---------- eigenvals : array_like The eigenvalues total_var : float the total variance (for plotting percent variance explained) ncomp : int, optional Number of factors to include in the plot. If None, will included the same as the number of maximum possible loadings x_label : str label of x-axis Returns ------- Figure Handle to the figure. """ fig = plt.figure() ncomp = len(eigenvals) if ncomp is None else ncomp vals = eigenvals vals = vals[:ncomp] # vals = np.cumsum(vals) ax = fig.add_subplot(121) ax.plot(np.arange(ncomp), vals[: ncomp], 'b-o') ax.autoscale(tight=True) xlim = np.array(ax.get_xlim()) sp = xlim[1] - xlim[0] xlim += 0.02 * np.array([-sp, sp]) ax.set_xticks(np.arange(ncomp)) ax.set_xlim(xlim) ylim = np.array(ax.get_ylim()) scale = 0.02 sp = ylim[1] - ylim[0] ylim += scale * np.array([-sp, sp]) ax.set_ylim(ylim) ax.set_title('Scree Plot') ax.set_ylabel('Eigenvalue') ax.set_xlabel(x_label) per_variance = vals / total_var cumper_variance = np.cumsum(per_variance) ax = fig.add_subplot(122) ax.plot(np.arange(ncomp), per_variance[: ncomp], 'b-o') ax.plot(np.arange(ncomp), cumper_variance[: ncomp], 'g--o') ax.autoscale(tight=True) xlim = np.array(ax.get_xlim()) sp = xlim[1] - xlim[0] xlim += 0.02 * np.array([-sp, sp]) ax.set_xticks(np.arange(ncomp)) ax.set_xlim(xlim) ylim = np.array(ax.get_ylim()) scale = 0.02 sp = ylim[1] - ylim[0] ylim += scale * np.array([-sp, sp]) ax.set_ylim(ylim) ax.set_title('Variance Explained') ax.set_ylabel('Proportion') ax.set_xlabel(x_label) ax.legend(['Proportion', 'Cumulative'], loc=5) fig.tight_layout() return fig def plot_loadings(loadings, col_names=None, row_names=None, loading_pairs=None, percent_variance=None, title='Factor patterns'): """ Plot factor loadings in 2-d plots Parameters ---------- loadings : array like Each column is a component (or factor) col_names : a list of strings column names of `loadings` row_names : a list of strings row names of `loadings` loading_pairs : None or a list of tuples Specify plots. Each tuple (i, j) represent one figure, i and j is the loading number for x-axis and y-axis, respectively. If `None`, all combinations of the loadings will be plotted. percent_variance : array_like The percent variance explained by each factor. Returns ------- figs : a list of figure handles """ k_var, n_factor = loadings.shape if loading_pairs is None: loading_pairs = [] for i in range(n_factor): for j in range(i + 1,n_factor): loading_pairs.append([i, j]) if col_names is None: col_names = ["factor %d" % i for i in range(n_factor)] if row_names is None: row_names = ["var %d" % i for i in range(k_var)] figs = [] for item in loading_pairs: i = item[0] j = item[1] fig = plt.figure(figsize=(7, 7)) figs.append(fig) ax = fig.add_subplot(111) for k in range(loadings.shape[0]): plt.text(loadings[k, i], loadings[k, j], row_names[k], fontsize=12) ax.plot(loadings[:, i], loadings[:, j], 'bo') ax.set_title(title) if percent_variance is not None: x_str = f'{col_names[i]} ({percent_variance[i]:.1f}%)' y_str = f'{col_names[j]} ({percent_variance[j]:.1f}%)' ax.set_xlabel(x_str) ax.set_ylabel(y_str) else: ax.set_xlabel(col_names[i]) ax.set_ylabel(col_names[j]) v = 1.05 xlim = np.array([-v, v]) ylim = np.array([-v, v]) ax.plot(xlim, [0, 0], 'k--') ax.plot([0, 0], ylim, 'k--') ax.set_aspect('equal', 'datalim') ax.set_xlim(xlim) ax.set_ylim(ylim) fig.tight_layout() return figs