%% Clear
clear, close all, clc;

%% Globals

cr_vals = [2, 3, 4, 5, 7, 10, 15, 20, 25, 50, 60, 100];

nModels = 5;

names = ["Tailored", "DDBD-Dict", "DDBD-Wavelet", "Bernoulli-DCT", "Gaussian-DCT"];
markers = ["-pentagram", "-square", "-o", "-*", "-diamond"];
for i=1:nModels
    plt_info(i).name = names(i);
    plt_info(i).mkr = markers(i);
end

%% Load the trimmed data

for i=1:length(cr_vals)
    cr = cr_vals(i);
    path = strcat('results_trimmed\', num2str(cr), '.mat');
    results(i) = load(path);
end

for i=1:length(cr_vals)
    cr = cr_vals(i);
    path = strcat('results_trimmed\', num2str(cr), '_idx.mat');
    index_vals(i) = load(path);
end

for i=1:length(cr_vals)
    cr = cr_vals(i);
    path = strcat('results_trimmed\', num2str(cr), '_pwr.mat');
    pwr_dat(i) = load(path);
end

for i=1:length(cr_vals)
    cr = cr_vals(i);
    path = strcat('results_trimmed\', num2str(cr), '_time.mat');
    time_dat(i) = load(path);
end

meta = load("data\total_data\meta_data.mat");

%% Recovery Time Plot

bar_better = zeros(12, 5);

tay_time = zeros(12, 6);
tay_time(1,:) = [0.002706 0.000246 0.000260 0.000271 0.000727 0.000447];
tay_time(2,:) = [0.000228 0.000163 0.000174 0.000153 0.000318 0.000148];
tay_time(3,:) = [0.000151 0.000123 0.000239 0.000188 0.000278 0.000107];
tay_time(4,:) = [0.000228 0.000141 0.000095 0.000097 0.000248 0.000101];
tay_time(5,:) = [0.000145 0.000080 0.000075 0.000115 0.000247 0.000057];
tay_time(6,:) = [0.000094 0.000106 0.000064 0.000099 0.000367 0.000096];
tay_time(7,:) = [0.000128 0.000055 0.000092 0.000053 0.000436 0.000050];
tay_time(8,:) = [ 0.000082 0.000088 0.000046 0.000068 0.000197 0.000042];
tay_time(9,:) = [0.000182 0.000046 0.000058 0.000044 0.000184 0.000022];
tay_time(10,:) = [0.000056 0.000055 0.000046 0.000041 0.000164 0.000019];
tay_time(11,:) = [0.000063 0.000048 0.000034 0.000041 0.000168 0.000023];
tay_time(12,:) = [0.000072 0.000059 0.000048 0.000048 0.000184 0.000043];

bar_better(:, 1) = mean(tay_time, 2);

for i=1:length(time_dat)
    bar_better(i,2:5) = mean(time_dat(i).solve_time, 2);
end

bar(linspace(1,12,12), bar_better);
xticklabels(cr_vals);
legend(["Tailored" "DDBD-Dict" "DDBD-Wavelet" "Bern-Dct" "Gauss-Dct" ]);
xlabel("Compression Ratio");
ylabel("Time to Recover Signal (s)");

%% Load Data from Cell Mat

tmp = cell2mat(arrayfun(@(x) [x.tailored.prd], results, 'UniformOutput', false));
tailored_prd = reshape(tmp, 5000, 12);
tmp = cell2mat(arrayfun(@(x) [x.ddbd_dict.prd], results, 'UniformOutput', false));
ddbd_dict_prd = reshape(tmp, 10000, 12);
tmp = cell2mat(arrayfun(@(x) [x.ddbd_wave.prd], results, 'UniformOutput', false));
ddbd_wave_prd = reshape(tmp, 10000, 12);
tmp = cell2mat(arrayfun(@(x) [x.gauss_dct.prd], results, 'UniformOutput', false));
gauss_dct_prd = reshape(tmp, 10000, 12);
tmp = cell2mat(arrayfun(@(x) [x.bern_dct.prd], results, 'UniformOutput', false));
bern_dct_prd = reshape(tmp, 10000, 12);

tailored_prd(:,9) = [];
ddbd_dict_prd(:,9) = [];
ddbd_wave_prd(:,9) = [];
bern_dct_prd(:,9) = [];
gauss_dct_prd(:,9) = [];

all_prd = {tailored_prd, ddbd_dict_prd, ddbd_wave_prd, bern_dct_prd, gauss_dct_prd };

%% Plot the data from above

% NOTE that #9 was deemed not good
tmp = cr_vals;
tmp(9) = [];

figure;
hold on;
for i=1:length(all_prd)
    plot(tmp, mean(cell2mat(all_prd(i)), 1), plt_info(i).mkr, 'MarkerSize', 5, 'LineWidth', 2);
    % errorbar(tmp, mean(cell2mat(all_prd(i)), 1), std(cell2mat(all_prd(i)), 1), plt_info(i).mkr, 'MarkerSize', 3, 'LineWidth', 1);
end
hold off;

legend(plt_info(:).name, 'location', 'best');
xlabel("Compression Ratio");

xticks(tmp)
% ylabel("Mean Reconstructed SNR (dB)");
ylabel("Mean PRD");



% print('-dsvg', '-loose', 'images/final_images/results/mean_prd_prime.svg');

%% Box Plot Stuff 

% b = boxchart(tailored_prd);
% set(b, 'MarkerStyle', 'none');
% set(b, 'Notch', 'on');
% hold on;
% bb = boxchart(ddbd_dict_prd);
% set(bb, 'MarkerStyle', 'none');
% set(bb, 'Notch', 'on');

aboxplot({tailored_prd, ddbd_dict_prd}, 'labels', tmp);
legend(["Tailored", "DDBD-Dict"], 'location', 'best');
xlabel("Compression Ratio");
ylabel("Mean PRD");
colormap("turbo")

%% Scatter and Mean by patient [Not Tailored]

cr_to_check = 10;
test_indices = index_vals(cr_vals == cr_to_check).test_idx.subset;
patients = meta.beat_patient(test_indices);
unique_patients = unique(patients);

num_patients = length(test_indices);
num_unique = length(unique_patients);
cur_prd = ddbd_wave_prd(:,cr_vals == cr_to_check);

t = linspace(1, num_patients, num_patients);
% gscatter(t, cur_prd, patients);


for i=1:num_unique
    cur_pat = unique_patients(i);
    prd_per_pat = cur_prd(patients == cur_pat);
    mean_prd(i) = mean(prd_per_pat);
    fprintf("Patient [%d] --> Mean PRD [%f]\n", cur_pat, mean_prd(i));
    scatter(linspace(1, length(mean_prd(i)), length(mean_prd(i))));
    
end

mean_prd_ddbd_wave.prd = mean_prd;
mean_prd_ddbd_wave.pats = unique_patients;

scatter(linspace(1, num_unique, num_unique), mean_prd);
xticklabels(unique_patients);

%% Overlay

hold on;
scatter(linspace(1, num_unique, num_unique), abs(mean_prd_ddbd_wave.prd - mean(mean_prd_ddbd_wave.prd, 2)));
scatter(linspace(1, num_unique, num_unique), abs(mean_prd_ddbd_dict.prd - mean(mean_prd_ddbd_dict.prd, 2)));
hold off;
xticklabels(unique_patients');


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% Load Combined Results

for i=1:length(cr_vals)
    cr = cr_vals(i);
    path = strcat('data\results\', num2str(cr), '.mat');
    tmp = load(path);
    results(i) = tmp.results;
    clear tmp;
end


%% Box Plot Logic

% idx = isoutlier(outages.Customers,'quartiles');
% outliers = outages(idx,:);
% size(outliers,1)

% bplot.dat = [ddbd_dict_prd1'; tailored_prd1'];
% bplot.cr = cr_vals;
% bplot.label = [repmat("DDBD Dict", 1, size(ddbd_dict_prd1,2)) repmat("tailored", 1, size(tailored_prd1,2))];
% boxchart(bplot.cr, bplot.dat, 'GroupByColor', bplot.label');

test = [tailored_prd'; ddbd_dict_prd(1:5000, :)'];
crs =  repmat(tmp, size(test,2), 1)';
cat = [repmat("DDBD Dict", 11, size(tailored_prd,2)) repmat("tailored", 11, size(ddbd_dict_prd(1:5000, :),2))];

new_test = test(:);
new_crs = crs(:);
new_cat = cat(:);

figure;
b = boxchart(new_crs, new_test, 'GroupByColor', new_cat);

set(b, 'MarkerStyle', 'none');
set(b, 'Notch', 'on');
title('PRD1 vs. Compression Ratio');
xlabel('Compression Ratio');
ylabel('PRD1');
legend;
ylim([0 6]);

%% 

load patients
boxchart(double(Age<30), Systolic, 'GroupByColor', Smoker)
colororder([1 1 0; 0 1 1]); 

%% Power Plots


tay_pwr = [pwr_dat.tailored];
ddbd_dict_pwr = [pwr_dat.ddbd_dict];
ddbd_wave_pwr = [pwr_dat.ddbd_wave];
gauss_dct_pwr = [pwr_dat.gauss_dct];
bern_dct_pwr = [pwr_dat.bern_dct];


% for i=1:length(tay_pwr)
%     tay_pwr(i).smp_pwr = 10e-20;
% end


pwr_total = {tay_pwr; ddbd_dict_pwr; ddbd_wave_pwr; gauss_dct_pwr; bern_dct_pwr};
% pwr_total = {tay_pwr; ddbd_dict_pwr; ddbd_wave_pwr};

hold on;
for i=1:length(pwr_total)
    plot(cr_vals, [pwr_total{i}.smp_pwr],  plt_info(i).mkr);
%     plot([pwr_total{i}.smp_pwr],  plt_info(i).mkr);
    % plot([pwr_total{i}.smp_pwr] + [pwr_total{i}.tx_pwr], plt_info(i).mkr);
end
set(gca, 'YScale', 'log')

hold off;
legend(plt_info(:).name, 'location', 'northeast');
xlabel("Compression Ratio");
ylabel("Power Drain (J)");
xticks(cr_vals)

%% Recover Time Plots



%% C-Psi Plots

N = 300;
M = 60;
CR = 5;

% CR of 5 (index 4)
load_beats = false;
if load_beats
    beats_tested = index_vals(4).test_idx.subset;
    load("data\total_data\conditioned.mat");
    beats_dict = beats(beats_tested, :);
    clear beats;
end

load_tay = false;
if load_tay
    new_res = load("data\results\5.mat");
    tailored_c = new_res.results.tailored.C;
    tailored_Psi = new_res.results.tailored.Psi;
    clear new_res;
end

% TAILORED 
mc_tailored = mutual_coherence(tailored_c, tailored_Psi);
% plot_mc(tailored_c, tailored_Psi, mc_tailored);

%DDBD DICT
ddbd_dict_c = ddbd_c(N, M, CR);
[ddbd_dict_psi,S,V] = svd(beats_dict','econ');
ddbd_dict_psi = ddbd_dict_psi';
ddbd_dict_mc = mutual_coherence(ddbd_dict_c, ddbd_dict_psi);
% plot_mc(ddbd_dict_c, ddbd_dict_psi, ddbd_dict_mc');

% names = ["Tailored", "DDBD-Dict", "DDBD-Wavelet", "Bernoulli-DCT", "Gaussian-DCT"];

% DDBD-Wavelet
ddbd_wavlet_c = ddbd_dict_c;
ddbd_wavlet_psi = wavlet_transform_mtx(N, 'rbio5.5', 5);
ddbd_wavlet_mc = mutual_coherence(ddbd_wavlet_c, ddbd_wavlet_psi);
plot_mc(ddbd_wavlet_c, ddbd_wavlet_psi, ddbd_wavlet_mc);

load('C:\Users\mitch\OneDrive\Documents\Masters\masters_thesis\project\compressed_sensing\utils\sensing_functions\BernoulliSample.mat');
bern_dct_c = BernoulliSample(1:M, 1:N);
bern_dct_c(bern_dct_c == -1) = 0;
bern_dct_psi = dctmtx(N);
bern_dct_mc = mutual_coherence(bern_dct_c, bern_dct_psi);
% plot_mc(bern_dct_c, bern_dct_psi, bern_dct_mc);

gauss_c = random('normal', 0, 1, [M N]);

%% Just Plotting C

figure;
pcolor(gauss_c), colormap("turbo"),axis  equal, axis off;
print('-dsvg', '-loose', 'images/final_images/gauss_c_final.svg');

%% Plotting Just Psi
figure;
h = pcolor(bern_dct_psi);
colormap("turbo"),axis  equal, axis off;
set(h, 'EdgeColor', 'none');
print('-dsvg', '-loose', 'images/final_images/dct_psi_final.svg');

%% Plotting Beat Reconstruction

% CR of 60 (cr_vals index of 11)
cr = 60;
cr_ind = find(cr_vals == cr);

% Get beat indexes
subset_beats = index_vals(cr_ind).test_idx.subset;
tay_test_beat_idx = index_vals(cr_ind).test_idx.tailored.test;      % Test Indexes of Subset
tay_test_beats = subset_beats(tay_test_beat_idx);                   % Translate Test Indexes of Subset into actual beat numbers

% Extract Tay PRD
tmp = results(cr_ind).tailored;
tay_prd = [tmp(:).prd];                                             % Extract vector of Tailor PRD values

% Extract DDBD DICT PRD
tmp = results(cr_ind).ddbd_dict;
ddbd_dict_prd_full = [tmp(:).prd];
ddbd_dict_prd = ddbd_dict_prd_full(tay_test_beat_idx);                   % Only take the subset PRD values that were in the tailored PRD

prd_diff = ddbd_dict_prd - tay_prd;
ind_of_max = find(prd_diff == max(prd_diff));
beat_of_max = tay_test_beats(ind_of_max);

ind_of_min = find(tay_prd == min(tay_prd));
beat_of_min = tay_test_beats(ind_of_min);

%% Plot the beats

original = og_beats(beat_of_min, :);
tay_recon = recon_beats.tailored((tay_test_beats == beat_of_min), :);
ddbd_recon = recon_beats.ddbd_dict((subset_beats == beat_of_min), :);

plot(original);
hold on;
plot(tay_recon);
plot(ddbd_recon);
legend(["original" "Tailored", "DDBD-Dict"])

found_tay_prd = tay_prd(tay_test_beats == beat_of_min);
found_ddbd_prd = ddbd_dict_prd_full(subset_beats == beat_of_min);
actual_tay_prd = (norm(tay_recon - original) / norm(original)) * 100;
actual_ddbd_prd = (norm(ddbd_recon - original) / norm(original)) * 100;

fprintf("Tay  PRD Found/Actual [%f] / [%f]\n", found_tay_prd, actual_tay_prd);
fprintf("DDBD PRD Found/Actual [%f] / [%f]\n", found_ddbd_prd, actual_ddbd_prd);


% 
% subset_beats = sort(unsorted_subset_beats);
% 
% unsorted_tailored_beats = unsorted_subset_beats(index_vals(cr_ind).test_idx.tailored.test);     % Remember that test indexes subset indexes total
% tailored_beats = sort(unsorted_tailored_beats);
% 
% bIndices = subset_beats(ismember(subset_beats, tailored_beats));        % Vector of beat indexes that are in tailored test and subset
% bIndices = sort(bIndices);
% 
% % Extract Tailored PRD 
% tmp = results(cr_ind).tailored;
% tay_prd = [tmp(:).prd];
% tay_prd = tay_prd(ismember(tailored_beats, bIndices));
% 
% % Extract DDBD DICT PRD
% tmp = results(cr_ind).ddbd_dict;
% ddbd_dict_prd = [tmp(:).prd];
% ddbd_dict_prd = ddbd_dict_prd(ismember(subset_beats, tailored_beats));
% 
% % Track the PRD Difference
% prd_diff = ddbd_dict_prd - tay_prd;
% % scatter(linspace(1,555,555), prd_diff);
% ind_of_max = find(prd_diff == max(prd_diff));
% 
% beat_of_max = bIndices(ind_of_max);
% 
% %% 
% 
% % Extract the beat data
% getBeats = true;
% if getBeats
%    og_load = load("data\total_data\conditioned.mat");
%    og_beats = og_load.beats;
%    clear og_load;
% 
%    recon_load = load("data\results\60.mat");
%    recon_beats.tailored = recon_load.results.tailored.recon_beats;
%    recon_beats.ddbd_dict = recon_load.results.ddbd_dict.recon_beats;
%    clear recon_load;
% end
% 
% % Note og_beats will be indexed based on bIndices while recon_beats will be based on their original beat index
% 
% original = og_beats((bIndices == beat_of_max), :);
% tay_recon = recon_beats.tailored(471, :);
% ddbd_recon = recon_beats.ddbd_dict(9727, :);

%% Now Plot!



fprintf("Tay PRD [%f]\n", tay_prd(bIndices == beat_of_max));
fprintf("Actual Tay PRD [%f]\n", ((norm(tay_recon - original) / norm(original)) * 100));
fprintf("DDBD PRD [%f]\n", ddbd_dict_prd(bIndices == beat_of_max));


%%
ind_to_find = prd_diff == max(prd_diff);
beat_to_find = bIndices(ind_to_find);

ogInd = bIndices == bIndices(ind_to_find);
tInd = tailored_beats == beat_to_find;
dInd = subset_beats == beat_to_find;


plot(og_beats(ogInd, :));
hold on;
plot(recon_beats.tailored(ogInd, :));
plot(recon_beats.ddbd_dict(ogInd, :));
legend(["original" "Tailored", "DDBD-Dict"])

original = og_beats(ind_to_find, :);
reconstructed = recon_beats.tailored(ind_to_find, :);

(norm(reconstructed - original) / norm(original)) * 100





%%Functions

function c = ddbd_c(N, M, CR)
    c = zeros(M,N);
    for i = 1:M
        offset = (i-1)*CR + 1;
        off_end = min(offset+CR-1, N);
        c(i, offset:off_end) = ones(1,(off_end-offset)+1);
    end
end

function mc = mutual_coherence(phi, psi)

    for f=1:size(phi,1)
        for g=1:size(psi, 1)
            mc(f,g) = abs( phi(f,:) * psi(:,g)) / (norm(phi(f,:)) * norm(psi(:,g)));
        end
    end
%     figure;
%     m = surf(mc);
%     set(m, 'LineStyle', 'none');
%     xlabel('N');
%     ylabel('M');
%     title('Mutual Coherence');
%     zlabel('MC');
end

function plot_mc(C, Psi, MC)
    
    figure;
    ax1 = subplot(3,1,1);
    pcolor(~C), axis equal, axis off;
    colormap(ax1, "gray");
    
    ax2 = subplot(3,1,2);
    pcolor(Psi), axis equal, axis off;
    colormap(ax2, "turbo");
    
    ax3 = subplot(3,1,3);
    m = mesh(MC);
    % set(m, 'LineStyle', 'none');
    colormap(ax3, "turbo");

end

function aboxplot(X,varargin)

% Parameters
widthl = 0.7;
widths = 0.8;
widthe = 0.4;
outMarker = '.';
outMarkerSize = 3;
outMarkerEdgeColor = [0.6 0.6 0.6];
outMarkerFaceColor = [0.6 0.6 0.6];
alpha = 0.05;
cmap = [];
colorrev = 0;
colorgrd = 'green_down';

% Get the number or data matrices
if iscell(X)
    d = length(X);
else
    % If data is a matrix extend to a 3D array
    if 2 == ndims(X)
        X = reshape(X, [1,size(X)]);
    end
    d = size(X,1);
end;

% Get the data size
if iscell(X)
    n = size(X{1},2);
else
    n = size(X,3);
end

% Set the labels
labels = cell(n,1);
for i=1:n
    labels{i} = num2str(i);
end

% Optional arguments
optargin = size(varargin,2);

i = 1;
while i <= optargin
    switch lower(varargin{i})
        case 'labels'
            labels = varargin{i+1};
        case 'colormap'
            cmap = varargin{i+1};
        case 'colorgrad'
            colorgrd = varargin{i+1};
        case 'colorrev'
            colorrev = varargin{i+1};
        case 'outliermarker'
            outMarker = varargin{i+1};
        case 'outliermarkersize'
            outMarkerSize = varargin{i+1};
        case 'outliermarkeredgecolor'
            outMarkerEdgeColor = varargin{i+1};
        case 'outliermarkerfacecolor'
            outMarkerFaceColor = varargin{i+1};
        case 'widthl'
            widthl = varargin{i+1};
        case 'widths'
            widths = varargin{i+1};
        case 'widthe'
            widthe = varargin{i+1};
    end
    i = i + 2;
end

% Colors
colors = cell(d,n);
if colorrev
    %  Set colormap
    if isempty(cmap)
        cmap = colorgrad(n,colorgrd);
    end
    if size(cmap,1) ~= n
        error('The number of colors in the colormap must equal n.');
    end
    for j=1:d
        for i=1:n
            colors{j,i} = cmap(i,:);
        end
    end
else
    %  Set colormap
    if isempty(cmap)
        cmap = colorgrad(d,colorgrd);
    end
    if size(cmap,1) ~= d
        error('The number of colors in the colormap must equal n.');
    end
    for j=1:d
        for i=1:n
            colors{j,i} = cmap(j,:);
        end
    end
end

xlim([0.5 n+0.5]);

hgg = zeros(d,1);

for j=1:d
    % Get the j matrix
    if iscell(X)
        Y = X{j};
    else
        Y = squeeze(X(j,:,:));
    end
    
    % Create a hggroup for each data set
    hgg(j) = hggroup();
    set(get(get(hgg(j),'Annotation'),'LegendInformation'),'IconDisplayStyle','on');
    legendinfo(hgg(j),'patch',...
        'LineWidth',0.5,...
        'EdgeColor','k',...
        'FaceColor',colors{j,1},...
        'LineStyle','-',...
        'XData',[0 0 1 1 0],...
        'YData',[0 1 1 0 0]);
    
    for i=1:n
    
        % Calculate the mean and confidence intervals
        [q1 q2 q3 fu fl ou ol] = quartile(Y(:,i));
        u = nanmean(Y(:,i));

        % large interval  [i - widthl/2 i + widthl/2] delta = widthl
        % medium interval start: i - widthl/2 + (j-1) * widthl / d
        % medium interval end: i - widthl/2 + j * widthl / d
        % medium interval width: widthl / d
        % medium interval middle: i-widthl/2+(2*j-1)*widthl/(2*d)
        % small interval width: widths*widthl/d
        % small interval start: i-widthl/2+(2*j-1-widths)*widthl/(2*d)
  
        % Plot outliers
%         hold on;
%         plot((i-widthl/2+(2*j-1)*widthl/(2*d)).*ones(size(ou)),ou,...
%             'LineStyle','none',...
%             'Marker',outMarker,...
%             'MarkerSize',outMarkerSize,...
%             'MarkerEdgeColor',outMarkerEdgeColor,...
%             'MarkerFaceColor',outMarkerFaceColor,...
%             'HitTest','off',...
%             'Parent',hgg(j));
%         plot((i-widthl/2+(2*j-1)*widthl/(2*d)).*ones(size(ol)),ol,...
%             'LineStyle','none',...
%             'Marker',outMarker,...
%             'MarkerSize',outMarkerSize,...
%             'MarkerEdgeColor',outMarkerEdgeColor,...
%             'MarkerFaceColor',outMarkerFaceColor,...
%             'HitTest','off',...
%             'Parent',hgg(j));
%         hold off;
        
        % Plot fence
        line([i-widthl/2+(2*j-1)*widthl/(2*d) i-widthl/2+(2*j-1)*widthl/(2*d)],[fu fl],...
            'Color','k','LineStyle',':','HitTest','off','Parent',hgg(j));
        line([i-widthl/2+(2*j-1-widthe)*widthl/(2*d) i-widthl/2+(2*j-1+widthe)*widthl/(2*d)],[fu fu],...
            'Color','k','HitTest','off','Parent',hgg(j));
        line([i-widthl/2+(2*j-1-widthe)*widthl/(2*d) i-widthl/2+(2*j-1+widthe)*widthl/(2*d)],[fl fl],...
            'Color','k','HitTest','off','Parent',hgg(j));
        
        % Plot quantile
        if q3 > q1
            rectangle('Position',[i-widthl/2+(2*j-1-widths)*widthl/(2*d) q1 widths*widthl/d q3-q1],...
                'EdgeColor','k','FaceColor',colors{j,i},'HitTest','off','Parent',hgg(j));
        end
        
        % Plot median
        line([i-widthl/2+(2*j-1-widths)*widthl/(2*d) i-widthl/2+(2*j-1+widths)*widthl/(2*d)],[q2 q2],...
            'Color','k','LineWidth',1,'HitTest','off','Parent',hgg(j));
        
        % Plot mean
        hold on;
        plot(i-widthl/2+(2*j-1)*widthl/(2*d), u,...
            'LineStyle','none',...
            'Marker','o',...
            'MarkerEdgeColor','k',...
            'MarkerFaceColor',colors{j,i},...
            'HitTest','off','Parent',hgg(j));
        hold off;
    end
end

box on;

set(gca,'XTick',1:n);
set(gca,'XTickLabel',labels);

end
























