clc
clear all
close all
%% 生成数据点
% rng('default');
n = 300;
data = [randn(n, 2)*0.85+ones(n, 2); randn(n, 2)*0.85-ones(n, 2)];
center = mean(data);
%% PCA
[coeff, ~, latent, ~, ~] = pca(data);
% r1 r2 为自定义的向量大小参数(模)
r1 = 6;
r2 = 3;
% p1 p2 为第一主轴和第二主轴上的点
p1 = r1*coeff(:, 1)'+center;
p2 = r2*coeff(:, 2)'+center;
% 主轴方向与X轴之间的夹角
angle = cart2pol(coeff(1, :), coeff(2, :))*180/pi;
beta = angle(1, 1);
% 置信椭圆坐标(以 95% 为例)
semimajor = sqrt(latent(1, 1)); % 长轴长度(一半)
semiminor = sqrt(latent(2, 1)); % 短轴长度(一半)
alpha = linspace(0, 360, 2000)';
% 卡方分布表
% level = 4.605; % 90%
level = 5.991; % 95%
% level = 9.210; % 99%
% 椭圆坐标点
ellipse_X = center(1, 1)+sqrt(level)*(semimajor*cosd(alpha)*cosd(beta)-...
semiminor*sind(alpha)*sind(beta));
ellipse_Y = center(1, 2)+sqrt(level)*(semimajor*cosd(alpha)*sind(beta)+...
semiminor*sind(alpha)*cosd(beta));
%% 可视化
figure
hold on
box on
grid on
% 原始数据
scatter(data(:, 1), data(:, 2), 15, 'LineWidth', 1.2,...
'MarkerEdgeColor', [151, 138, 189]/255,...
'MarkerFaceColor', [151, 138, 189]/255);
xlim([-5, 5]);
ylim([-5, 5]);
set(gca, 'linewidth', 1.5)
% 置信椭圆
plot(ellipse_X, ellipse_Y, 'Color', [0, 102, 255]/255,...
'LineStyle', '-', 'LineWidth', 3),
% 第一主轴方向
arrow_1 = annotation('arrow', 'Color', [162, 20, 47]/255,...
'HeadStyle', 'cback2', 'LineWidth', 3, 'HeadWidth', 20, 'HeadLength', 20);
arrow_1.Parent = gca;
arrow_1.X = [center(1, 1), p1(1, 1)];
arrow_1.Y = [center(1, 2), p1(1, 2)];
% 第二主轴方向
arrow_2 = annotation('arrow', 'Color', [0, 114, 189]/255,...
'HeadStyle', 'cback2', 'LineWidth', 3, 'HeadWidth', 20, 'HeadLength', 20);
arrow_2.Parent = gca;
arrow_2.X = [center(1, 1), p2(1, 1)];
arrow_2.Y = [center(1, 2), p2(1, 2)];
% 中心点
plot(center(1, 1), center(1, 2),...
'Marker', 'o',...
'MarkerSize', 8,...
'MarkerEdgeColor', [162, 20, 47]/255,...
'MarkerFaceColor', [162, 20, 47]/255);
% title('主轴方向和置信椭圆', 'FontSize', 16, 'FontWeight', 'bold')
% text(2, -3, '99% 置信椭圆', 'FontSize', 16, 'FontWeight', 'bold')
axis equal