import matplotlib.pyplot as plt
import numpy as np
from io import StringIO
from sklearn.datasets import load_wine
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler

plt.rcParams.update({'text.color': 'gray', 'axes.labelcolor': 'gray', 'axes.edgecolor': 'gray',
                     'xtick.color': 'gray', 'ytick.color': 'gray'})

X, y = load_wine(return_X_y=True, as_frame=True)
colors = np.array(['#58a6ff', '#f0883e', '#3fb950'])

fig, axes = plt.subplots(1, 2, figsize=(9.5, 4.0))
for ax, (title, data) in zip(axes, [('raw columns', X.to_numpy()),
                                    ('standardized columns', StandardScaler().fit_transform(X))]):
    pca = PCA(n_components=2).fit(data)
    Z = pca.transform(data)
    for k in range(3):
        ax.scatter(Z[y == k, 0], Z[y == k, 1], s=14, color=colors[k], alpha=0.85, label=f'cultivar {k}')
    top = X.columns[np.argmax(np.abs(pca.components_[0]))]
    evr = pca.explained_variance_ratio_ * 100
    ax.set_xlabel(f'PC1 ({evr[0]:.1f}% of the variance; largest weight: {top})', fontsize=8.5)
    ax.set_ylabel(f'PC2 ({evr[1]:.1f}%)', fontsize=8.5)
    ax.set_title(f'PCA on the {title}', fontsize=10, loc='left')
    ax.tick_params(labelsize=8)
axes[1].legend(fontsize=8, framealpha=0, loc='lower left')
fig.suptitle('Wine, 13 chemical measurements: proline is measured in the hundreds, hue around 1',
             fontsize=9.5, color='gray')
plt.tight_layout()

buffer = StringIO()
plt.savefig(buffer, format="svg", transparent=True)
print(buffer.getvalue())

plt.close()
